stm32F40x系统滴答定时器计算方法及应用(寄存器版本)
系统滴答定时器计算方法,在这记录一下,防止时间久了遗忘
下图是:时钟树的一小部分:在STM32F4xx中文参考手册.pdf文档第107页可以找到。
框架图:
上面框架图是来自于:Cortex M3与M4权威指南.pdf 文档第313-315页
公式:
1Hz = 1s 要计1个数用时1s
10Hz = 0.1s 要计10个数用时1s
100Hz = 0.01s 要计100个数用时1s
21MHz ---> 1s 要计21M个数用时1s 21000 000个数
100ms ---> 2100 000个数
ms级 ---> 21 000
如:
1s = 21 000 000
100ms = 21 000 00
换算
168MHz = 168000KHz = 168000000Hz
外部时钟 <=> 168M/8=21M
①:
存放24位:二进制(1111 1111 1111 1111 1111 1111)=>16进制 0xFFFFFF
计数最多为:16777215次
16777215 / 168 = 0.099864375s = 99.864375ms 约等于 100ms
16777215 四舍五入 16800000
168MHz = 168000000
16800000/168000000 = 0.1s = 100ms 这个计时太短(过快)无法满足所需
如果是使用了21MHz来计算的话刚好是168的8倍
所以可以计算800ms
②:
同样计算公式: oxffffff / 21000
16777215 / 21 = 798.9ms 这个时间基本满足所有计时时间
也就是最多可以记这么多毫秒: oxffffff / 21000 = 798.9ms
配置流程:
①:系统滴答ms级延时设置
选择时钟源、清空当前计数器的值、设置重载值、使能计数器、等待定时时间到、关闭倒数计数器、计数器清零
②:系统滴答us级延时设置
选择时钟源、清空当前计数器的值、设置重载值、使能计数器、等待定时时间到、关闭倒数计数器、计数器清零
systick.h文件
#ifndef __SYSTICK_H__
#define __SYSTICK_H__
#include <stm32f4xx.h>
void systick_delay_ms(u16 nms);
#endif
systick.c文件
#include "sysTick.h"
/*
函数功能:系统滴答豪秒延时
函数形参:nms
返回值:无
*/
void systick_delay_ms(u16 nms)
{
//21MHz = 21000000Hz/s = 21000Hz/ms
if(nms>(0xffffff / 21000)) //毫秒,只要是大于这个值就不允许延时
{
return;
}
SysTick->CTRL &= ~(0x1<<2);//选择21MHz的时钟源
SysTick->VAL = 0x00; //清空当前计数器的值
SysTick->LOAD = ms * 21000;//要记的数
SysTick->CTRL |= 1<<0; //使能倒计数寄存器
/** SysTick->CTRL中的Set bit 16 - count flag **/
while(!(SysTick->CTRL & (0x1<<16)))//等待定时时间达到产生(位16)的标志
{
;
}
SysTick->CTRL &= ~(1<<0); //关闭倒数计数器 清零 可以不写
SysTick->VAL &= ~(1<<0); //计数器清零 可以不写,寄存器有自动清零功能
}
main.c
#include "led.c"
#include "systick.h"
int main(void)
{
led_init();
while(1)
{
LED1_ON;
systick_delay_ms(500); //延时0.5s
LED1_OFF;
systick_delay_ms(500); //延时0.5s
}
}