2905|2

32

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

【GD32L233C-START评测】MODBUS测试 [复制链接]

    疫情期间隔离了,没事做,今天在L233测试了下MODBUS。

     L233的串口和其他系列的串口状态标志管理有些差别。比如帧错误,校验错误,TC标志需要手动清除,另外发送空中断标志在初始化后是0,发数据时单一像其他MCU那样开中断在中断中发数据是不行的,需要先发送一个数据产生发送空标志,然后开中断,剩余的数据在中断里面完成。

 

    为方便操作,定义下面一组串口操作宏:

// 数据收发
#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测试主要是串口收发管理程序的移植:
应用层初始化,调用扫描即可:

/******************************************************************************
* [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);
	}
}

本测试板子作为从机,测试结果如下

附上测试工程:

software.rar (1.83 MB, 下载次数: 85)

此帖出自GD32 MCU论坛

最新回复

为啥不可以在中断中发送数据?有点怪异。   详情 回复 发表于 2022-3-16 18:43
点赞 关注(1)
 

回复
举报

7608

帖子

2

TA的资源

五彩晶圆(高级)

沙发
 

为啥不可以在中断中发送数据?有点怪异。

此帖出自GD32 MCU论坛

点评

仅首次发送的时候要先发一字节产生TBF标志,剩余的在中断里面发。这是串口初始化后该标志为0导致的,其他MCU的该标志在初始化后是1,直接开中断就可以响应。  详情 回复 发表于 2022-3-16 19:16
 
个人签名

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

 
 

回复

32

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
freebsder 发表于 2022-3-16 18:43 为啥不可以在中断中发送数据?有点怪异。

仅首次发送的时候要先发一字节产生TBF标志,剩余的在中断里面发。这是串口初始化后该标志为0导致的,其他MCU的该标志在初始化后是1,直接开中断就可以响应。

此帖出自GD32 MCU论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表