用stm32库函数编写的modbus源代码.pdf
《用stm32库函数编写的modbus源代码.pdf》由会员分享,可在线阅读,更多相关《用stm32库函数编写的modbus源代码.pdf(38页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、用 stm32 库函数编写的 modbus 源代码 说在前面的话:1.请勿盲目抄袭。这个协议使用了一个定时器,所以在别处请不要再使用,如果定时器不够用,可以做虚拟定时器。也就是采用一个物理的定时器产生时基。在这个定时器的中断函数中可以给相应的多个定时器自加 1.每个虚拟定时器可以用两个变量分别控制打开关闭,和计时。这个已经试验通过了可行的。其实就跟我们使用物理的定时器一样,只不过物理的定时器是用晶振产生时基。2.这段代码已经调试通过了,也硬件试验过,没有问题,如果你出现问题了,看看你在主函数的的各种基本配置有没有完成。如果要使用 06 和10 号功能,你还需要在主函数中建立一个 100 个元素
2、的数组,每个元素是 16位。3.写这个文档的时候,这个协议已经是半年前完成的了。所以有些东西记得不是很清楚了,如果说错了,请以实际为准。只是不想让这份代码死在电脑中了,所以才想起来要拿出来分享,支持开源精神。4.如果实在实在是没有弄出来,请联系我,可以共同交流,我的邮箱:*#includestm32f10 x.h/*此 Modbus 协议暂时只支持 RTU 模式,只支持作为 Modbus 从设备。暂时支持的功能码(16 进制)如下表所示:01.读线圈状态(读多个输出位的状态,有效地位为0-31)02.读输入位状态(读多个输入位的状态,有效地位为0-31)03.读保持寄存器(读多个保持寄存器的数
3、值,有效地位为0-99)04.读输入寄存器(读多个输入寄存器的数值,有效地址为0-1)05.强制单个线圈(强制单个输出位的状态,有效地位为0-31)06.预制单个寄存器(设定一个寄存器的数值,有效地址为0-99)0F.强制多个线圈(强制多个输出位的状态,有效地址为0-31)10.预制多个寄存器(设定多个寄存器的数值,有效地址为0-99)暂时支持的错误代码为:01 不合法功能代码从机接收的是一种不能执行功能代码。发出查询命令后,该代码指示无程序功能。(不支持的功能代码)02 不合法数据地址接收的数据地址,是从机不允许的地址。(起始地址不在有效范围内)03 不合法数据查询数据区的值是从机不允许的值
4、。(在起始地址的基础上,这个数量是不合法的)供用户调用的函数有: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(
5、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_Buffer210;/用来存放接收到的完整的一帧数据(第一个字节用来存放接收到的有效字节数,也就是数组中的有效字
6、节数)u8 Send_Buffer210;/用来存放待发送的完整的一帧数据(第一个字节用来存放待发送的有效字节数,也就是数组中的有效字节数)u8 Rcv_Data;/用来存放接收的一个字节 u8 Send_Data;/用来存放要发送的一字节 u8 Mod_Id;/用来标志作为从站的站号 u8 Rcv_Num;/用来表示接收的一帧的有效字节数(从功能码到 CRC 校验)u8 Send_Num;/用来表示待发送的一帧的字节数 u8*PointToRcvBuf;/用来指向接收的数据缓存 u8*PointToSendBuf;/用来指向带发送的数据缓存 u8 Comu_Busy;/用来表示能否接收下一帧
7、数据 u8 HaveMes;extern u16 HoldReg100;/CRC 校验查表用参数/*CRC 高位字节值表*/static u8 auchCRCHi=0 x00,0 xC1,0 x81,0 x40,0 x01,0 xC0,0 x80,0 x41,0 x01,0 xC0,0 x80,0 x41,0 x00,0 xC1,0 x81,0 x40,0 x01,0 xC0,0 x80,0 x41,0 x00,0 xC1,0 x81,0 x40,0 x00,0 xC1,0 x81,0 x40,0 x01,0 xC0,0 x80,0 x41,0 x01,0 xC0,0 x80,0 x41,0
8、x00,0 xC1,0 x81,0 x40,0 x00,0 xC1,0 x81,0 x40,0 x01,0 xC0,0 x80,0 x41,0 x00,0 xC1,0 x81,0 x40,0 x01,0 xC0,0 x80,0 x41,0 x01,0 xC0,0 x80,0 x41,0 x00,0 xC1,0 x81,0 x40,0 x01,0 xC0,0 x80,0 x41,0 x00,0 xC1,0 x81,0 x40,0 x00,0 xC1,0 x81,0 x40,0 x01,0 xC0,0 x80,0 x41,0 x00,0 xC1,0 x81,0 x40,0 x01,0 xC0,0
9、x80,0 x41,0 x01,0 xC0,0 x80,0 x41,0 x00,0 xC1,0 x81,0 x40,0 x00,0 xC1,0 x81,0 x40,0 x01,0 xC0,0 x80,0 x41,0 x01,0 xC0,0 x80,0 x41,0 x00,0 xC1,0 x81,0 x40,0 x01,0 xC0,0 x80,0 x41,0 x00,0 xC1,0 x81,0 x40,0 x00,0 xC1,0 x81,0 x40,0 x01,0 xC0,0 x80,0 x41,0 x01,0 xC0,0 x80,0 x41,0 x00,0 xC1,0 x81,0 x40,0
10、x00,0 xC1,0 x81,0 x40,0 x01,0 xC0,0 x80,0 x41,0 x00,0 xC1,0 x81,0 x40,0 x01,0 xC0,0 x80,0 x41,0 x01,0 xC0,0 x80,0 x41,0 x00,0 xC1,0 x81,0 x40,0 x00,0 xC1,0 x81,0 x40,0 x01,0 xC0,0 x80,0 x41,0 x01,0 xC0,0 x80,0 x41,0 x00,0 xC1,0 x81,0 x40,0 x01,0 xC0,0 x80,0 x41,0 x00,0 xC1,0 x81,0 x40,0 x00,0 xC1,0
11、x81,0 x40,0 x01,0 xC0,0 x80,0 x41,0 x00,0 xC1,0 x81,0 x40,0 x01,0 xC0,0 x80,0 x41,0 x01,0 xC0,0 x80,0 x41,0 x00,0 xC1,0 x81,0 x40,0 x01,0 xC0,0 x80,0 x41,0 x00,0 xC1,0 x81,0 x40,0 x00,0 xC1,0 x81,0 x40,0 x01,0 xC0,0 x80,0 x41,0 x01,0 xC0,0 x80,0 x41,0 x00,0 xC1,0 x81,0 x40,0 x00,0 xC1,0 x81,0 x40,0
12、x01,0 xC0,0 x80,0 x41,0 x00,0 xC1,0 x81,0 x40,0 x01,0 xC0,0 x80,0 x41,0 x01,0 xC0,0 x80,0 x41,0 x00,0 xC1,0 x81,0 x40 ;/*CRC 低位字节值表*/static u8 auchCRCLo=0 x00,0 xC0,0 xC1,0 x01,0 xC3,0 x03,0 x02,0 xC2,0 xC6,0 x06,0 x07,0 xC7,0 x05,0 xC5,0 xC4,0 x04,0 xCC,0 x0C,0 x0D,0 xCD,0 x0F,0 xCF,0 xCE,0 x0E,0 x
13、0A,0 xCA,0 xCB,0 x0B,0 xC9,0 x09,0 x08,0 xC8,0 xD8,0 x18,0 x19,0 xD9,0 x1B,0 xDB,0 xDA,0 x1A,0 x1E,0 xDE,0 xDF,0 x1F,0 xDD,0 x1D,0 x1C,0 xDC,0 x14,0 xD4,0 xD5,0 x15,0 xD7,0 x17,0 x16,0 xD6,0 xD2,0 x12,0 x13,0 xD3,0 x11,0 xD1,0 xD0,0 x10,0 xF0,0 x30,0 x31,0 xF1,0 x33,0 xF3,0 xF2,0 x32,0 x36,0 xF6,0 x
14、F7,0 x37,0 xF5,0 x35,0 x34,0 xF4,0 x3C,0 xFC,0 xFD,0 x3D,0 xFF,0 x3F,0 x3E,0 xFE,0 xFA,0 x3A,0 x3B,0 xFB,0 x39,0 xF9,0 xF8,0 x38,0 x28,0 xE8,0 xE9,0 x29,0 xEB,0 x2B,0 x2A,0 xEA,0 xEE,0 x2E,0 x2F,0 xEF,0 x2D,0 xED,0 xEC,0 x2C,0 xE4,0 x24,0 x25,0 xE5,0 x27,0 xE7,0 xE6,0 x26,0 x22,0 xE2,0 xE3,0 x23,0 x
15、E1,0 x21,0 x20,0 xE0,0 xA0,0 x60,0 x61,0 xA1,0 x63,0 xA3,0 xA2,0 x62,0 x66,0 xA6,0 xA7,0 x67,0 xA5,0 x65,0 x64,0 xA4,0 x6C,0 xAC,0 xAD,0 x6D,0 xAF,0 x6F,0 x6E,0 xAE,0 xAA,0 x6A,0 x6B,0 xAB,0 x69,0 xA9,0 xA8,0 x68,0 x78,0 xB8,0 xB9,0 x79,0 xBB,0 x7B,0 x7A,0 xBA,0 xBE,0 x7E,0 x7F,0 xBF,0 x7D,0 xBD,0 x
16、BC,0 x7C,0 xB4,0 x74,0 x75,0 xB5,0 x77,0 xB7,0 xB6,0 x76,0 x72,0 xB2,0 xB3,0 x73,0 xB1,0 x71,0 x70,0 xB0,0 x50,0 x90,0 x91,0 x51,0 x93,0 x53,0 x52,0 x92,0 x96,0 x56,0 x57,0 x97,0 x55,0 x95,0 x94,0 x54,0 x9C,0 x5C,0 x5D,0 x9D,0 x5F,0 x9F,0 x9E,0 x5E,0 x5A,0 x9A,0 x9B,0 x5B,0 x99,0 x59,0 x58,0 x98,0 x
17、88,0 x48,0 x49,0 x89,0 x4B,0 x8B,0 x8A,0 x4A,0 x4E,0 x8E,0 x8F,0 x4F,0 x8D,0 x4D,0 x4C,0 x8C,0 x44,0 x84,0 x85,0 x45,0 x87,0 x47,0 x46,0 x86,0 x82,0 x42,0 x43,0 x83,0 x41,0 x81,0 x80,0 x40 ;/声明 modbus 的函数 void ModInit(u8 Id);/用于 Modbus 初始化,参数 Id 为站号(1-255)void ModRcv(void);/用于 modbus 信息接收 void ModSe
18、nd(void);/用于 modbus 信息接收 void MessageHandle(u8*pointer_in,u8*pointer_out);/处理收到的信息帧 void ReadOutputBit(u8*pointer_1,u8*pointer_2);/读线圈 void ReadInputBit(u8*pointer_1,u8*pointer_2);/读输入位 void ReadHoldingReg(u8*pointer_1,u8*pointer_2);/读保持寄存器 void ReadInputReg(u8*pointer_1,u8*pointer_2);/读输入寄存器 void F
19、orceSingleCoil(u8*pointer_1,u8*pointer_2);/强制单个线圈 void PresetSingleReg(u8*pointer_1,u8*pointer_2);/预制单个寄存器 void ForceMulCoil(u8*pointer_1,u8*pointer_2);/强制多个线圈 void PresetMulReg(u8*pointer_1,u8*pointer_2);/预制多个寄存器 void ErrorHandle(u8 Mode,u8*Pointer);/错误信息帧处理 u16 CRC16(u8*puchMsgg,u8 usDataLen);/用于计
20、算 CRC 校验码 /*函数功能:用于 Modbus 初始化 函数输入:Id 为 Modbus 站号。函数输出:无。*/void ModInit(u8 Id)/modbus 参数初始化 PointToRcvBuf=Rcv_Buffer;PointToSendBuf=Send_Buffer;Send_Num=1;/发送的数据顺序(输出数组的第几个数)Mod_Id=Id;/站号设置 Rcv_Buffer1=Mod_Id;Send_Buffer1=Mod_Id;Comu_Busy=0;/*函数功能:用于 Modbus 信息接收 函数输入:无。函数输出:无。*/void ModRcv(void)Hav
21、eMes=1;/表示接收到了信息 Rcv_Data=USART_ReceiveData(USART1);if(Comu_Busy!=1)/如果不忙,可以接收下一帧信息 TIM_Cmd(TIM2,DISABLE);TIM_SetCounter(TIM2,0);if(Tim_Out!=0)&(Rcv_Data=Mod_Id)/如果间隔时间超过了 3.5 个字符,同时接受的字节和自己的站号一致,则认为接收开始 Rcv_Complete=0;/表示数据帧接收开始 Rcv_Num=0;/接收数据个数初始化 Rcv_Num+;/同时个数加一 if(0=Tim_Out)&(0=Rcv_Complete)/如
22、果处于接收一帧的正常过程中 if(Rcv_Num(*PointToSendBuf)/发送已经完成 Comu_Busy=0;*PointToSendBuf=0;Rcv_Num=0;Send_Num=1;/启动数据发送 USART_ITConfig(USART1,USART_IT_TC,DISABLE);/关闭数据发送中断 /*函数功能:Modbus 专用定时器(TIM2)函数输入:无。函数输出:无。*/void TIM2_IRQHandler(void)if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET)/检查指定的 TIM 中断发生与否:TIM 中断源
23、TIM_ClearITPendingBit(TIM2,TIM_IT_Update );/清除 TIMx 的中断待处理位:TIM 中断源 Tim_Out=1;TIM_Cmd(TIM2,DISABLE);TIM_SetCounter(TIM2,0);Rcv_Complete=1;Rcv_Buffer0=Rcv_Num;if(HaveMes!=0&Rcv_Num4)Comu_Busy=1;MessageHandle(PointToRcvBuf,PointToSendBuf);/*函数功能:CRC 校验用函数 函数输入:puchMsgg 是要进行 CRC 校验的消息,usDataLen 是消息中字节数
24、 函数输出:计算出来的CRC校验码。*/u16 CRC16(u8*puchMsgg,u8 usDataLen)/puchMsgg 是要进行 CRC 校验的消息,usDataLen 是消息中字节数 u8 uchCRCHi=0 xFF;/*高 CRC 字节初始化*/u8 uchCRCLo=0 xFF;/*低 CRC 字节初始化*/u8 uIndex;/*CRC 循环中的索引*/while(usDataLen-)/*传输消息缓冲区*/uIndex=uchCRCHi *puchMsgg+;/*计算 CRC*/uchCRCHi=uchCRCLo auchCRCHiuIndex;uchCRCLo=auch
25、CRCLouIndex;return(uchCRCHi 8)|uchCRCLo);/*函数功能:对输入的信息帧进行处理,按照功能码不同,调用不同的函数处理 函数输入:两个指针,pointer_1 指向用来存放输入信息帧的数组,pointer_2 用来指向存放输出信息帧的数组(两个数组的第一个元素都用来存放信息帧的有效字节个数)后面的元素按照 Modbus 协议组织。函数输出:无。*/void MessageHandle(u8*pointer_in,u8*pointer_out)u16 CalKey;/计算出来的校验值 u16 RcvKey;/接收到的校验值 HaveMes=0;/清除信息位 /
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- stm32 库函数 编写 modbus 源代码
限制150内