【GD32L233C-START评测】MODBUS测试
<p> 疫情期间隔离了,没事做,今天在L233测试了下MODBUS。</p><p> L233的串口和其他系列的串口状态标志管理有些差别。比如帧错误,校验错误,TC标志需要手动清除,另外发送空中断标志在初始化后是0,发数据时单一像其他MCU那样开中断在中断中发数据是不行的,需要先发送一个数据产生发送空标志,然后开中断,剩余的数据在中断里面完成。</p>
<p> </p>
<p> 为方便操作,定义下面一组串口操作宏:</p>
<pre>
<code>// 数据收发
#define UART_SEND_DAT(dat) USART_TDATA(mbPORT) = dat
#define UART_RCV_DAT() USART_RDATA(mbPORT)
// 缓冲状态
#define UART_RX_NE_ST() ((USART_STAT(mbPORT)& USART_STAT_RBNE) != 0) //rx not empty
#define UART_TX_NF_ST() (0 != (USART_STAT(mbPORT)& USART_STAT_TBE)) //tx not full
#define UART_TX_TC_ST() (USART_STAT(mbPORT) & (USART_STAT_TC))
#define UART_TX_TC_CLR() USART_INTC(mbPORT) = USART_INTC_TCC
// 接收控制
#define UART_RX_EN()USART_CTL0(mbPORT) |= USART_CTL0_UEN | USART_CTL0_REN
#define UART_RX_INT_EN()USART_CTL0(mbPORT) |= USART_CTL0_UEN | USART_CTL0_REN | USART_CTL0_RBNEIE
#define UART_RX_INT_DIS() USART_CTL0(mbPORT) &= ~(USART_CTL0_REN | USART_CTL0_RBNEIE)
// 发送控制
#define UART_TX_EN()USART_CTL0(mbPORT) |= USART_CTL0_UEN | USART_CTL0_TEN
#define UART_TX_INT_EN()USART_CTL0(mbPORT) |= USART_CTL0_UEN | USART_CTL0_TBEIE | USART_CTL0_TEN
#define UART_TX_INT_DIS() USART_CTL0(mbPORT) &= ~(USART_CTL0_TBEIE | USART_CTL0_TCIE)
// 错误标志及清除
#define UART_RX_ERR_FLAG (USART_STAT_PERR | USART_STAT_FERR)
#define UART_RX_ERR_CLR() USART_INTC(mbPORT) = USART_INTC_PEC | USART_INTC_FEC
</code></pre>
<p>modbus测试主要是串口收发管理程序的移植:<br />
应用层初始化,调用扫描即可:</p>
<pre>
<code>/******************************************************************************
* @brief Slave device handle.
*
* @param none
*
* @return none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
void modbus_task(const void *argv)
{
mb_cmd_buff_type mcmd;
mb_obj_init(&mb.obj00);
//master config
mb00_Init(MB_RTU_SLAVE, mb_baud_tab, MB_PAR_NONE);
mb.obj00.slave_id = 1;
mb.obj00.rtu_master_delay_set = 3;
mb.obj00.rcv_end_handle_comp = rcv_end_handle_comp;
mb.obj00.os_event_send = mb_os_send;
mb.obj00.os_event_base = 2 << 4;
mb.obj00.rtu_length_cut = 1;
//cmd config
mcmd.device_id = 0;
mcmd.cmd = FUN_CODE_READ_COILS;
mcmd.dat = mb_tst.pv_w;
mcmd.dat_addr = 0;
mcmd.amount = 48;
mcmd.call_back = 0;
mb.obj00.api->stc_cmd_req(0, &mcmd);
mcmd.cmd = FUN_CODE_READ_DISCRETE;
mb.obj00.api->stc_cmd_req(1, &mcmd);
mcmd.cmd = FUN_CODE_W_R_MULTIPLE_REG;
mb.obj00.api->stc_cmd_req(2, &mcmd);
mcmd.cmd = FUN_CODE_W_R_MULTIPLE_REG;
mb.obj00.api->stc_cmd_req(3, &mcmd);
mcmd.cmd = FUN_CODE_WRITE_MULTIPLE_REG;
mb.obj00.api->stc_cmd_req(4, &mcmd);
mcmd.cmd = FUN_CODE_WRITE_MULTIPLE_COIL;
mb_tst.pv_w = 0;
mb.obj00.api->stc_cmd_req(5, &mcmd);
//task handle
for (;;)
{
osEvent event;
// wait modbus event
event = osSignalWait(0, 1000);
(void)event;
mb_poll(&mb.obj00);
mb_tst.obj_size = sizeof(mb.obj00);
}
}</code></pre>
<p>本测试板子作为从机,测试结果如下</p>
<p></p>
<p>附上测试工程:</p>
<p></p>
<p>为啥不可以在中断中发送数据?有点怪异。</p>
freebsder 发表于 2022-3-16 18:43
为啥不可以在中断中发送数据?有点怪异。
<p>仅首次发送的时候要先发一字节产生TBF标志,剩余的在中断里面发。这是串口初始化后该标志为0导致的,其他MCU的该标志在初始化后是1,直接开中断就可以响应。</p>
页:
[1]