一、概述

前段时间研究了FreeModbus的主机程序,发现虽然好用,但是移植起来麻烦;基于此自己手搓了一个基于STM32F407hal开发的裸机ModbusMaster程序。

二、应用

整理的一个思路:

主机主要有读写两种指令:

读数据:

1)先发送数据,同时启动定时器(用于超时计时和接收计时)

2)等待接受数据

3)没有接收到数据且达到超时时间则数据重发;接收到数据则处理数据,置位标志位重新发送数据。

参考代码:

void ModbusMaster_Read03(uint8_t slave, uint16_t StartAddr, uint16_t num)
{
//	    int j;
   static uint16_t crc;//计算的CRC校验位
	if(Modbus_Master.SendFlag==0&&Modbus_Master.ReFlag==0)//没有发送数据在发送中,也没有接收数据在处理中
	{
		Modbus_Master.SlaveAddr = slave;
		Modbus_Master.Txbuf[0] = slave; //这是要匹配的从机地址
		Modbus_Master.Txbuf[1] = 0x03; //功能码
		Modbus_Master.Txbuf[2] = StartAddr / 256; //起始地址高位
		Modbus_Master.Txbuf[3] = StartAddr % 256; //起始地址低位
		Modbus_Master.Txbuf[4] = num / 256; //寄存器个数高位
		Modbus_Master.Txbuf[5] = num % 256; //寄存器个数低位
		crc = Modbus_CRC16( &Modbus_Master.Txbuf[0], 6); //获取CRC校验位
		Modbus_Master.Txbuf[6] = crc / 256; //寄存器个数高位
		Modbus_Master.Txbuf[7] = crc % 256; //寄存器个数低位
		
		Modbus_rs485_send_data(Modbus_Master.Txbuf,8);
		Modbus_Master.SendFlag = 1; //表示发送数据完毕	
		
		btim_tim2_int_Open();
	
	}
    //发送数据包装完毕
}

写数据:

1)写数据

2)等待从机返回应答数据

3)再次写数据

参考代码:

void ModbusMaster_Write06(uint8_t slave, uint16_t StartAddr, uint16_t Data)
{
//	    int j;
   static uint16_t crc;//计算的CRC校验位
	if(Modbus_Master.SendFlag==0&&Modbus_Master.ReFlag==0)//没有发送数据在发送中,也没有接收数据在处理中
	{
		Modbus_Master.SlaveAddr = slave;
		Modbus_Master.Txbuf[0] = slave; //这是要匹配的从机地址
		Modbus_Master.Txbuf[1] = 0x06; //功能码
		Modbus_Master.Txbuf[2] = StartAddr / 256; //起始地址高位
		Modbus_Master.Txbuf[3] = StartAddr % 256; //起始地址低位
		Modbus_Master.Txbuf[4] = Data / 256; //寄存器个数高位
		Modbus_Master.Txbuf[5] = Data % 256; //寄存器个数低位
		crc = Modbus_CRC16( &Modbus_Master.Txbuf[0], 6); //获取CRC校验位
		Modbus_Master.Txbuf[6] = crc / 256; //寄存器个数高位
		Modbus_Master.Txbuf[7] = crc % 256; //寄存器个数低位
		
		Modbus_rs485_send_data(Modbus_Master.Txbuf,8);
		Modbus_Master.SendFlag = 1; //表示发送数据完毕	
		
		btim_tim2_int_Open();
	
	}
    //发送数据包装完毕
}

测试数据:

三、完整代码链接

基于STM32F407Hal库的ModbusMaster主机程序;裸机框架资源-CSDN下载

更多推荐