stm32 滴答时钟实现较准时延时功能
时间:10-02
整理:3721RD
点击:
前记:
以前自己在编写延时函数的时候,经常是for()结构或者while()结构以及do while{}结构。但这3种方法是非常的粗糙,在我现在的工作中是不能满足其精度的。由于stm32中有个滴答时钟,于是以后stm32相关的延时程序,打算拿它作挡箭牌了。
首先是,stm32 的数据手册上并没有滴答时钟的东西,只说了其会产生中断,具体如何,没说。谷歌了几遍,又查询了些许资料,发现来源于<<xxx权威指南>>和<<xxx技术手册>>。
然后在网上发现使用其作为延迟功能有两个方法,一个是使用中断方式,一个是使用查询方式<非中断>。
延时程序的头文件Delay.h
- #ifndef _DELAY_H_
- #define _DELAY_H_
- void delay_init(u8 SYSCLK);
- void delay_ms(u16 nms);
- void delay_us(u32 Nus);
- #endif
- /**********************************************************
- 文件:Delay.c
- 函数:void delay_init(u8 SYSCLK);
- void delay_ms(u16 nms);
- void delay_us(u32 Nus);
- 说明:三个函数实现的功能是不采用中断方式,并且用stm32系统滴答时钟来实现延时功能。
- 出自 正点原子<<stm32不完全手册>> -- 该程序设计的理念在该书中已经讲解。
- ***********************************************************/
- #include <stm32f10x.h>
- #include "Delay.h"
- static u8 fac_us=0;//us延时倍乘数
- static u16 fac_ms=0;//ms
- /**************************************************
- Name: delay_init
- 功能:应用程序延时函数初始化,包括为滴答时钟准备相关数值
- 参数:u8 SYSCLK
- 返回:None
- ***************************************************/
- void delay_init(u8 SYSCLK)
- {
- SysTick->CTRL&=0xfffffffb;//设置滴答时钟的时钟源:bit 2清空,选择外部时钟HCLK/8
- fac_us = SYSCLK / 8;
- fac_ms = (u16)fac_us*1000;
- }
- /**************************************************
- 名字:delay_ms
- 共能:应用程序ms级别的延时实现
- 参数:u16 nms
- 返回:None
- ***************************************************/
- void delay_ms(u16 nms)
- {
- u32 temp;
- SysTick->LOAD=(u32)nms*fac_ms;//时间加载
- SysTick->VAL =0x00; //清空计数器
- SysTick->CTRL=0x01 ; //开始倒数
- do
- {
- temp=SysTick->CTRL;
- }
- while(temp&0x01&&!(temp&(1<<16)));//等待时间到达
- SysTick->CTRL=0x00; //关闭计数器
- SysTick->VAL =0X00; //清空计数器
- }
- /***********************************************************
- 名字:delay_us
- 功能:应用程序us级别的延时实现
- 参数:u32 Nus
- 返回:None
- ************************************************************/
- 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)));//等待时间到达
- SysTick->CTRL=0x00; //关闭计数器
- SysTick->VAL =0X00; //清空计数器
- }
- 调用该延时函数的例程 test.c
- #include <stm32f10x.h>
- #include "Hardware/led.h"
- #include "Delay.h"
- /*LED 灯闪灭函数*/
- void loop(void)
- {
- while(1){
- GPIO_ResetBits(GPIOD, GPIO_Pin_2);
- delay_ms(1000); //ms级别延时函数的调用
- GPIO_SetBits(GPIOD, GPIO_Pin_2);
- delay_ms(1000);
- }
- }
- int main()
- {
- SystemInit();
- delay_init(72);//延时函数初始化,并传参数
- led_init();//led初始化
- loop();//调用led闪灭函数
- }