《STM32 modbus程序.pdf》由会员分享,可在线阅读,更多相关《STM32 modbus程序.pdf(5页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、modbus.c Page 1/*modbus-rtu 通讯规约通讯方式:rs-485 半双功校验方式:crc16停止位:2位编写:孙可编写日期:2008年6月18日版本:v0.2编程思路:1.串口中断允许自动接收总线上的信息,当接收的 字节后超过3.5个字节时间没有新的字节认为本次 接收完成,接收完成标志置1;如果接收完成标志已 经置1又有数据进来则丢弃新来的数据。2.串口接收数据的处理,当接收完成标志置1进入 接收数据处理,(1)首先判断接收的第一位数据与 本机地址是否相同,如果不相同清空接收缓存不发 送任何信息;(2)接收的第一位数据与本机地址相 同,则对接收缓存中的数据进行crc16校
2、验,如果接 收的校验位与本校验结果不相同清空接收缓存不发 送任何信息;(3)如果crc16校验正确则根据数据串中的命令码进 行相应的处理。*/#include modbus.hu8 Com0_id=0 x05;/本机串口0的通讯地址u8 Uart0_rev_buff100;/com0串口接收缓冲区u8 Uart0_send_buff100;/com0串口发送缓冲区vu8 Uart0_rev_count;vs8 Uart0_send_counter=0;vu8 Uart0_rev_comflag;vu8 Crc_counter=0;/com0校验计数器vu8*Uart0_send_pointer
3、=Uart0_send_buff;/com0串口发送指针vu16 Mkgz_bz=0;/模块故障标志1:输入异常,2:过压,3:欠压,4:过温vu16 Out_current=50;/输出电流vu16 Out_voltage=240;/输出电压vu16 Mkzt_bz=0;/模块状态标志vu16 OutX_current=1000;/输出限流vu16 Jc_voltage=2530;/均充电压vu16 Fc_voltage=2400;/浮充电压vu16 user_day=1825;/使用天数void Delay(vu32 nCount);unsigned short getCRC16(vola
4、tile unsigned char*ptr,unsigned char len);void mov_data(u8 a100,u8 b100,u8 c);void Modbus_Function_3(void);void Modbus_Function_6(void);/*函数名称:crc16校验函数功能:crc16校验函数输入:字节指针*ptr,数据长度len函数返回:双字节crc函数编写:孙可编写日期:2008年6月9日函数版本:v0.2*/unsigned short getCRC16(volatile unsigned char*ptr,unsigned char len)unsig
5、ned char i;unsigned short crc=0 xFFFF;if(len=0)len=1;while(len-)modbus.c Page 2 crc=*ptr;for(i=0;i=1;crc=0 xA001;else crc=1;ptr+;return(crc);/*块数据复制数据函数功能:把数组a的c个数据复制到数组b中输入:指针a,指针b,数据个数c返回:无编写:孙可编写日期:2008年3月28日版本:v0.1*/void mov_data(u8 a100,u8 b100,u8 c)u8 i;for(i=c;i0;i-)ai=bi;/void Modbus_Functio
6、n_3(void)u16 tempdress=0;u8 i=3;u16 crcresult;tempdress=(Uart0_rev_buff2=0 x0120)&(tempdress+Uart0_rev_buff5 8)&0 xff;i+;/后面不放break的目的是继续往下执行 case 0 x0122:Uart0_send_buffi=Out_voltage&0 xff;i+;Uart0_send_buffi=(Out_voltage 8)&0 xff;i+;case 0 x0124:modbus.c Page 3 Uart0_send_buffi=Out_current&0 xff;i
7、+;Uart0_send_buffi=(Out_current 8)&0 xff;i+;case 0 x0126:Uart0_send_buffi=Mkzt_bz&0 xff;i+;Uart0_send_buffi=(Mkzt_bz 8)&0 xff;i+;case 0 x0128:/这个地址是备用的里面的数据没有意义 Uart0_send_buffi=0 x00;i+;Uart0_send_buffi=0 x00;i+;case 0 x012A:Uart0_send_buffi=OutX_current&0 xff;i+;Uart0_send_buffi=(OutX_current 8)&0
8、 xff;i+;case 0 x012C:Uart0_send_buffi=Jc_voltage&0 xff;i+;Uart0_send_buffi=(Jc_voltage 8)&0 xff;i+;case 0 x012E:Uart0_send_buffi=Fc_voltage&0 xff;i+;Uart0_send_buffi=(Fc_voltage 8)&0 xff;i+;case 0 x0130:Uart0_send_buffi=0 x00;i+;Uart0_send_buffi=0 x00;i+;/UCSRB|=(1TXCIE)|(1 8)&0 xff;Uart0_send_count
9、er=Uart0_send_counter+2;Uart0_send_pointer=Uart0_send_buff;USART_SendData(USART1,*Uart0_send_pointer+);USART_ITConfig(USART1,USART_IT_TXE,ENABLE);/void Modbus_Function_6(void)u16 tempdress=0;u8 tx_flat=0;u16 crcresult;tempdress=(Uart0_rev_buff28)+Uart0_rev_buff3;switch(tempdress)case 0 x0126:modbus.
10、c Page 4 Mkzt_bz=(Uart0_rev_buff4 0)tx_flat=1;break;case 0 x012A:OutX_current=(Uart0_rev_buff4 0)tx_flat=1;break;case 0 x012C:Jc_voltage=(Uart0_rev_buff4 0)tx_flat=1;break;case 0 x012E:Fc_voltage=(Uart0_rev_buff4 0)tx_flat=1;break;case 0 x01EE:user_day=(Uart0_rev_buff48)+Uart0_rev_buff5;tx_flat=1;/e
11、eprom_write_word(&user_day_eep,user_day);break;default:/命令码无效不应答 tx_flat=0;if(tx_flat=1)Uart0_send_buff0=Com0_id;Uart0_send_buff1=0 x06;Uart0_send_buff2=Uart0_rev_buff2;Uart0_send_buff3=Uart0_rev_buff3;Uart0_send_buff4=Uart0_rev_buff4;Uart0_send_buff5=Uart0_rev_buff5;Uart0_send_counter=6;/UCSRB|=(1T
12、XCIE)|(1 8)&0 xff;Uart0_send_counter=Uart0_send_counter+2;Uart0_send_pointer=Uart0_send_buff;USART_SendData(USART1,*Uart0_send_pointer+);USART_ITConfig(USART1,USART_IT_TXE,ENABLE);/void Com0_Communication(void)s8 i=0;if(Uart0_rev_comflag=1)/接收完成标志=1处理,否则退出 if(Uart0_rev_buff0=Com0_id)/地址错误不应答 modbus.
13、c Page 5 unsigned short crcresult;unsigned char temp2;crcresult=getCRC16(Uart0_rev_buff,Crc_counter-2);temp1=crcresult&0 xff;temp0=(crcresult 8)&0 xff;if(Uart0_rev_buffCrc_counter-1=temp0)&(Uart0_rev_buffCrc_counter-2=temp1)/crc校验错误不应答 /SETBIT(PORTC,PC6);Delay(1);switch(Uart0_rev_buff1)case 0 x03:if
14、(user_day 0)Modbus_Function_3();break;case 0 x06:Modbus_Function_6();break;Uart0_rev_comflag=0;for(i=100;i -1;i-)Uart0_rev_buffi=0;/*Function Name :Delay*Description :Inserts a delay time.*Input :nCount:specifies the delay time length.*Output :None*Return :None*/void Delay(vu32 nCount)for(;nCount!=0;nCount-);/