赞
踩
第一次写博客,记录下STM32学习过程中的踩坑经历。在很多时候自认为的坑、自认为的程序Bug都是由于我自身的粗心大意导致或者对于移植的程序理解不够深刻导致的,然后自己找了半天,进行各种尝试,最后发现是这样那样的低级错误。现在记录下防止以后再踩坑。
在移植dht11温湿度传感器文件和OLED文件时出现问题。单独的温湿度传感器实验文件采用串口打印数据,想着采用OLED来显示数据,因此将OLED相关的C文件和头文件移植到,温湿度传感器实验程序中并进行修改。然后就发现OLED 屏幕一点反应也没有,一片黑。以下只展示主函数的代码。
修改前代码:
int main(void) { DHT11_Data_TypeDef DHT11_Data; /* 配置SysTick 为1us中断一次 */ SysTick_Init(); USART_Config();//初始化串口1 printf("\r\n***温湿度传感器实验***\r\n"); /*初始化DTT11的引脚*/ DHT11_Init (); while(1) { /*调用DHT11_Read_TempAndHumidity读取温湿度,若成功则输出该信息*/ if( DHT11_Read_TempAndHumidity ( & DHT11_Data ) == SUCCESS) { printf("\r\n读取DHT11成功!\r\n\r\n湿度为%d.%d %RH ,温度为 %d.%d℃ \r\n",\ DHT11_Data.humi_int,DHT11_Data.humi_deci,DHT11_Data.temp_int,DHT11_Data.temp_deci); } else { printf("Read DHT11 ERROR!\r\n"); } Delay_ms(1000); } }
修改后的代码:
int main(void) { DHT11_Data_TypeDef DHT11_Data; /* 配置SysTick 为1us中断一次 */ SysTick_Init(); delay_init(); USART_Config();//初始化串口1 // printf("\r\n***温湿度传感器实验***\r\n"); /*初始化DTT11的引脚*/ DHT11_Init (); OLED_Init(); OLED_Clear(); while(1) { /*调用DHT11_Read_TempAndHumidity读取温湿度,若成功则输出该信息*/ if( DHT11_Read_TempAndHumidity ( & DHT11_Data )== SUCCESS) { OLED_Clear(); OLED_ShowCH(0,0,"湿度:"); OLED_ShowNum(70, 0, DHT11_Data.humi_int, 2, 1); OLED_ShowCH(0,2,"温度:"); OLED_ShowNum(70, 2, DHT11_Data.temp_int, 2, 1); } // delay_ms(1000); } }
修改的内容并不复杂,只是将printf()采用OLED显示函数替换而已,程序的结构并没有进行改动。
(1)首先想到的是有没有漏了什么重要的语句,检查下代码,因为程序并没有报错和警告。发现没有漏了什么。
(2)开始怀疑是不是杜邦线接触不良或者接线接错引起的,排除。没问题
(3)是不是温湿度传感器或者OLED坏了,单独测试,没问题。
(4)进行简单的调试,发现程序并没有执行if语句中的内容,怀疑是DHT11_Read_TempAndHumidity ( )函数的问题,在函数里面写LED点亮语句,发现LED没亮也就是说程序根本就没有进入到DHT11_Read_TempAndHumidity ( )里面。
(5)开始自闭。。。。。。
(6)开发板有没有问题呢?试下,没问题。
(7)继续自闭。。。。。。
自闭了很久突然觉得会不会是两个延时初始化函数的问题,因为DHT11.c文件用的延时函数放在SysTick.c文件中,OLED.c文件用的延时函数放在delay.c文件中,当时为了不改函数名,就继续用它们各自的延时函数,只是将头文件声明了下而已。因为两个延时函数都有初始化函数,所以就有了SysTick_Init();
delay_init();
将DHT11.C中使用到的延时函数用delay.c中的延时函数替换,只留一个延时初始化函数。然后问题就解决了。
void SysTick_Init(void)
{
/* SystemFrequency / 1000 1ms中断一次
* SystemFrequency / 100000 10us中断一次
* SystemFrequency / 1000000 1us中断一次
*/
// if (SysTick_Config(SystemFrequency / 100000)) // ST3.0.0库版本
if (SysTick_Config(SystemCoreClock / 1000000)) // ST3.5.0库版本
{
/* Capture error */
while (1);
}
// 关闭滴答定时器
SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;
}
void delay_init()
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8
fac_us=SystemCoreClock/8000000; //为系统时钟的1/8
fac_ms=(u16)fac_us*1000; //非OS下,代表每个ms需要的systick时钟数
}
其中的原理现在还是不清楚,估计是初始化了相同的寄存器数据吧,等以后明白了在来补充。
总结下,相同功能的函数还是一个就够了,避免出现函数命名或者一些不知名的错误,在自己写代码的时候也要考虑代码的移植性和函数变量等等的命名规范。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。