【AT-START-F423测评】多通道MODBUS测试

今天测试一下基于UART的MODBUS-RTU,AT32F423多大8路UART,做工业仪表是个不错的选择。
本次测试使用两个串口:
USART2配置为从机:9600,8N2, 站号1
USART3配置为主站:9600,8N2, 配置命令访问站号1

IO配置:

复制

// U2

{GPIOA, GPIO_MODE_MUX, GPIO_DRIVE_STRENGTH_STRONGER, GPIO_OUTPUT_PUSH_PULL, GPIO_PULL_NONE, GPIO_MUX_7, GPIO_PINS_2 | GPIO_PINS_3},        

// U3

{GPIOB, GPIO_MODE_MUX, GPIO_DRIVE_STRENGTH_STRONGER, GPIO_OUTPUT_PUSH_PULL, GPIO_PULL_NONE, GPIO_MUX_7, GPIO_PINS_10 | GPIO_PINS_11},

串口初始化:

复制


/*****************************************************************************

 * [url=home.php?mod=space&uid=247401]@brief[/url]           com modle init .

 * @param   none

 * [url=home.php?mod=space&uid=266161]@return[/url]  none

 * [url=home.php?mod=space&uid=72445]@[/url] Pass/ Fail criteria: none

 *****************************************************************************/

static void qc_port_Init(uu8 qcMode, uint32_t ulBaudRate, mb_parity_type eParity)

{

        usart_data_bit_num_type dat_bits;

        usart_stop_bit_num_type stop_bits;

        usart_parity_selection_type parity;



        qc_port_hal_cfg();



        qc_cb_set();

        qc_obj.mode = qcMode;

        qc_obj.dat_send = qc_port_send;



        qc_byte_send = qc_rtu_byte_send;



        // rtu mode

        if (MB_PAR_NONE == eParity)

        {

                dat_bits = USART_DATA_8BITS;

                stop_bits = USART_STOP_2_BIT;

                parity = USART_PARITY_NONE;

        }

        else if (MB_PAR_NONE_1S == eParity)

        {

                dat_bits = USART_DATA_8BITS;

                stop_bits = USART_STOP_1_BIT;

                parity = USART_PARITY_NONE;

        }

        else if (MB_PAR_ODD == eParity)

        {

                dat_bits = USART_DATA_9BITS;

                stop_bits = USART_STOP_1_BIT;

                parity = USART_PARITY_ODD;

        }

        else

        {

                dat_bits = USART_DATA_9BITS;

                stop_bits = USART_STOP_1_BIT;

                parity = USART_PARITY_EVEN;

        }



        // rtu timer

        if (ulBaudRate > 19200)

        {

                qc_obj.tim_sv = 3;

        }

        else

        {

                qc_obj.tim_sv = (com_timer_cal(ulBaudRate, (35 * 11 + 9) / 10, 300, 12000) + 99) / 100;

        }



        usart_init(qc_port, ulBaudRate, dat_bits, stop_bits);

        usart_parity_selection_config(qc_port, parity);

        usart_enable(qc_port, TRUE);



        nvic_irq_set(qc_uart_irqn, 0x00, 1);



        qc_tx1_rx0_enable(0);



        UART_TX_EN();

}

中断处理:

复制

/*****************************************************************************

 * [url=home.php?mod=space&uid=247401]@brief[/url] UART interrupt routine.

 * @param   none

 * [url=home.php?mod=space&uid=266161]@return[/url]  none

 *****************************************************************************/

void qc_isr()

{

        volatile uint32_t IntSt;

        volatile uint8_t Data;



        IntSt = qc_port->sts;



        if (IntSt & USART_RDBF_FLAG)

        {

                Data = UART_RCV_DAT();



                if ((IntSt & UART_RX_ERR_FLAG) != 0)

                {

                        if (qc_obj.rx_cnt >= 1)

                        {

                                qc_obj.err_hal = 1;

                        }

                        UART_RX_ERR_CLR();

                }



                qc_data_rcv(&qc_obj, Data);

        }

        else if ((qc_obj.tx_size <= qc_obj.tx_cnt) && (IntSt & USART_TDC_FLAG))

        {

                qc_send_end(&qc_obj);

                qc_tx1_rx0_enable(0);

                UART_TX_TC_CLR();

        }

        else if (IntSt & USART_TDBE_FLAG)

        {

                if (qc_data_send(&qc_obj, qc_rtu_byte_send, 1))

                {

                        UART_TX_TC_EN();

                }

        }

        else

        {

        }

}

U3主站命令:

复制

void qc_init(void)

{

        // master config

        qc03_Init(QC_MODE_MASTER, 9600, MB_PAR_NONE);

        mb.qc03.os_event_send = mb_os_send;



        mcmd.id = 1;

        mcmd.wdat = &mb_input[0].uval;

        mcmd.rdat = &mb_input[0].uval;

        mcmd.wa = 0;

        mcmd.wn = 96;

        mcmd.ra = 0x1800;

        mcmd.rn = 1;

        mcmd.callback = qc_callback;

        mcmd.attr = QC_MB_ATTR_HOLD_MW;

        mqc_stc_cmd_req(&mb.qc03, 0, &mcmd);

       

        mcmd.wdat = &mb_input[0].uval;

        mcmd.wa = 96;

        mcmd.wn = 96;

        mqc_stc_cmd_req(&mb.qc03, 1, &mcmd);



        // slave config

        qc02_Init(QC_MODE_SLAVE, 9600, MB_PAR_NONE);

        mb.qc02.os_event_send = mb_os_send;



        mcmd.id = 1;

        mcmd.wdat = &mb_input[0].uval;

        mcmd.rdat = &mb_input[0].uval;

        mcmd.wa = 16;

        mcmd.wn = 16;

        mcmd.ra = 0;

        mcmd.rn = 8;

        mcmd.callback = qc_callback;

        mcmd.attr = QC_MB_ATTR_HOLD_MW;

        mqc_stc_cmd_req(&mb.qc02, 0, &mcmd);

        mqc_stc_cmd_req(&mb.qc02, 1, &mcmd);

}


测试时,将评估板PA2连接PB10, PA3连接PB11可完成两个端口通信,运行结果如下:



为方便运行时观察,可以显示串口通信信息到OLED显示屏,效果如下:


任务资源信息:
 


至此,modbus移植测试成功,可以用来连接各种modbus接口的传感器和PLC设备了。

下面附上测试代码:
 

 AT32F423_EVAL.rar (4.59 MB)
编译环境:IAR EW for Arm 9.40
---------------------
作者:aple0807
链接:https://bbs.21ic.com/icview-3336710-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值