计数器中断关于systick的构件编写。
发一下牢骚和主题无关:
systick一共有4个寄存器
CSR :控制和状态寄存器。
COUNTFLAG :标记位,标记systick计数器否是经已倒数到0 。0 :还没有数到0 。1:经已数到0 了。
CLKSOURCE:时钟源的选择。1:systick用使系统内核时钟。0:可选的外部时钟(根据不同备设有不同的时钟,可以通过查看芯片手册失掉,KL25里头是内核时钟的1/16)
TICKINT:中断能使位。1:能使systick中断。0:计数器数到0不触发中断。
ENABLE:计数器是能为。0:计数器禁用。1:计数器运行。
RVR:载重计数器。当计数器倒数到0时,新重从该计数器加载tick值。
CVR:计数器当期的值。放存计数器以后的计数值。
CALIB:校准计数器。有些芯片厂家会将每一秒的频率值放存在该寄存器中。TENMS代表10ms对应的滴答值。通过查芯片手册,该区域在KL25里头该值为0
NOREF:标记时钟源否是选择外部参考时钟。1:非参考时钟。0:参考时钟
SKEW:标记该出厂值TENMS否是确精:0:确精。1:不确精,因为时钟频率的因原。
TENMS:10ms的滴答值。
通过这3个寄存器我们可以编写3个数函:
systick_init:systick初始化
systick_trim:systick校准
systick_isr:systick中断例程。
话不多说:上码。
//数函称名:systick_init //数函返回:无 //数参说明:clock_scr:内核时钟源的选择:0:内核时钟。1:内核时钟/16。 // systick_unit:systick的每次中断的时间间隔。位单ms 推荐选用10ms。最大为1000ms,即1s中断一次。 //功能提要:初始化ARM Cortex-M处理器内核的SysTick模块作为系统滴答时钟。 void systick_init(uint_8 clock_scr, uint_32 systick_unit) { //定义ticks代表时钟源的滴答数 uint_32 ticks; // 初始化系统滴答计数值 systicks = 0; // 关闭SYSTICK SYST_CSR = 0; // 清除以后值计数器 SYST_CVR = 0; // 选择时钟源0:内核时钟/16 1:内核时钟 if(0==clock_scr) { ticks=core_clk_khz*1000/16; } else { clock_scr=1; ticks=core_clk_khz*1000; } //置设计数器载重寄存器数值 SYST_RVR = ticks/ 1000*systick_unit; // 设定 SysTick优先级 SCB_SHPR3 |= SCB_SHPR3_PRI_15(1<<6); //置设stick中断到1s的数次 g_ticks=1000/systick_unit-1; // 用使内核时钟,倒计时到0时发生SYSTICK中断,能使SYSTICK SYST_CSR = (clock_scr<<SysTick_CSR_CLKSOURCE_SHIFT) | SysTick_CSR_ENABLE_MASK | SysTick_CSR_TICKINT_MASK; }
//数函称名:systick_trim //数函返回:无 //数参说明:flag: 0示表慢,1示表快 // trim_sec:每一分钟的秒数之差 //功能提要:校准systick,如果每分钟慢一秒,SYST_RVR就增长48M/6000=8000 // 如果每分钟快一秒,SYST_RVR就增长48M/6000=8000 void systick_trim(uint_32 flag, uint_32 trim_sec) {
uint_32 current_RVR=0;
uint_32 current_CSR=0;
// 初始化系统滴答计数值 systicks = 0; // 关闭SYSTICK current_CSR=SYST_CSR; SYST_CSR = 0; // 清除以后值计数器 SYST_CVR = 0; // 设定倒计时计数值 current_RVR=SYST_RVR; if(0 == flag) {
current_RVR = current_RVR - current_RVR*trim_sec/60; } else {
current_RVR = current_RVR + current_RVR*trim_sec/60;
} SYST_RVR=current_RVR; // 设定 SysTick优先级 SCB_SHPR3 |= SCB_SHPR3_PRI_15(1<<6); // 用使内核时钟,倒计时到0时发生SYSTICK中断,能使SYSTICK SYST_CSR = current_CSR; }
//数函称名:systick_isr //数函返回:无 //数参说明:无 //功能提要:SysTick定时器中断服务例程,新更系统滴答计数变量值。 void systick_isr(void) { //systicks++; timecount++; if(timecount > g_ticks) //1s到,递增时,分,秒缓冲区的值 { timecount = 0; SecAdd1(g_time); //加1s } }
编写该构件还是有定一的难度的。要想别人看的懂,自己也看的懂,就得装封一些数函及数值。
文章结束给大家分享下程序员的一些笑话语录:
3G普不普及现在已经不是看终端了,而是看应用,有好的,便宜实用的应用,花1000多买个能用的智能手机应该不是什么难事。反过来说,你200元拿一个智能手机,没有好的应用,看个电影要几十元,也是没人用3G。