专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

STM32延时函数分析

作者:佚名   来源:本站原创   点击数:  更新时间:2013年10月22日   【字体:

Cortex-M3内核处理器有个systick  24位倒计时定时器,当计数到0时,重新装载初值.

delay_init(u8 SYSCLK)            //定时初始化函数分析
{
   Systick->CTRL&=0xfffffffb;      //bit2清空,选择外部时钟  HCLK/8
  fac_us=SYSCLK/8;                     
  fac_ms=(u16)fac_us*1000;


 摘自STM32手册
     
6.2.6

系统时钟(SYSCLK)选择
系统复位后,HSI振荡器被选为系统时钟。当时钟源被直接或通过PLL间接作为系统时钟时,它将不能被停止。
只有当目标时钟源准备就绪了(经过启动稳定阶段的延迟或PLL稳定),从一个时钟源到另一个时钟源的切换才会发生。在被选择时钟源没有就绪时,系统时钟的切换不会发生。直至目标时钟源就绪,才发生切换。
在时钟控制寄存器(RCC_CR)里的状态位指示哪个时钟已经准备好了,哪个时钟目前被用作系统时钟。

Systick时钟那里来?



Systick时钟由系统时钟8分频后决定.

解析delay_us(u32 nus)函数

void delay_us(u32 nus)
{
u32 temp;
Systick->LOAD=nus*fac_us;         //装入定时值
Systick->VAL=0x00;                      //清空计数器值
Systick->CTRL=0x01;                  //开启倒计时定时器
do
{
 temp=Systick->CTRL;              //定时器状态赋给变量
}while((temp&0x01)&&(temp&(1<<16)));          //判断开启和是否计数到了0 (到达设定值)
Systick->CTRL=0x00;                                         //关闭定时
Systick->VAL=0x00;                                                //清空计数值

}




定时1us分析:
  由于Systick时钟设置为是系统时钟的8分频 ,假设SYSCLK=72M  则Systick=9MHZ

 因为fac_us是基数无单位

  fac_us=SYSCLK/8;  即72/8=9  则Systick->LOAD=nus*fac_us,   假设定时1us  则Systick->LOAD=9.
  因为Systick是9M的速度倒计时  所以9个计数时间为9*(1/9M)  就是1us 

必须保证nus<=(2^24)/fac_us

编程实例:    I/O口输出500us方波

#include <stm32f10x_lib.h>
#include "sys.h"
#include "delay.h"
#include "usart.h"

 
#define LED0 PBout(0)
#define LED1 PBout(1)

 

 
void led_init(void)
{
 RCC->APB2ENR|=1<<3;
 GPIOB->CRL&=0xffffff00;
 GPIOB->CRL|=0x00000033;   //推挽输出  
 GPIOB->ODR|=0xffff;

 
}

 

 
int main(void)
{
  Stm32_Clock_Init(9);
  delay_init(72);
  led_init();
  while(1)
  {
LED0=0;
delay_us(500);
LED0=1;
delay_us(500);
  }
}





delay_ms(u16 nms)函数分析:
 
void delay_ms(u16 nms)
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms;//时间加载(SysTick->LOAD为24bit)
SysTick->VAL =0x00; //清空计数器
SysTick->CTRL=0x01 ; //开始倒数
do
{
temp=SysTick->CTRL;
}
while(temp&0x01&&!(temp&(1<<16)));//等待时间到达
SysTick->CTRL=0x00; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}

由于fac_ms基数为9000  所以假设nms=1则 倒计时时间9000/9M=0.001s=1ms就是延时1ms
所以最大定时时间  T=2^24/9000=1864ms


延时实例:
  while(1)
  {
LED0=0;
delay_ms(500);
LED0=1;
delay_ms(500);
  }






改变最大延时方法:  降低PLL倍频,计算得到系统新频率.
int main(void)
{
  Stm32_Clock_Init(4);
  delay_init(32);
  led_init();
  while(1)
  {
LED0=0;
delay_ms(3000);
LED0=1;
delay_ms(3000);
  }
}


 



此时最大延时  由于SYSCLK=32M  所以Systick=4M   既fac_ms=4000
                         Tmax=2^24/4000=4194ms


如果设置超过4194发生溢出,定时就不准了
例子:
int main(void)
{
  Stm32_Clock_Init(4);
  delay_init(32);
  led_init();
  while(1)
  {
LED0=0;
delay_ms(4200);
LED0=1;
delay_ms(4200);
  }
}

 
 


 

参考文献:<<例说STM32
 >>
               <<STM32手册>>
关闭窗口

相关文章