STM32的SysTick延时方法
研究的杨桃电子的开发板,发现在“四种方法实现的LED闪灯程“”不是我想要的那种。我想要的是任意时间的延迟,他的程序里面则是24位滴答定时器倒数结束就算结束了,有个延时时间的最大值,所以需要找到别的办法来实现我想要的那种。
发现了二种解决办法,一种是使能SYS定时器的中断功能,一种是读取SysTick->CTRL寄存器位16标志位。
先谈另外一个发现:一般情况下,要对一个外设寄存器赋值,要先使能这个外设的时钟,类似GPIO。但是SysTick定时器不需要,它可以对SysTick->LOAD寄存器和SysTick->VAL寄存器直接赋值,而一旦对SysTick->CTRL寄存器赋值,这个滴答定时器就开始倒数了。所以就是滴答定时器一直是处以使能状态的。
方法一:采用SYS定时器的中断功能
Delay.h的头文件内容:
1 #ifndef __DELAY_H 2 #define __DELAY_H 3 #include "stm32f10x.h" 4 5 void Delay_ms(uint32_t nTime); 6 void TimingDelay_Decrement(void); 7 8 #endif
Delay.c的文件内容:
1 /*采用SysTick定时器中断方式做延时(程序起始处)*/ 2 uint32_t TimingDelay; //这个定义只能放外面 3 void Delay_ms(uint32_t nTime) //ms级延时 4 { 5 TimingDelay = nTime; 6 SysTick->LOAD=9000; //目前没有SysTick_SetReload(9000)这个函数 7 SysTick->VAL=0x00; //清空SysTick的值 8 SysTick->CTRL=0x00000003; //打开(使能)SysTick并且允许产生SysTick中断 9 while(TimingDelay != 0x00); //等待计数到0 10 SysTick->CTRL=0x00000000; //关闭(失能)SysTick 11 } 12 13 14 void TimingDelay_Decrement(void) //中断函数 15 { 16 if (TimingDelay != 0x00) 17 { 18 TimingDelay--; 19 } 20 } 21 22 /*采用SysTick定时器中断方式做延时(程序结束处)*/
stm32f10x_it.c文件中的中断函数内容:
1 extern void TimingDelay_Decrement(void); 2 void SysTick_Handler(void) 3 { 4 TimingDelay_Decrement(); 5 }
方法二:采用读取SysTick->CTRL寄存器位16标志位
Delay.h的头文件内容:
1 #ifndef __DELAY_H 2 #define __DELAY_H 3 #include "stm32f10x.h" 4 5 void SysTick_Delay_ms(uint32_t nTime); 6 7 #endif
Delay.c的文件内容:
1 /*采用SysTick定时器位16标志位读取方式做延时(程序起始处)*/ 2 3 void SysTick_Delay_ms(uint32_t nTime) //ms级延时 4 { 5 uint32_t i; 6 SysTick->LOAD=9000; 7 SysTick->VAL=0x00; 8 SysTick->CTRL=0x01; 9 for (i=0; i<nTime; i++) 10 { 11 // 当计数器的值减小到 0 的时候, CRTL 寄存器的位 16 会置 1 12 // 当置 1 时,读取该位会清 0 13 while ( !((SysTick->CTRL)&(1<<16)) ); 14 } 15 SysTick->CTRL=0x00; 16 } 17 18 /*采用SysTick定时器位16标志位读取方式做延时(程序结束处)*/
总体说来,第二种办法不涉及中断,是比较好的方法。