STC32G12K128/STC32G8K64系列芯片的串口超时中断功能,因为需要进入串口中断额外处理,所以在高波特率接受场景,易造成中断过多
(Ai8051U、STC32G144K246新版的硬件超时中断修复了这个问题)
以及,带有串口DMA接受,但是无硬件超时中断的AI8H8K64U、Ai8H4K64TLCD、Ai8H1K08T也可以参考此进行功能增加
从而可以方便的完成高速串口接受不定长数据,且包与包之间间隔较短的情况。
说明:此功能需要占用完整的一组PWM,PWM不能做其他用处了,一组PWM可以用于一个串口接受的监控,PWMA和PWMB两组就可以分别用作两个串口的接受超时中断
超时中断时钟数可设置,且拥有硬件中断(PWM中断)
以下程序以STC32G12K128为演示平台,设置主频为24Mhz,需要外部短接PWM1P(P20)和RXD(P30)
串口通讯频率选择为500Kbps,通过串口助手发送后,会在结束后返回当前发送了多长的数据(通过DMA接受完成字节读取)
这里可以通过调整程序设置,实现PWMA组通过PWM1P或PWM2P监控,PWMB组通过PWM5或PWM6监控
以下为演示效果:
发送了三个字符串,右边的HEX蓝色为单片机返回的字符长度
程序的思路为:
使用SMCR从模式的触发模式(定时器CEN启动受控,关闭不受控),设置下降沿有效(串口的起始位),等待有效边沿来启动PWMA定时器 第一个下降沿后,PWM计数器开始向上计数,超过CCR3设置的值后,通过通道3比较中断,来切换为复位模式(有效边沿时复位CNTR),同时关闭通道3中断(较小值),设置有效边沿为上升沿有效(串口的结束位) 复位模式下只要有数据就会不断清空CNTR,如果长时间没发数据,CNTR持续增长,超过CCR4设置的值后,通道4(较大值)比较中断触发,清空CNTR,然后切换为触发模式,关闭PWM定时器,并且打开通道3比较,等待第二次发送。这个时候就可以作为超时中断引出了 给客户只需要引出通道4比较中断即可。通道1、2需要留作输入(方便切换PWM1P或者PWM2P的所有IO口),不可更改。
以下为完整程序(仅PWM中断部分,主循环无需多余代码)
- ////////////////////////////////////////
- // PWMA中断服务程序
- // 入口参数: 无
- // 函数返回: 无
- ////////////////////////////////////////
- void PWMA_ISR(void) interrupt PWMA_VECTOR
- {
- //<<AICUBE_USER_PWM0_ISR_CODE1_BEGIN>>
- // 在此添加中断函数用户代码
- sr1 = PWMA_SR1;
- sr1 &= PWMA_IER;
- //启动触发点
- if (sr1&0x08) //判断PWM捕获/比较中断
- {
- //PWMA_CNTRH = 0x00;//可选,更稳定一些
- //PWMA_CNTRL = 0x00;
- PWMA_SMCR = 0x54;//(PWM1P输入)+(复位模式)
- PWMA_IER = 0x10;//关闭启动触发点1
- PWMA_CCER1 = 0x11;//上升沿有效
- }
- //超时触发点
- if (sr1&0x10) //判断PWM捕获/比较中断
- {
- PWMA_CR1 = 0x00;
- PWMA_CNTRH = 0x00;
- PWMA_CNTRL = 0x00;
- PWMA_SMCR = 0x56;//(PWM1P输入)+(触发模式)
- PWMA_IER = 0x08;//CC3,CC4中断
- PWMA_CCER1 = 0x33;//下降沿有效
- SBUF = DMA_UR1R_DONE;//测试数据,接受了多少个长度的数据
- DMA_UR1R_CR = 0x00;//关闭DMA
- DMA_UR1R_CR = 0xA1;//重新开始接受
- }
- PWMA_SR1 = 0x00;//清除PWM捕获/比较中断标志
- //<<AICUBE_USER_PWM0_ISR_CODE1_END>>
- }
-
-
- //<<AICUBE_USER_FUNCTION_IMPLEMENT_BEGIN>>
- // 在此添加用户函数实现代码
- void PWM_OVER_Init(void)
- {
- PWMA_ENO = 0x00;//关闭所有输出通道
- PWMA_CR1 = 0x00;
- PWMA_CR2 = 0x00;
- PWMA_SMCR = 0x56;//(PWM1P输入)+(触发模式)
- //PWMA_SMCR = 0x54;//(PWM1P输入)+(复位模式)
- PWMA_IER = 0x08;//CC3中断
- PWMA_CCER1 = 0x00;
- PWMA_CCER2 = 0x00;
- PWMA_CCMR1 = 0x01;//TI1FP1
- PWMA_CCMR2 = 0x01;//TI2FP2
- PWMA_CCMR3 = 0x60;//输出,关闭预装载
- PWMA_CCMR4 = 0x60;//输出,关闭预装载
- PWMA_CCER1 = 0x33;//下降沿有效
- //PWMA_CCER1 = 0x11;//上升沿有效
- PWMA_CCER2 = 0x11;//CC3,4使能
- PWMA_CNTRH = 0x00;
- PWMA_CNTRL = 0x00;
- PWMA_PSCRH = 0x00;
- PWMA_PSCRL = 0x00;
- PWMA_ARRH = 0xff;
- PWMA_ARRL = 0xff;
- PWMA_RCR = 0x00;
- PWMA_CCR3H = *(unsigned char *)&cap1;
- PWMA_CCR3L = *((unsigned char *)&cap1+1);
- PWMA_CCR4H = *(unsigned char *)&cap2;
- PWMA_CCR4L = *((unsigned char *)&cap2+1);
- PWMA_BKR = 0x80;
- PWMA_EGR = 0x01;
- }
- //<<AICUBE_USER_FUNCTION_IMPLEMENT_END>>
复制代码 以下为使用STC32G12K128的测试程序,在屠龙刀3.2板上测试通过
uart1_over.zip
(485.57 KB, 下载次数: 0)
这个程序目前设置的是PWM1P输入,如果想要用PWM1P的其他通道作为输入,可通过PWMA_PS切换到其他通道
如果恰好RXD跟PWM口在同一个端口上,则可以不用外部飞线,直接就可以使用这个硬件超时功能
例如STC32G12K128中,串口2的P1.0和P1.1,串口3的P0.0和P0.1就可以直接使用
如果想要切换为PWM2P输入,只需要更改高4位为6即可,
使用PWMB组,可以直接更换PWMA关键词为PWMB,然后CCR1,2,3,4对应CCR5,6,7,8即可实现替换
PWMA_SMCR = 0x66;//(PWM2P输入)+(触发模式)
PWMA_SMCR = 0x64;//(PWM2P输入)+(复位模式)
|