CH579M开发笔记12——485通信方式

专栏目录:CH579M开发笔记——目录


功能概述

        上一篇文章中,我们简单学习了串口1的收发功能,使用的是查询方法接收串口数据。本文我们将基于串口3的进行中断方法的接收和发送,同时使用SP3485芯片,将串口数据转换为485信号和其他485设备进行通信。

        本文旨在讲解UART3的初始化和485通信的测试,串口通信的超时判断和状态机方法在本文代码中已经体现,我们将在下一篇文章中着重讲解该方法。

        开发板485接口的位置如下图所示↓↓。


核心代码

 

GPIO初始化

查看代码
GPIOA_SetBits(GPIO_Pin_9);
GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);
UART1_DefInit();
printf("Realiot UART test\r\n");
/////////////////////////////////////////////////////////////////////////
GPIOA_SetBits(GPIO_Pin_6);
GPIOA_ModeCfg(GPIO_Pin_6, GPIO_ModeOut_PP_5mA);
GPIOB_ResetBits(GPIO_Pin_3 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_9);
GPIOB_ModeCfg(GPIO_Pin_3 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_9, GPIO_ModeOut_PP_5mA);

 

串口3的参数配置及中断响应函数

查看代码

void uart3_init(u32 baudrate)
{
    GPIOA_SetBits(GPIO_Pin_5);
    GPIOA_ModeCfg(GPIO_Pin_4, GPIO_ModeIN_PU); // RXD-配置上拉输入
    GPIOA_ModeCfg(GPIO_Pin_5, GPIO_ModeOut_PP_5mA); // TXD-配置推挽输出,注意先让IO口输出高电平
    UART3_BaudRateCfg(baudrate);
    UART3_DefInit();
    UART3_ByteTrigCfg(UART_1BYTE_TRIG);
    UART3_INTCfg(ENABLE, RB_IER_RECV_RDY | RB_IER_LINE_STAT);
    NVIC_EnableIRQ(UART3_IRQn);
}

void UART3_IRQHandler(void)
{
    u8 rev = 0;
    switch (UART3_GetITFlag()) {
    case UART_II_LINE_STAT: // 线路状态错误
    {
        UART3_GetLinSTA();
    } break;
    case UART_II_RECV_RDY: // 数据达到设置触发点
    {
        rev = UART3_RecvByte();
        if (uart3_rx_sta == 0) {
            uart3_rx_sta |= 0x8000;
        }
        if ((uart3_rx_sta & 0xFF) < uart3_rx_max) {
            uart3_rx_buf[uart3_rx_sta & 0xFF] = rev;
            uart3_rx_sta++;
        }
        GPIOB_InverseBits(GPIO_Pin_3);
        uart3_rx_tcnt = 0;
    } break;

    case UART_II_RECV_TOUT: // 接收超时,暂时一帧数据接收完成
    {
    } break;
    case UART_II_THR_EMPTY: // 发送缓存区空,可继续发送
        break;
    case UART_II_MODEM_CHG: // 只支持串口0
        break;
    default:
        break;
    }
}

 

定时器的参数配置及中断响应函数

查看代码

void timer0_init(u16 ms)
{
    TMR0_TimerInit(FREQ_SYS / (1000 / ms)); // 设置定时时间 100us
    TMR0_ITCfg(ENABLE, TMR0_3_IT_CYC_END); // 开启中断
    NVIC_EnableIRQ(TMR0_IRQn);
}

void TMR0_IRQHandler(void) // TMR0 定时中断
{
    if (TMR0_GetITFlag(TMR0_3_IT_CYC_END)) {
        TMR0_ClearITFlag(TMR0_3_IT_CYC_END); // 清除中断标志
    }
    if ((++timer0_cnt) > 999) {
        timer0_cnt = 0;
        cycle_1000ms = 1;
    }
    if (timer0_cnt % 99 == 0) {
        cycle_100ms = 1;
    }

    if (timer0_cnt % 499 == 0) {
        cycle_500ms = 1;
    }

    if (uart3_rx_sta & 0x8000) {
        if (uart3_rx_tcnt++ > 20) {
            uart3_rx_tcnt = 0;
            uart3_rx_sta &= 0x3FFF;
            uart3_rx_sta |= 0x4000;
        }
    }
}

功能验证

     使用烧录工具将编译后的hex文件写入开发板后,使用串口助手(软件)+USB转485模块(硬件)向开发发送数据,可以看到开发板的将收到的数据原样返回。

 

注意事项

  • 如果无法达到实验效果,请确认485总线的A B接线是否正确(与串口通信的TX1↔RX2 TX2↔RX1方式不同,485总线的接线方式是A1↔A2 B1↔B2)。
  • SP3485芯片使用时,第2/3引脚短接,由PA6进行控制,高电平时处于发送状态;低电平时处于接收状态(两线485属于半双工通信,不可同时收发数据,请注意)。
  • 收发控制的PA6引脚电平状态改变后,增加5ms的延时,保证芯片的工作状态稳定和数据完整的收发,否则,会发生数据的丢失。一般情况下,在完成数据发送后,需要理解将485芯片的状态设置为接收状态,以免错过数据的接收。
posted @ 2022-02-10 16:03  realiot  阅读(553)  评论(0)    收藏  举报