【记录】实现delay
2016-07-02 11:06
274 查看
1. 实现方法
处理器有一个24位的系统定时器,SysTick。该定时器向下计数。计数到0后,重新从STK_LOAD寄存器中重载计数值,继续向下计数。使用SysTick的优点是,不用占用中断和定时器资源。2. 相关寄存器
STK_CTRL:0-bit,计数器使能位;
1-bit,选择时钟源
16-bit,计数到0后,该标志位被置1
STK_LOAD
计数值重载寄存器,当计数值计数到0后,将从该寄存器中重新加载计数值。
STK_VAL
保存当前计数值
#include "delay.h" static u8 fac_us = 0; static u16 fac_ms = 0; void delay_init(u8 sys_clock) { SysTick->CTRL &= ~(1<<2); //external clock fac_us = sys_clock/8; //AHB/8 fac_ms = (u16)fac_us*1000; } //n < 2^24/fac_us //sys_clock = 168MHz, fac_us=21MHz, 2^24/fac_us=798915 void delay_us(u32 n) { u32 temp; SysTick->LOAD = n*fac_us; //connter SysTick->VAL = 0; //clear current value SysTick->CTRL = 0x01; //start timer do { temp = SysTick->CTRL; }while((temp&0x01)&&!(temp&(1<<16))); //16-bit will be set 0 when current value is 0 SysTick->CTRL = 0x00; //stop timer SysTick->VAL = 0x00; //clear current value } //@sys_clock=168MHz, n < 798 void delay_ms(u16 n) { u32 temp; SysTick->LOAD = (u32)n*fac_ms; SysTick->VAL = 0x00; SysTick->CTRL = 0x01; do { temp = SysTick->CTRL; }while((temp&0x01)&&!(temp&(1<<16))); //16-bit will be set 0 when current value is 0 SysTick->CTRL = 0x00; //stop timer SysTick->VAL = 0x00; //clear current value }
实现更长的延时(超过798.915ms)。方法是多次调用上面实现的delay_ms。如果需要延时5s。5000ms>798.915ms,所以无法使用delay_ms。按照delay_long_ms的方法,每一个repeat可以延时540ms,repeat=5000/540=9, remain = 5000%540=140。对于用户而言,直接调用
delay_long_ms(5000);
程序中使用540的原因。理论上这个数值越接近798.915越好,但是我们要注意,798915这个值是按照系统时钟168MHz下计算出来的。
2^24*8/clock
而有些时候,系统可以工作在248MHz频率下,超频使用。此时2^24*8/248=541200。考虑到驱动的兼容性,选择540作为单次最大延时时间。
void delay_long_ms(u16 n) { u8 repeat = n / 540; u16 remain = n % 540; while(repeat) { delay_ms(540); repeat--; } if(remain) delay_ms(remain); }
参考
STM32F3与 F4 系列 Cortex M4 内核编程手册STM32F4 开发指南(寄存器版)
STM32F4xxx中文参考手册
相关文章推荐
- QWebEngineView与js交互
- cywin 蛋疼到死的 chmod ... Invalid argument
- Swap Two Nodes in Linked List
- 基于rem的响应式布局
- 35.静态链接库和动态链接库
- Hibernate注解配置与XML配置区别
- Android图形系统之Surface、SurfaceView、SurfaceHolder及SurfaceHolder.Callback之间的联系
- 关于Javascript表单验证
- windows Hook 消息分类
- Oracle的高水位线介绍
- eclipse导入项目出现中文乱码解决方案
- Java基础——序列化
- Java千百问_08JDK详解(015)_JVMTI提供哪些功能
- java.util.concurrent并发包诸类概览
- oracle undo与redo的区别
- Swift 柯里化(Currying)
- 给织梦DEDECMS系统添加栏目图片
- hdu4651
- mongo集群迁移删除孤立文档
- c++内存对齐的问题