用stm32库函数编写的modbus源代码

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

用stm32库函数编写的modbus源代码

说在前面的话:

1.请勿盲目抄袭。这个协议使用了一个定时器,所以在别处请不要再使用,如果定时器不够用,可以做虚拟定时器。也就是采用一个物理的定时器产生时基。在这个定时器的中断函数中可以给相应的多个定时器自加1.每个虚拟定时器可以用两个变量分别控制打开关闭,和计时。这个已经试验通过了可行的。其实就跟我们使用物理的定时器一样,只不过物理的定时器是用晶振产生时基。

2.这段代码已经调试通过了,也硬件试验过,没有问题,如果你出现问题了,看看你在主函数的的各种基本配置有没有完成。如果要使用06和10号功能,你还需要在主函数中建立一个100个元素的数组,每个元素是16位。

3.写这个文档的时候,这个协议已经是半年前完成的了。所以有些东西记得不是很清楚了,如果说错了,请以实际为准。只是不想让这份代码死在电脑中了,所以才想起来要拿出来分享,支持开源精神。

4.如果实在实在是没有弄出来,请联系我,可以共同交流,我的邮箱:***********************

#include"stm32f10x.h"

/* 此Modbus协议暂时只支持RTU模式,只支持作为Modbus从设备。

暂时支持的功能码(16进制)如下表所示:

01.读线圈状态(读多个输出位的状态,有效地位为0-31)

02.读输入位状态(读多个输入位的状态,有效地位为0-31)

03.读保持寄存器(读多个保持寄存器的数值,有效地位为0-99)

04.读输入寄存器(读多个输入寄存器的数值,有效地址为0-1)

05.强制单个线圈(强制单个输出位的状态,有效地位为0-31)

06.预制单个寄存器(设定一个寄存器的数值,有效地址为0-99)

0F.强制多个线圈(强制多个输出位的状态,有效地址为0-31)

10.预制多个寄存器(设定多个寄存器的数值,有效地址为0-99)

暂时支持的错误代码为:

01 不合法功能代码从机接收的是一种不能执行功能代码。发出查询命令后,该代码指示无程序功能。(不支持的功能代码)

02 不合法数据地址接收的数据地址,是从机不允许的地址。(起始地址不在有效范围内)

03 不合法数据查询数据区的值是从机不允许的值。(在起始地址的基础上,这个数量是不合法的)

供用户调用的函数有:

1.void ModInit(u8 Id);//用于Modbus初始化,在函数调用前,必须初始化函数,用于Main函数中

2.void ModRcv(void);//用于modbus信息接收,放在串口接收中断

3.void ModSend(void);//用于modbus信息接收,放在串口发送中断

例如:void USART1_IRQHandler(void) //USART1中断

{

if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)

{

void ModRcv(void);

……

……

……

}

if(USART_GetITStatus(USART1,USART_IT_TC)!=RESET)

{

void ModSend(void);//用于modbus信息接收

……

……

……

}

}

*/

//modbus用通讯参数

u8 Tim_Out;//大于3.5个字符时间,保守取3ms (波特率9600的时候大约2点几毫秒)

u8 Rcv_Complete;//一帧是否已经接受完成

u8 Send_Complete;//一帧是否已经发送完成

u8 Com_busy;//通讯繁忙,表示上一帧还未处理结束

u8 Rcv_Buffer[210];//用来存放接收到的完整的一帧数据(第一个字节用来存放接收到的有效字节数,也就是数组中的有效字节数)

u8 Send_Buffer[210];//用来存放待发送的完整的一帧数据(第一个字节用来存放待发送的有效字节数,也就是数组中的有效字节数)

u8 Rcv_Data;//用来存放接收的一个字节

u8 Send_Data;//用来存放要发送的一字节

u8 Mod_Id;//用来标志作为从站的站号

u8 Rcv_Num;//用来表示接收的一帧的有效字节数(从功能码到CRC校验)

u8 Send_Num;//用来表示待发送的一帧的字节数

u8 *PointToRcvBuf;//用来指向接收的数据缓存

u8 *PointToSendBuf;//用来指向带发送的数据缓存

u8 Comu_Busy;//用来表示能否接收下一帧数据

u8 HaveMes;

extern u16 HoldReg[100];

//CRC校验查表用参数

/* CRC 高位字节值表*/

static u8 auchCRCHi[] = {

0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,

0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,

0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,

0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,

0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,

0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,

0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,

0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,

0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,

0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,

0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,

相关文档
最新文档