完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
在这个论坛上用原子的开发板也学习了许多,谢谢大家!
以下更改,如果有更好的实现方法,请指正! 更改的目的是为了将systick计数器用于中断定时,作为一个系统时间,开机后不停运行, 将来可以作为一个多任务的时间节拍使用! //Delay.c //使用芯片的 SysTick 部件进行软件延时的操作 // #include "delay.h" #include "sys.h" vu32 system_time =0u; //系统时间计数器,单位和节拍重装寄存器的设置值有关 static vu16 systick_reload_val; //系统节拍重装值 static vu16 systick_cnt_of_1us; //1us时间内的systick的计数值 //初始化延迟函数 //SYSTICK的时钟固定为HCLK时钟的1/8 //SYSCLK:系统时钟(MHz) void delay_init(u8 SYSCLK) { SysTick->CTRL = SysTick_Counter_Clear; //清除(停止) SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8; //选择外部时钟(bit2=0 HCLK/8) systick_reload_val= (u16)((SYSCLK *CONST_SYSTICK_NUM_OF_US) >>3); //节拍定时 CONST_SYSTICK_NUM_OF_US(us) SysTick->CTRL |= BIT(SYSTICK_CTRL_BIT_TICKINT); //使能中断 SysTick->LOAD = systick_reload_val; SysTick->VAL = 0x00; //清空计数器 MY_NVIC_Init(CONST_NVIC_PP_SYSTEM_TASK, CONST_NVIC_SP_MID_MAX, WWDG_IRQChannel); //属于系统级中断,高于一般的应用中断优先级 SysTick->CTRL |= SysTick_Counter_Enable; //开始计数(倒数) systick_cnt_of_1us =(SYSCLK >>3); //1us时间内的systick的计数值 system_time =0u; } //Systick 中断函数 void SysTick_Handler(void) { system_time ++; //??? //这里增加任务切换 } //得到系统时间,单位:1/8ms u32 get_system_time(void) { return system_time; } //得到和指定时间thetime的差值,单位:1/8ms u32 get_system_time_difference(u32 thetime) { //无符号数据减法, 0x0000 0001 - 0xffff fffa =0x0000 0007, 不会异常! return(system_time -thetime); } //延时指定毫秒数时间 //SysTick->LOAD为24位寄存器,所以,最大延时为: //nms<=0xffffff*8*CONST_SYSTICK_NUM_OF_US/SYSCLK*1000 void delay_xms(u32 Xms) { u32 start; start =system_time; Xms <<= 3; //系统时间单位是1/8ms while(get_system_time_difference(start) //为了兼容开发板的程序 void delay_xus(u32 Xus) { u32 start_val; u32 target_val; u32 all_systick_cnt; u16 systick_cnt; if(Xus ==0) return; all_systick_cnt =Xus *systick_cnt_of_1us; start_val = SysTick->VAL; //得到当前计数器的值(!=0) if(all_systick_cnt <=start_val) { //延时在剩余计数值内 target_val =start_val -(all_systick_cnt -1); //保证结束值非0![=0 进中断后重装,这里判不到==0的] while((SysTick->VAL >target_val) && (SysTick->VAL <=start_val) ); } else if(all_systick_cnt <=systick_reload_val) { //延时在剩余值之外,但是在一个节拍之内 target_val =start_val +(systick_reload_val -all_systick_cnt); while(SysTick->VAL !=target_val); } else { //延时在一个节拍之外 systick_cnt =all_systick_cnt/systick_reload_val; all_systick_cnt -= systick_cnt *systick_reload_val; //计数的余数,小于一个节拍 if(all_systick_cnt ==0) { do { if(SysTick->VAL ==start_val) { systick_cnt --; while(SysTick->VAL ==start_val); //因为在一个systick的计数值单位时间内,会多次执行while循环! 需要特殊处理!!【下同】 //离开的时候,已经不相等,则不要再 systick_cnt+1 了! 不能直接+1后再判断,因为可能瞬间不等而导致多计数一个节拍! } }while(systick_cnt !=0); } else if(all_systick_cnt <=start_val) { //延时余数在剩余计数值内 target_val =start_val -(all_systick_cnt -1); //保证结束值非0![=0 进中断后重装,这里判不到==0的] if(target_val ==SysTick->VAL) { while(target_val ==SysTick->VAL); //离开的时候,已经不相等,则不要再 systick_cnt+1 了! } else { systick_cnt++; //第一个判断点是延时的余数时间,节拍数要加1! 这里默认这里的语句操作时间小于一个systick的计数单位时间! } do { if(SysTick->VAL ==target_val) { systick_cnt --; while(SysTick->VAL ==target_val); //离开的时候,已经不相等,则不要再 systick_cnt+1 了! } }while(systick_cnt !=0); } else { //延时余数在剩余值之外 target_val = start_val + (systick_reload_val -all_systick_cnt); do { if(SysTick->VAL ==target_val) { systick_cnt --; while(SysTick->VAL ==target_val); //离开的时候,已经不相等,则不要再 systick_cnt+1 了! } }while(systick_cnt !=0); } } } //End Of File //Delay.h 文件 #ifndef _DELAY_H_ #define _DELAY_H_ #include <STM32f10x_lib.h> //常数的定义 #define CONST_SYSTICK_NUM_OF_US 125 //系统时间单位是1/8ms #define CONST_SYSTICK_DELAY_MAX_MS (u32)( *CONST_SYSTICK_NUM_OF_US) #define SYSTICK_CTRL_BIT_COUNTFLAG 16 //=1 倒计数为0发生过,读取时清除此位 #define SYSTICK_CTRL_BIT_CLKSOURCE 2 //=1 内核时钟 #define SYSTICK_CTRL_BIT_TICKINT 1 //=1 倒计数到0时挂起CPU(进入中断函数) #define SYSTICK_CTRL_BIT_ENABLE 0 //=1 开始倒计数 extern vu32 system_time; //系统时间,单位:1/8ms //函数的声明 extern void delay_init(u8 SYSCLK); extern void delay_xms(u32 Xms); extern void delay_xus(u32 Xus); #endif //End Of File |
|
相关推荐
5个回答
|
|
很给力啊
|
|
|
|
|
|
|
|
原子哥,是否考虑出一份ucos新手入门教程啊?看过ucos那本书,不过还是很晕啊
|
|
|
|
光看不练,肯定晕了.
|
|
|
|
无从下手啊,没有可以借鉴的。原子哥那例程我有读过了。主要是那滴答时钟不明白是怎么给ucos用的
|
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1758 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1613 浏览 1 评论
1053 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
721 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1670 浏览 2 评论
1931浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
721浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
563浏览 3评论
588浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
548浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-19 19:52 , Processed in 0.981533 second(s), Total 86, Slave 70 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号