当前位置: 首页 > news >正文

rtthread的串口框架、485框架

一、串口接收超时中断的实现。

 1. rtthread中定义的串口超时结构体

定义串口接收超时的结构体
CM_TMR0_TypeDef       为TM0的实例(实际有CM_TMR0_1 CM_TMR0_2 对应华大460的两个TMR0单元 )

channel 每个timer0有两个通道(TMR0_CHA、TMR0_CHB)

clock 为FCG2_PERIPH_TMR0_1、FCG2_PERIPH_TMR0_2

timeout_bits 为超时的位个数  40表示40bit位传输时间

irq_config 包含 .irq_num  中断IRQ .irq_prio 中断优先级 .int_src 中断源

irq_callback 中断回调指针

/* HC32 config Rx timeout */
struct hc32_uart_rxto
{
    CM_TMR0_TypeDef             *TMR0_Instance;
    rt_uint32_t                 channel;
    rt_uint32_t                 clock;
    rt_size_t                   timeout_bits;
#if defined (HC32F460) || defined (HC32F4A0)
    struct hc32_irq_config      irq_config;
    func_ptr_t                  irq_callback;
#endif
};

eg 如下格式化 

#define UART1_RXTO_CONFIG                                       \
    {                                                           \
        .TMR0_Instance = CM_TMR0_1,                             \
        .channel       = TMR0_CH_A,                             \
        .clock         = FCG2_PERIPH_TMR0_1,                    \
        .timeout_bits  = 20UL,                                  \
        .irq_config    =                                        \
        {                                                       \
            .irq_num   = BSP_UART1_RXTO_IRQ_NUM,                \
            .irq_prio  = BSP_UART1_RXTO_IRQ_PRIO,               \
            .int_src   = INT_SRC_USART1_RTO,                    \
        },                                                      \
    }

 hc32_dma_config中调用hc32_uart_rx_timeout

/* Initialization uart rx timeout for DMA */
hc32_uart_rx_timeout(serial);

hc32_uart_rx_timeout中根据serial的rx_timeout初始化TMR0

     启用TMR0的时钟 (TMR0_1 或TMR0_2)

FCG_TMR0_CLK(uart->config->rx_timeout->clock, ENABLE);

清零CNTR ,    //TMR0_Instance为CM_TMR0_1 或CM_TMR0_2

    /* TIMER0 basetimer function initialize */
    TMR0_SetCountValue(TMR0_Instance, ch, 0U);

使用外部时钟XTAL32 分频系数1。计算CMPR的值。

 

    TMR0_StructInit(&stcTmr0Init);
    stcTmr0Init.u32ClockDiv = TMR0_CLK_DIV1;
    stcTmr0Init.u32ClockSrc = TMR0_CLK_SRC_XTAL32;
    if (TMR0_CLK_DIV1 == stcTmr0Init.u32ClockDiv)
    {
        alpha = 7UL;
    }
    else if (TMR0_CLK_DIV2 == stcTmr0Init.u32ClockDiv)
    {
        alpha = 5UL;
    }
    else if ((TMR0_CLK_DIV4 == stcTmr0Init.u32ClockDiv) || \
             (TMR0_CLK_DIV8 == stcTmr0Init.u32ClockDiv) || \
             (TMR0_CLK_DIV16 == stcTmr0Init.u32ClockDiv))
    {
        alpha = 3UL;
    }
    else
    {
        alpha = 2UL;
    }
    /* TMR0_CMPA<B>R calculation formula: CMPA<B>R = (RTB / (2 ^ CKDIVA<B>)) - alpha */
    ckdiv   = 1UL << (stcTmr0Init.u32ClockDiv >> TMR0_BCONR_CKDIVA_POS);
    cmp_val = ((rtb + ckdiv - 1UL) / ckdiv) - alpha;
    DDL_ASSERT(cmp_val <= 0xFFFFUL);
    stcTmr0Init.u16CompareValue = (uint16_t)(cmp_val);
    TMR0_Init(TMR0_Instance, ch, &stcTmr0Init);

2.启用USART的 RX_TIMEOUT功能,将为每一字节启动定时功能。

    /* TMR0_CMPA<B>R calculation formula: CMPA<B>R = (RTB / (2 ^ CKDIVA<B>)) - alpha */
    ckdiv   = 1UL << (stcTmr0Init.u32ClockDiv >> TMR0_BCONR_CKDIVA_POS);
    cmp_val = ((rtb + ckdiv - 1UL) / ckdiv) - alpha;
    DDL_ASSERT(cmp_val <= 0xFFFFUL);
    stcTmr0Init.u16CompareValue = (uint16_t)(cmp_val);
    TMR0_Init(TMR0_Instance, ch, &stcTmr0Init);
    TMR0_HWStartCondCmd(TMR0_Instance, ch, ENABLE);
    TMR0_HWClearCondCmd(TMR0_Instance, ch, ENABLE);
    /* Clear compare flag */
    TMR0_ClearStatus(TMR0_Instance, (uint32_t)(0x1UL << (ch * TMR0_STFLR_CMFB_POS)));

#if defined (HC32F460) || defined (HC32F4A0)
    NVIC_EnableIRQ(uart->config->rx_timeout->irq_config.irq_num);
#endif
    USART_ClearStatus(uart->config->Instance, USART_FLAG_RX_TIMEOUT);
    USART_FuncCmd(uart->config->Instance, (USART_RX_TIMEOUT | USART_INT_RX_TIMEOUT), ENABLE);

3.发送超时后会置为TMO中断

irq_config 和irq_callback 绑定,当TMO置位时触发IRQ中断执行irq_callback 

hc32_install_irq_handler(&uart_config[i].rx_timeout->irq_config, 
uart_config[i].rx_timeout->irq_callback, RT_FALSE);

相关文章:

  • c++中sleep是什么意思(不是Sleep() )
  • 保姆级教程 | Office-Word中图目录制作及不显示图注引文的方法
  • Linux第十四节 — 环境变量和进程地址空间
  • 在VS中如何将控制台(console)项目改为窗口(window)项目
  • python~http的请求参数中携带map
  • 【AI表格处理工具】
  • 如何使用Spring Boot实现商品的管理系统
  • [AI相关]生成视频-第一个项目,20k星开源MoneyPrinterTurbo
  • 【网络】高级IO(2)
  • NX二次开发搜索槽或者刻字面
  • 【第四节】C++设计模式(创建型模式)-Builder(建造者)模式
  • 2025年-G14-Lc88-278.第一个坏版本 -java版
  • 【电机控制】42步进电机+arduino:WHEELTEC_MS42DDC
  • ubuntu部署小笔记-采坑
  • 【Java】File 类
  • SQLite 删除表
  • 054 redisson
  • 安全面试3
  • Python 中read、readline、readlines 有哪些区别?
  • 针对不同文本长度的处理方案,结合层次化编码和检索优化策略
  • 杨国荣︱《老子智慧八十一讲》及其他
  • “穿越看洪武”,明太祖及其皇后像台北故宫博物院南院展出
  • 铁路上海站迎五一返程客流最高峰,今日预计到达75.9万人次
  • 想要“逆转”糖尿病,减少这两处脂肪是关键
  • 自我田野|从城市搬到农村生活,我找回了真实和附近
  • 体坛联播|拜仁遭绝平未能提前夺冠,刘翔钻石联赛纪录作古