返回列表 发新帖我要提问本帖赏金: 20.00元(功能说明)

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

[复制链接]
2070|1
 楼主| aple0807 发表于 2023-10-29 10:39 | 显示全部楼层 |阅读模式
本帖最后由 aple0807 于 2023-10-29 10:38 编辑

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

IO配置:
  1. // U2
  2. {GPIOA, GPIO_MODE_MUX, GPIO_DRIVE_STRENGTH_STRONGER, GPIO_OUTPUT_PUSH_PULL, GPIO_PULL_NONE, GPIO_MUX_7, GPIO_PINS_2 | GPIO_PINS_3},        
  3. // U3
  4. {GPIOB, GPIO_MODE_MUX, GPIO_DRIVE_STRENGTH_STRONGER, GPIO_OUTPUT_PUSH_PULL, GPIO_PULL_NONE, GPIO_MUX_7, GPIO_PINS_10 | GPIO_PINS_11},
串口初始化:

  1. /*****************************************************************************
  2. * [url=home.php?mod=space&uid=247401]@brief[/url]           com modle init .
  3. * @param   none
  4. * [url=home.php?mod=space&uid=266161]@return[/url]  none
  5. * [url=home.php?mod=space&uid=72445]@[/url] Pass/ Fail criteria: none
  6. *****************************************************************************/
  7. static void qc_port_Init(uu8 qcMode, uint32_t ulBaudRate, mb_parity_type eParity)
  8. {
  9.         usart_data_bit_num_type dat_bits;
  10.         usart_stop_bit_num_type stop_bits;
  11.         usart_parity_selection_type parity;

  12.         qc_port_hal_cfg();

  13.         qc_cb_set();
  14.         qc_obj.mode = qcMode;
  15.         qc_obj.dat_send = qc_port_send;

  16.         qc_byte_send = qc_rtu_byte_send;

  17.         // rtu mode
  18.         if (MB_PAR_NONE == eParity)
  19.         {
  20.                 dat_bits = USART_DATA_8BITS;
  21.                 stop_bits = USART_STOP_2_BIT;
  22.                 parity = USART_PARITY_NONE;
  23.         }
  24.         else if (MB_PAR_NONE_1S == eParity)
  25.         {
  26.                 dat_bits = USART_DATA_8BITS;
  27.                 stop_bits = USART_STOP_1_BIT;
  28.                 parity = USART_PARITY_NONE;
  29.         }
  30.         else if (MB_PAR_ODD == eParity)
  31.         {
  32.                 dat_bits = USART_DATA_9BITS;
  33.                 stop_bits = USART_STOP_1_BIT;
  34.                 parity = USART_PARITY_ODD;
  35.         }
  36.         else
  37.         {
  38.                 dat_bits = USART_DATA_9BITS;
  39.                 stop_bits = USART_STOP_1_BIT;
  40.                 parity = USART_PARITY_EVEN;
  41.         }

  42.         // rtu timer
  43.         if (ulBaudRate > 19200)
  44.         {
  45.                 qc_obj.tim_sv = 3;
  46.         }
  47.         else
  48.         {
  49.                 qc_obj.tim_sv = (com_timer_cal(ulBaudRate, (35 * 11 + 9) / 10, 300, 12000) + 99) / 100;
  50.         }

  51.         usart_init(qc_port, ulBaudRate, dat_bits, stop_bits);
  52.         usart_parity_selection_config(qc_port, parity);
  53.         usart_enable(qc_port, TRUE);

  54.         nvic_irq_set(qc_uart_irqn, 0x00, 1);

  55.         qc_tx1_rx0_enable(0);

  56.         UART_TX_EN();
  57. }
中断处理:
  1. /*****************************************************************************
  2. * [url=home.php?mod=space&uid=247401]@brief[/url] UART interrupt routine.
  3. * @param   none
  4. * [url=home.php?mod=space&uid=266161]@return[/url]  none
  5. *****************************************************************************/
  6. void qc_isr()
  7. {
  8.         volatile uint32_t IntSt;
  9.         volatile uint8_t Data;

  10.         IntSt = qc_port->sts;

  11.         if (IntSt & USART_RDBF_FLAG)
  12.         {
  13.                 Data = UART_RCV_DAT();

  14.                 if ((IntSt & UART_RX_ERR_FLAG) != 0)
  15.                 {
  16.                         if (qc_obj.rx_cnt >= 1)
  17.                         {
  18.                                 qc_obj.err_hal = 1;
  19.                         }
  20.                         UART_RX_ERR_CLR();
  21.                 }

  22.                 qc_data_rcv(&qc_obj, Data);
  23.         }
  24.         else if ((qc_obj.tx_size <= qc_obj.tx_cnt) && (IntSt & USART_TDC_FLAG))
  25.         {
  26.                 qc_send_end(&qc_obj);
  27.                 qc_tx1_rx0_enable(0);
  28.                 UART_TX_TC_CLR();
  29.         }
  30.         else if (IntSt & USART_TDBE_FLAG)
  31.         {
  32.                 if (qc_data_send(&qc_obj, qc_rtu_byte_send, 1))
  33.                 {
  34.                         UART_TX_TC_EN();
  35.                 }
  36.         }
  37.         else
  38.         {
  39.         }
  40. }
U3主站命令:
  1. void qc_init(void)
  2. {
  3.         // master config
  4.         qc03_Init(QC_MODE_MASTER, 9600, MB_PAR_NONE);
  5.         mb.qc03.os_event_send = mb_os_send;

  6.         mcmd.id = 1;
  7.         mcmd.wdat = &mb_input[0].uval;
  8.         mcmd.rdat = &mb_input[0].uval;
  9.         mcmd.wa = 0;
  10.         mcmd.wn = 96;
  11.         mcmd.ra = 0x1800;
  12.         mcmd.rn = 1;
  13.         mcmd.callback = qc_callback;
  14.         mcmd.attr = QC_MB_ATTR_HOLD_MW;
  15.         mqc_stc_cmd_req(&mb.qc03, 0, &mcmd);
  16.       
  17.         mcmd.wdat = &mb_input[0].uval;
  18.         mcmd.wa = 96;
  19.         mcmd.wn = 96;
  20.         mqc_stc_cmd_req(&mb.qc03, 1, &mcmd);

  21.         // slave config
  22.         qc02_Init(QC_MODE_SLAVE, 9600, MB_PAR_NONE);
  23.         mb.qc02.os_event_send = mb_os_send;

  24.         mcmd.id = 1;
  25.         mcmd.wdat = &mb_input[0].uval;
  26.         mcmd.rdat = &mb_input[0].uval;
  27.         mcmd.wa = 16;
  28.         mcmd.wn = 16;
  29.         mcmd.ra = 0;
  30.         mcmd.rn = 8;
  31.         mcmd.callback = qc_callback;
  32.         mcmd.attr = QC_MB_ATTR_HOLD_MW;
  33.         mqc_stc_cmd_req(&mb.qc02, 0, &mcmd);
  34.         mqc_stc_cmd_req(&mb.qc02, 1, &mcmd);
  35. }

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

为方便运行时观察,可以显示串口通信信息到OLED显示屏,效果如下:
mbdisp.png
任务资源信息:
shell.png
至此,modbus移植测试成功,可以用来连接各种modbus接口的传感器和PLC设备了。

下面附上测试代码:
AT32F423_EVAL.rar (4.59 MB, 下载次数: 39)
编译环境:IAR EW for Arm 9.40


打赏榜单

ArterySW 打赏了 20.00 元 2024-01-24
理由:作品优秀

wangwu1976@ 发表于 2024-1-24 13:48 | 显示全部楼层
做得真不错,顶一个
您需要登录后才可以回帖 登录 | 注册

本版积分规则

77

主题

326

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部