2644 views|2 replies

31

Posts

0

Resources
The OP
 

【GD32L233C-START Review】MODBUS Test [Copy link]

I was quarantined during the epidemic and had nothing to do, so I tested MODBUS on L233 today.

The serial port status flag management of L233 is slightly different from that of other series. For example, the frame error, check error, and TC flag need to be cleared manually. In addition, the send empty interrupt flag is 0 after initialization. When sending data, it is not possible to open an interrupt and send data in the interrupt like other MCUs. You need to send a data first to generate the send empty flag, then open the interrupt, and the remaining data is completed in the interrupt.

For easy operation, define the following set of serial port operation macros:

// 数据收发
#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

Modbus testing is mainly the transplantation of the serial port transceiver management program:
application layer initialization, call scanning:

/******************************************************************************
* [url=home.php?mod=space&uid=159083]@brief[/url] Slave device handle.
*               
* @param   none
*
* [url=home.php?mod=space&uid=784970]@return[/url] 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_BAUD_115200], 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] = 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);
	}
}

This test board is used as a slave, and the test results are as follows

Attached is the test project:

software.rar (1.83 MB, downloads: 85)

This post is from GD32 MCU

Latest reply

Why can't I send data in an interrupt? That's a bit weird.   Details Published on 2022-3-16 18:43
 

7452

Posts

2

Resources
2
 

Why can't I send data in an interrupt? That's a bit weird.

This post is from GD32 MCU

Comments

Only when sending for the first time, you need to send one byte to generate the TBF flag, and the rest are sent in the interrupt. This is caused by the flag being 0 after the serial port is initialized. The flag of other MCUs is 1 after initialization, and they can respond directly by opening the interrupt.  Details Published on 2022-3-16 19:16
 
Personal signature

默认摸鱼,再摸鱼。2022、9、28

 
 

31

Posts

0

Resources
3
 
freebsder posted on 2022-3-16 18:43 Why can't I send data in an interrupt? It's a bit weird.

Only when sending for the first time, you need to send one byte to generate the TBF flag, and the rest are sent in the interrupt. This is caused by the flag being 0 after the serial port is initialized. The flag of other MCUs is 1 after initialization, and they can respond directly by opening the interrupt.

This post is from GD32 MCU
 
 
 

Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

Related articles more>>
Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list