浅析STM32 中常用的三个函数(sys.c,delay.c,usart.c)之二

Posted 18689400042qaz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅析STM32 中常用的三个函数(sys.c,delay.c,usart.c)之二相关的知识,希望对你有一定的参考价值。

2.delay函数也是非常常用的函数

  提到delay延时,我就想到了STM32里面专门用来延时的systick定时器,常用 ck定时器是一个24位倒计数定时器,当计到0时,将从RELOAD寄存器重新自动装载初值。只要不把Systick的控制使能位及状态寄存器中的使能位清除,就会永不停息的工作。这个定时器的优点如下:

  1)不占用中断       2)也不占用系统定时器

 

#include "delay.h"
#include "stm32f10x.h"
void delay_init()
{

    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);    //选择外部时钟  HCLK/8
    fac_us=SystemCoreClock/8000000;            //为系统时钟的1/8    f=72000000/8/(10^6)=9    t=(1/9)/10^6s  =(1/9)us
                             //因此,时基fac_us=9,因为9*(1/9us)=1us,使滴答定时器计数9次就是1us
    fac_ms=(u16)fac_us*1000;               //fac_us*1000就是9000,9000*(1/9us)=1000us=1ms    


//延时nus
//nus为要延时的us数.                                               
void delay_us(u32 nus)
{        
    u32 temp;             
    SysTick->LOAD=nus*fac_us;                     //时间加载               
    SysTick->VAL=0x00;                            //清空计数器
    SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;    //开始倒数      
    do
    {
        temp=SysTick->CTRL;
    }while((temp&0x01)&&!(temp&(1<<16)));        //等待时间到达   
    SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;    //关闭计数器
    SysTick->VAL =0X00;                           //清空计数器     
}
//延时nms
//注意nms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms
//对72M条件下,nms<=1864 
void delay_ms(u16 nms)
{                     
    u32 temp;           
    SysTick->LOAD=(u32)nms*fac_ms;                //时间加载(SysTick->LOAD为24bit)
    SysTick->VAL =0x00;                            //清空计数器
    SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;    //开始倒数  
    do
    {
        temp=SysTick->CTRL;
    }while((temp&0x01)&&!(temp&(1<<16)));        //等待时间到达   
    SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;    //关闭计数器
    SysTick->VAL =0X00;                           //清空计数器              
} 

 

 

 

 此时,没有什么比一个权威的M3中文手册来说明更合适的了!!!

技术图片

这个是CTRL寄存器,即SysTick->CTRL所指向的寄存器,他是SysTick控制及状态寄存器。

其中值得一提的是位0(使能位)以及位16(COUNTFLAG)

  SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数  

  在延时函数里面SysTick_CTRL_ENABLE_Msk的定义是#define SysTick_CTRL_ENABLE_Msk            (1ul << 0)

  其实就是把CTRL寄存器的位0(开始计数使能位)置1,方式是|=0x01. 

  SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器


关闭计数器函数,通过把除使能位之外的位置1,使能位清零,即&=(~0x01)

位16是SysTick定时器中的一个计数完成一周期的标志位,当SysTick定时器从装载值计到0时,读取该位就是1,读取该位之后该位置0.
常用于等待计数程序中,当作计数结束标志位,表明已经计时规定时间。
 do
    {
        temp=SysTick->CTRL;
    }while((temp&0x01)&&!(temp&(1<<16)));        //等待时间到达



技术图片

SysTick->LOAD=(u32)nms*fac_ms;                //时间加载(SysTick->LOAD为24bit)
SysTick->LOAD所指向的就是SysTick重装载数值寄存器,他的作用如他的描述所述,就是当SysTick定时器计数到0时,自动装载RELOAD
SysTick重装载数值寄存器里面的值。



技术图片

SysTick->VAL =0x00;                            //清空计数器
SysTick->VAL所指向的就是SysTick当前数值寄存器,他保存的是计数器当前的值,会随着倒计数一直不断变小。




注意:
fac_us 微妙级时基是计数到一微妙所要计数的次数
f=72*(10^6)/8=9*(10^6)HZ=9MHZ    //SysTick 定时器的计数频率
t=1/f=1/9us              //SysTick 定时器的计数时间
fac_us=1us/t=1us/(1/9us)=9 //即9为微妙级时基
而fac_us毫秒级时基是计数到一毫秒所要计数的次数
fac_ms=1000*fac_us

最大计时时间T
SysTick->LOAD为24位寄存器,因此,最大装载值是0xFFFFFF,
而T=0xFFFFFF*1/9us=1864135us=1864ms;





以上是关于浅析STM32 中常用的三个函数(sys.c,delay.c,usart.c)之二的主要内容,如果未能解决你的问题,请参考以下文章

STM32F103五分钟入门系列GPIO的常用库函数使用方法总结+一个网络上的误区

浅析STM32之usbh_def.H

SYSTEM文件夹下的sys文件夹学习小结

单片机STM32开发中常用库函数分析

STM32 常用GPIO操作函数记录

求助,STM32库函数RCC