您好,欢迎访问三七文档
当前位置:首页 > 临时分类 > STM32-modbus程序
modbus.cPage1/*****************************************************modbus-rtu通讯规约通讯方式:rs-485半双功校验方式:crc16停止位:2位编写:孙可编写日期:2008年6月18日版本:v0.2编程思路:1.串口中断允许自动接收总线上的信息,当接收的字节后超过3.5个字节时间没有新的字节认为本次接收完成,接收完成标志置1;如果接收完成标志已经置1又有数据进来则丢弃新来的数据。2.串口接收数据的处理,当接收完成标志置1进入接收数据处理,(1)首先判断接收的第一位数据与本机地址是否相同,如果不相同清空接收缓存不发送任何信息;(2)接收的第一位数据与本机地址相同,则对接收缓存中的数据进行crc16校验,如果接收的校验位与本校验结果不相同清空接收缓存不发送任何信息;(3)如果crc16校验正确则根据数据串中的命令码进行相应的处理。******************************************************/#includemodbus.hu8Com0_id=0x05;//本机串口0的通讯地址u8Uart0_rev_buff[100];//com0串口接收缓冲区u8Uart0_send_buff[100];//com0串口发送缓冲区vu8Uart0_rev_count;vs8Uart0_send_counter=0;vu8Uart0_rev_comflag;vu8Crc_counter=0;//com0校验计数器vu8*Uart0_send_pointer=Uart0_send_buff;//com0串口发送指针vu16Mkgz_bz=0;//模块故障标志1:输入异常,2:过压,3:欠压,4:过温vu16Out_current=50;//输出电流vu16Out_voltage=240;//输出电压vu16Mkzt_bz=0;//模块状态标志vu16OutX_current=1000;//输出限流vu16Jc_voltage=2530;//均充电压vu16Fc_voltage=2400;//浮充电压vu16user_day=1825;//使用天数voidDelay(vu32nCount);unsignedshortgetCRC16(volatileunsignedchar*ptr,unsignedcharlen);voidmov_data(u8a[100],u8b[100],u8c);voidModbus_Function_3(void);voidModbus_Function_6(void);/***************************************函数名称:crc16校验函数功能:crc16校验函数输入:字节指针*ptr,数据长度len函数返回:双字节crc函数编写:孙可编写日期:2008年6月9日函数版本:v0.2****************************************/unsignedshortgetCRC16(volatileunsignedchar*ptr,unsignedcharlen){unsignedchari;unsignedshortcrc=0xFFFF;if(len==0){len=1;}while(len--)modbus.cPage2{crc^=*ptr;for(i=0;i8;i++){if(crc&1){crc=1;crc^=0xA001;}else{crc=1;}}ptr++;}return(crc);}/***************************************块数据复制数据函数功能:把数组a的c个数据复制到数组b中输入:指针a,指针b,数据个数c返回:无编写:孙可编写日期:2008年3月28日版本:v0.1****************************************/voidmov_data(u8a[100],u8b[100],u8c){u8i;for(i=c;i0;i--){a[i]=b[i];}}///////////////////////////////////////////////////////////////////////voidModbus_Function_3(void){u16tempdress=0;u8i=3;u16crcresult;tempdress=(Uart0_rev_buff[2]8)+Uart0_rev_buff[3];if((tempdress=0x0120)&(tempdress+Uart0_rev_buff[5]0x0132)){Uart0_send_buff[0]=Com0_id;Uart0_send_buff[1]=0x03;Uart0_send_buff[2]=2*Uart0_rev_buff[5];Uart0_send_counter=2*Uart0_rev_buff[5]+3;switch(tempdress){case0x0120:{Uart0_send_buff[i]=Mkgz_bz&0xff;i++;Uart0_send_buff[i]=(Mkgz_bz8)&0xff;i++;}//后面不放break的目的是继续往下执行case0x0122:{Uart0_send_buff[i]=Out_voltage&0xff;i++;Uart0_send_buff[i]=(Out_voltage8)&0xff;i++;}case0x0124:{modbus.cPage3Uart0_send_buff[i]=Out_current&0xff;i++;Uart0_send_buff[i]=(Out_current8)&0xff;i++;}case0x0126:{Uart0_send_buff[i]=Mkzt_bz&0xff;i++;Uart0_send_buff[i]=(Mkzt_bz8)&0xff;i++;}case0x0128://这个地址是备用的里面的数据没有意义{Uart0_send_buff[i]=0x00;i++;Uart0_send_buff[i]=0x00;i++;}case0x012A:{Uart0_send_buff[i]=OutX_current&0xff;i++;Uart0_send_buff[i]=(OutX_current8)&0xff;i++;}case0x012C:{Uart0_send_buff[i]=Jc_voltage&0xff;i++;Uart0_send_buff[i]=(Jc_voltage8)&0xff;i++;}case0x012E:{Uart0_send_buff[i]=Fc_voltage&0xff;i++;Uart0_send_buff[i]=(Fc_voltage8)&0xff;i++;}case0x0130:{Uart0_send_buff[i]=0x00;i++;Uart0_send_buff[i]=0x00;i++;}}//UCSRB|=(1TXCIE)|(1TXEN);//发送、发送中断允许crcresult=getCRC16(Uart0_send_buff,Uart0_send_counter);Uart0_send_buff[Uart0_send_counter]=crcresult&0xff;Uart0_send_buff[Uart0_send_counter+1]=(crcresult8)&0xff;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);}}/////////////////////////////////////////////////////////////voidModbus_Function_6(void){u16tempdress=0;u8tx_flat=0;u16crcresult;tempdress=(Uart0_rev_buff[2]8)+Uart0_rev_buff[3];switch(tempdress){case0x0126:{modbus.cPage4Mkzt_bz=(Uart0_rev_buff[4]8)+Uart0_rev_buff[5];if(user_day0){tx_flat=1;}}break;case0x012A:{OutX_current=(Uart0_rev_buff[4]8)+Uart0_rev_buff[5];if(user_day0){tx_flat=1;}}break;case0x012C:{Jc_voltage=(Uart0_rev_buff[4]8)+Uart0_rev_buff[5];if(user_day0){tx_flat=1;}}break;case0x012E:{Fc_voltage=(Uart0_rev_buff[4]8)+Uart0_rev_buff[5];if(user_day0){tx_flat=1;}}break;case0x01EE:{user_day=(Uart0_rev_buff[4]8)+Uart0_rev_buff[5];tx_flat=1;//eeprom_write_word(&user_day_eep,user_day);}break;default://命令码无效不应答{tx_flat=0;}}if(tx_flat==1){Uart0_send_buff[0]=Com0_id;Uart0_send_buff[1]=0x06;Uart0_send_buff[2]=Uart0_rev_buff[2];Uart0_send_buff[3]=Uart0_rev_buff[3];Uart0_send_buff[4]=Uart0_rev_buff[4];Uart0_send_buff[5]=Uart0_rev_buff[5];Uart0_send_counter=6;//UCSRB|=(1TXCIE)|(1TXEN);//发送、发送中断允许crcresult=getCRC16(Uart0_send_buff,Uart0_send_counter);Uart0_send_buff[Uart0_send_counter]=crcresult&0xff;Uart0_send_buff[Uart0_send_counter+1]=(crcresult8)&0xff;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);}}/////////////////////////////////////////////////////////////voidCom0_Communication(void){s8i=0;if(Uart0_rev_comflag==1)//接收完成标志=1处理,否则退出{if(Uart0_rev_buff[0]==Com0_id)//地址错误不应答{modbus.cPage5unsignedshortcrcresult;unsignedchartemp[2];crcresult=getCRC16(Uart0_rev_buff,Crc
本文标题:STM32-modbus程序
链接地址:https://www.777doc.com/doc-4060380 .html