|
发表于 2016-9-6 13:19:26
|
显示全部楼层
从某处get的代码
- #include "stm32f30x.h"
- //使用DWT的时钟周期计数对延迟进行管理,与delay_systick不可同时使用
- #define DWT_CR *(volatile u32 *)0xE0001000
- #define DWT_CYCCNT *(volatile u32 *)0xE0001004
- #define DEM_CR *(volatile u32 *)0xE000EDFC
- #define DEM_CR_TRCENA (1 << 24)
- #define DWT_CR_CYCCNTENA (1 << 0)
复制代码
- static u8 cpuclkfeq; //用于保存cpu运行频率,可运行时动态修改
- static u32 startts, endts, wait_ms;
- //初始化延时系统,参数为CPU频率
- void delay_init(u8 clk)
- {
- cpuclkfeq = clk;
- //打开CYCCNT功能,并把计数器清零,最后打开计数器对cpu时钟进行向上计数
- DEM_CR |= DEM_CR_TRCENA;
- DWT_CR |= DWT_CR_CYCCNTENA;
- }
- //延时函数,参数为需要延时的微秒数
- void delay_us(u32 nus)
- {
- u32 ts;
- //保存进入函数时的计数器值
- startts = DWT_CYCCNT;
- ts = nus * cpuclkfeq - 8; //计算达到所需延时值的cpu时钟数,减去运行前面代码所需的时钟数
- endts = startts + ts; //计算达到所需延时时间的DWT_CYCCNT计数值,超过32bit所能表达的最大值2的32次方-1是自动绕回丢弃进位
- if(endts > startts) //判断是否跨越最大值边界
- {
- while(DWT_CYCCNT < endts); //等到计数到所需延时值的cpu时钟数值
- }
- else
- {
- while(DWT_CYCCNT > endts); //等待跨域32bit的最大值,2的32次方-1
- while(DWT_CYCCNT < endts); //等到计数到所需延时值的cpu时钟数值
- }
- }
- void delay_ms(u32 nms)
- {
- u32 ts;
- //保存进入函数时的计数器值
- startts = DWT_CYCCNT;
- ts = 1000 * nms * cpuclkfeq - 10; //计算达到所需延时值的cpu时钟数,减去运行前面代码所需的时钟数
- endts = startts + ts; //计算达到所需延时时间的DWT_CYCCNT计数值,超过32bit所能表达的最大值2的32次方-1是自动绕回丢弃进位
- if(endts > startts) //判断是否跨越最大值边界
- {
- while(DWT_CYCCNT < endts); //等到计数到所需延时值的cpu时钟数值
- }
- else
- {
- while(DWT_CYCCNT > endts); //等待跨域32bit的最大值,2的32次方-1
- while(DWT_CYCCNT < endts); //等到计数到所需延时值的cpu时钟数值
- }
- }
- void delay_us_set(u32 nus)
- {
- u32 ts;
- //保存进入函数时的计数器值
- startts = DWT_CYCCNT;
- ts = nus * cpuclkfeq - 8; //计算达到所需延时值的cpu时钟数,减去运行前面代码所需的时钟数
- endts = startts + ts; //计算达到所需延时时间的DWT_CYCCNT计数值,超过32bit所能表达的最大值2的32次方-1是自动绕回丢弃进位
- }
- void delay_ms_set(u32 nms)
- {
- u32 ts;
- //保存进入函数时的计数器值
- startts = DWT_CYCCNT;
- ts = 1000 * nms * cpuclkfeq - 10; //计算达到所需延时值的cpu时钟数,减去运行前面代码所需的时钟数
- endts = startts + ts; //计算达到所需延时时间的DWT_CYCCNT计数值,超过32bit所能表达的最大值2的32次方-1是自动绕回丢弃进位
- }
复制代码 |
|