【STM32学习】SysTick_Init()和delay_Init()踩坑记录

第一次写博客,记录下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时钟数   
}		

其中的原理现在还是不清楚,估计是初始化了相同的寄存器数据吧,等以后明白了在来补充。

三、总结

总结下,相同功能的函数还是一个就够了,避免出现函数命名或者一些不知名的错误,在自己写代码的时候也要考虑代码的移植性和函数变量等等的命名规范。
在这里插入图片描述

  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值