1 overview
1.1 目的
本文档用于起点开发板的RTI(Real TimeInterrupt)实时时钟中断模块软件说明。
不局限于硬件功能的实现,着眼于实现高质量、优美的软件。
2 question
时钟源怎么选择?
3 软件实现
3.1 CodingRule
具体可在源码的 ..Sourcescode_rules.txt中可见。
3.2 driver层
3.2.1 新建drclock.h
增加MC9S12系统时钟设置,目标时钟频率48MHz。
3.2.2 新建drsys_config.h
增加驱动层参数设置,如外部时钟晶振。
3.2.3 新建drrti.h
3.2.3.1 新增宏函数drrti_config_1ms()
为中间层module层提供RTI的设置1ms中断的接口。
3.2.3.1.1 寄存器CPMUCLKS
在伪停止(pseddo stop mode)模式中RTI停止运行。
RTI时钟源选择为OSCCLK。
3.2.3.2 新增宏函数drrti_enable_rti_interrupt()drrti_disable_rti_interrupt()
中断使能宏函数drrti_enable_rti_interrupt(),drrti_init()调用。
中断失能宏函数drrti_disable_rti_interrupt(),关闭rti时调用。
3.2.3.3 新增宏函数drrti_clear_int_flag()
中断标志位,写1清零。不清零会一直触发中断。
3.2.4 drint.h
3.2.4.1 新增宏替换DRINT_RTI_ISR
3.2.5 drint.c
3.2.5.1 新增drint_rti_isr()函数
实时时钟中断处理函数。先调用中间层module层的中断处理函数,然后清中断标志位。
3.3 中间件module层修改
3.3.1 新建mdrti.c
change log:
3.3.1.1 增加mdrti_init()
使用宏MDRTI_PERIOD确定定时器的周期,调用不同的driver的配置函数,最后使能中断。所以该初始化函数应该最后调用。
3.3.1.2 新增mdrti_isr_callback()
中间层module层的中断回调函数。
目前使用1ms定时周期。
3.3.2 新建mdsys_cfg.c
增加mdsys_poweron_time_ms,mdsys_poweron_time_s用于记录系统运行时间长度。
3.3.3 新建mdtask.c
3.3.3.1 新增函数mdtask_init()
该函数可用于任务调度时,计算所有任务的周期数的最小公倍数。
首先,当系统时间计时器(mdrti_1ms_counter)能整除每个任务的周期数时,该任务会被执行。但是mdrti_1ms_counter的最大值应当为任务的周期数的最小公倍数或者UINT16_MAX,一般在设置任务周期时最好是1ms, 2ms, 4ms, 5ms,10ms, 20ms, 50ms, 100ms, 1000ms。
3.3.3.2 新增mdtask_schedule()
用于调用所有的周期函数,main函数的主体只需要调用该函数即可。暂时只有两个任务mdio_input_sample(); apl_key_process_task(); apl_led_blinking_task();
3.3.4 修改mdinit.c
调用所有中间层module层的初始化函数。
3.4 应用层
3.4.1 新建aplled_cfg.c
3.4.1.1 新增aplled_blinking_config_table[]
为了实现LED的周期闪烁和不同亮暗时长不同,增加配置数组。数组类型如下:
initial_status是LED初始状态:
io_index是对应的mdio_cfg.c中的mdio_output_cfg[]中对应的索引号:
3.4.1.2 新增aplled_blinking_info[]
在一个LED闪烁周期内,计算该LED亮的时间长度,当达到led_on_time或者(blink_period-led_on_time)时间时需要反转电平。
3.4.2 新建aplled.c
3.4.2.1 新增aplled_init()
用于设置LED的初识状态,需要在aplinit.c中aplinit()被调用。
3.4.2.2 新增apl_led_blinking_task()
周期任务,在mdtask.c中的mdtask_schedule()被调用,实现LED周期闪烁。
3.4.3 新建aplconfig.h
用于应用层参数配置。
3.5 main.c
只保留mdinit(),aplinit(), mdtask_schedule()。
4 基础内容
4.1 缩略语
4.2 介绍
RTI全称real time interrupt,实时中断,最基础的定时器中断。
4.3 软件功能
interrupt enable register
clock select register
RTI control register
reference divider register
4.3.1 RTI中断原理
RTI超时后,RTIF标志位置位,在RTIE为1时产生中断,RTIF置位后会立即开始下一次的周期定时。
4.3.2 中断周期计算
具体实现见4.2.2.1drrti_config_1ms()。
①RTI选择OSCCLK作为时钟源;
②使用RTI控制寄存器——CPMURTI寄存器设置超时时间。RTR[6:4]预分频位,RTR[3:0]计数器为;
③实时时钟超时周期 = (RTR[3:0]+1) * (2*(RTR[6:4]+1))^103/OSCCLK (当RTDEC=1);
④实时时钟超时周期 = (RTR[3:0]+1) * (2^(RTR[6:4]+9)/OSCCLK (当RTDEC=0);
如果设置1ms超时周期,RTDEC=1,OSCCLK = 8MHz,则RTR[3:0] = 0x07; RTR[6:4] =0.
4.4 电路
时钟外部晶振8MHz。
5 软件测试及调试
5.1 MCU register
5.1.1 CPMU寄存器
5.1.2 CPMURTI寄存器
5.2 任务调用
当mdtask_old_tick_count不等于mdrti_1ms_counter时,此时tick_count整除apl_key_process_task()任务周期APL_KEY_SAMPLM_TASK_PERIOD,如下图mdrti_1ms_counter为25936,整除4,所以可以在apl_key_process_task ()断点前停止。
此时tick_count整除apl_led_blinking_task()任务周期APL_LED_HANDLE_TASK_PERIOD,如下图mdrti_1ms_counter为25936,整除4,所以可以在apl_led_blinking_task ()断点前停止。
5.3 mdrti_1ms_counter溢出测试
ONGOING!
6 实物展示
上一篇:MC9S12G128模块化分层化软件架构之十——TaskSchedule任务调度
下一篇:MC9S12G128模块化分层化软件架构之八_QAC静态代码分析
推荐阅读最新更新时间:2024-11-05 11:27