專注電子技術(shù)學(xué)習(xí)與研究
當前位置:單片機教程網(wǎng) >> MCU設(shè)計實例 >> 瀏覽文章

STM32延時函數(shù)分析

作者:佚名   來源:本站原創(chuàng)   點擊數(shù):  更新時間:2013年10月22日   【字體:

Cortex-M3內(nèi)核處理器有個systick  24位倒計時定時器,當計數(shù)到0時,重新裝載初值.

delay_init(u8 SYSCLK)            //定時初始化函數(shù)分析
{
   Systick->CTRL&=0xfffffffb;      //bit2清空,選擇外部時鐘  HCLK/8
  fac_us=SYSCLK/8;                     
  fac_ms=(u16)fac_us*1000;


 摘自STM32手冊
     
6.2.6

系統(tǒng)時鐘(SYSCLK)選擇
系統(tǒng)復(fù)位后,HSI振蕩器被選為系統(tǒng)時鐘。當時鐘源被直接或通過PLL間接作為系統(tǒng)時鐘時,它將不能被停止。
只有當目標時鐘源準備就緒了(經(jīng)過啟動穩(wěn)定階段的延遲或PLL穩(wěn)定),從一個時鐘源到另一個時鐘源的切換才會發(fā)生。在被選擇時鐘源沒有就緒時,系統(tǒng)時鐘的切換不會發(fā)生。直至目標時鐘源就緒,才發(fā)生切換。
在時鐘控制寄存器(RCC_CR)里的狀態(tài)位指示哪個時鐘已經(jīng)準備好了,哪個時鐘目前被用作系統(tǒng)時鐘。

Systick時鐘那里來?



Systick時鐘由系統(tǒng)時鐘8分頻后決定.

解析delay_us(u32 nus)函數(shù)

void delay_us(u32 nus)
{
u32 temp;
Systick->LOAD=nus*fac_us;         //裝入定時值
Systick->VAL=0x00;                      //清空計數(shù)器值
Systick->CTRL=0x01;                  //開啟倒計時定時器
do
{
 temp=Systick->CTRL;              //定時器狀態(tài)賦給變量
}while((temp&0x01)&&(temp&(1<<16)));          //判斷開啟和是否計數(shù)到了0 (到達設(shè)定值)
Systick->CTRL=0x00;                                         //關(guān)閉定時
Systick->VAL=0x00;                                                //清空計數(shù)值

}




定時1us分析:
  由于Systick時鐘設(shè)置為是系統(tǒng)時鐘的8分頻 ,假設(shè)SYSCLK=72M  則Systick=9MHZ

 因為fac_us是基數(shù)無單位

  fac_us=SYSCLK/8;  即72/8=9  則Systick->LOAD=nus*fac_us,   假設(shè)定時1us  則Systick->LOAD=9.
  因為Systick是9M的速度倒計時  所以9個計數(shù)時間為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)函數(shù)分析:
 
void delay_ms(u16 nms)
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms;//時間加載(SysTick->LOAD為24bit)
SysTick->VAL =0x00; //清空計數(shù)器
SysTick->CTRL=0x01 ; //開始倒數(shù)
do
{
temp=SysTick->CTRL;
}
while(temp&0x01&&!(temp&(1<<16)));//等待時間到達
SysTick->CTRL=0x00; //關(guān)閉計數(shù)器
SysTick->VAL =0X00; //清空計數(shù)器
}

由于fac_ms基數(shù)為9000  所以假設(shè)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倍頻,計算得到系統(tǒng)新頻率.
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


如果設(shè)置超過4194發(fā)生溢出,定時就不準了
例子:
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手冊>>
關(guān)閉窗口

相關(guān)文章