本帖最后由 lvben5d 于 2019-8-17 12:01 编辑
1. 前几日发的定时器帖子,有关初始化里,用库函数初始化分频系数,周期的 xxxx_init函数内,存在软件更新事件的代码,如果你不清除标志位,直接使能定时器中断,那么就会先进中断一次。导致有个别定时功能意外的激发。
2. 最近做LED点阵屏扫码程序时,发现对于08接口的单色屏扫16行大概,1ms就要扫1行,我把扫屏串行数据函数放在1ms定时器中断里,就会发现这个定时器会占用特别多CPU时间,我的串口中断即便在19200波特率下,总是会丢失字节(发生字节超时错误),原因在于定时器优先级高,且定时器内做的事情差不多需要0.5ms,我将串口中断优先级提升到可以抢占定时器中断,才不会发生串口字节丢失。虽然我主频已经是跑36MHZ了,串口中断接收1个字节,应该在1us内就可以中断处理完毕。
void TIMER14_IRQHandler(void)
{
timer_disable(TIMER14);
timer_interrupt_flag_clear(TIMER14, TIMER_INT_UP);
timer_counter_value_config(TIMER14, 0);
show_256x16_oneline(Sysinfo.scan_line);
if(16 == ++Sysinfo.scan_line) Sysinfo.scan_line = 0; //从第1行 扫到16行 再回到1行 舟而复始 索引0 是因为数组存储
timer_enable(TIMER14);
}
3.keil5.2x采用新一代complier 6编译器,可以快速提升编译速度,但对于代码优化会跟c5不同,从而导致运行跟预先不符合。 void delay_us(unsigned char ctr)
{
unsigned char nb;
volatile unsigned char nop=1;
for(; ctr>0; ctr--)
{
for(nb=0; nb<US_UPPER; nb++) //#elif defined (RISC_36MHZ) #define US_UPPER 5
nop++;
}
}
c6编译器 如果不对nop进行io修饰,全速运行下,这个for循环会比你想的快很多(不能通过指令执行时间*估算一共需要执行多少次来==软延迟效果),而c5编译下,即便不用volatile 修饰,运行的效果 软延时时间会接近你 每条指令时间*大致的指令数。
4. 我相信大家用的较多的应用往往包含USART,在大部分应用中,确保串口中断的优先级,在中断方式接收数据的时候,一定要快速读取接收到字节。否则容易出现字节超时错误OV,从代码健壮性和易于恢复来说,你的接收中断子程序里还是要对这个进行处理(判断标志位 清接收标志 读下接收寄存器)。一定要开1个定时器做字节超时保护,用于串口数据包异常下的自我恢复能力。
|