#include "sdi12.h" #include "bsp.h" u8 test = 0; Sdi_Fram_Record_Struct Sdi_Fram_Record_Structs; /***********************/ //函数名称: Diable_Usart3_TX(void) //功能复位串口:PB10作为普通IO口使用 //输入参数: 无 void Diable_Usart1_SDI(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_DeInit(USART1); //复位串口1 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); //GPIOB时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_ResetBits(GPIOB,GPIO_Pin_6); //GPIO_SetBits(GPIOB,GPIO_Pin_7); } void sdi12_Power_init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE); //GPIOC时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOC,&GPIO_InitStructure); GPIO_ResetBits(GPIOC,GPIO_Pin_1); GPIO_ResetBits(GPIOC,GPIO_Pin_2); GPIO_ResetBits(GPIOC,GPIO_Pin_3); } /***********************/ //函数名称: sdi12_power_on() //功能 :打开模块电源 //输入参数:ch--(1--6) static void sdi12_power_on( uint8_t ch) { switch(ch) { case 1: GPIO_ResetBits(GPIOC,GPIO_Pin_3); GPIO_ResetBits(GPIOC,GPIO_Pin_2); GPIO_ResetBits(GPIOC,GPIO_Pin_1); break; case 2: GPIO_ResetBits(GPIOC,GPIO_Pin_3); GPIO_ResetBits(GPIOC,GPIO_Pin_2); GPIO_SetBits(GPIOC,GPIO_Pin_1); break; case 3: GPIO_ResetBits(GPIOC,GPIO_Pin_3); GPIO_SetBits(GPIOC,GPIO_Pin_2); GPIO_ResetBits(GPIOC,GPIO_Pin_1); break; case 4: GPIO_ResetBits(GPIOC,GPIO_Pin_3); GPIO_SetBits(GPIOC,GPIO_Pin_2); GPIO_SetBits(GPIOC,GPIO_Pin_1); break; case 5: GPIO_SetBits(GPIOC,GPIO_Pin_3); GPIO_ResetBits(GPIOC,GPIO_Pin_2); GPIO_ResetBits(GPIOC,GPIO_Pin_1); break; case 6: GPIO_SetBits(GPIOC,GPIO_Pin_3); GPIO_ResetBits(GPIOC,GPIO_Pin_2); GPIO_SetBits(GPIOC,GPIO_Pin_1); break; default: GPIO_SetBits(GPIOC,GPIO_Pin_3); GPIO_SetBits(GPIOC,GPIO_Pin_2); GPIO_SetBits(GPIOC,GPIO_Pin_1); break; } } /***********************/ //函数名称: Enable_Usart3_TX(void) //功能 :初始化串口3 //输入参数: baund,串口波特率 void Enable_Usart1_SDI(void) { USART1_SDI_Configuration(1200); } /***********************/ //函数名称: Break_Sdi_Sensor(void) //功能 :发送break命令 //输入参数: 无 void Break_Sdi_Sensor(void) { Enable_SdiTX; GPIO_ResetBits(GPIOB,GPIO_Pin_6);//出现俩? delay_ms(20); GPIO_SetBits(GPIOB,GPIO_Pin_6); } void Sdi_StartMeasure(void) { u8 i=0; char temp_sdi[5]={'\0'}; USART1_SDI_CLR_RXBuf(); for(i=1;i<7;i++) { delay_ms(500); memset(temp_sdi,0,5); sprintf(temp_sdi,"%d%s",0,"M!"); Diable_Usart1_SDI(); Break_Sdi_Sensor();// 发送空号和传号 Enable_Usart1_SDI(); u1_printf("%s",temp_sdi); delay_ms(10); Enable_SdiRX; delay_ms(600); USART1_SDI_CLR_RXBuf();//读取数据部分代码 memset(temp_sdi,0,5); sprintf(temp_sdi,"%d%s",0,"D0!"); USART1_SDI_CLR_RXBuf(); Diable_Usart1_SDI(); Break_Sdi_Sensor();// 发送空号和传号 Enable_Usart1_SDI(); u1_printf("%s",temp_sdi); delay_ms(10); Enable_SdiRX; delay_ms(600); Sdi_Par(i); } /* Diable_Usart1_SDI(); Break_Sdi_Sensor();// 发送空号和传号 Enable_Usart1_SDI(); u1_printf("0M!"); delay_ms(8); Enable_SdiRX; 可正常发送 */ } char Sdi_readaddress(void) { char *str; osMutexAcquire(SDI_MutexID,osWaitForever); sdi12_power_on(1); USART_RS232_DEinit(); Enable_SDI_RS232=0; Diable_Usart1_SDI(); USART1_SDI_CLR_RXBuf(); Break_Sdi_Sensor();// 发送空号和传号 Enable_Usart1_SDI(); u1_printf("%s","?!"); delay_ms(8); Enable_SdiRX; delay_ms(500); osMutexRelease(SDI_MutexID); if((str=strstr(USART1_SDI_RX_BUF,"\r\n")) !=NULL) { str--; return str[0]; } return 0x7f; } void Sdi_chanegadd(char a,char b) { char tempadd_sdi[10]={'\0'}; sdi12_power_on(1); //a=3; //b=0; //osMutexAcquire(SDI_MutexID,osWaitForever); //sprintf(tempadd_sdi,"%c%c%c%c",a,'A',b,'!'); sprintf(tempadd_sdi,"%s","3A0!"); USART_RS232_DEinit(); Enable_SDI_RS232=0; Diable_Usart1_SDI(); USART1_SDI_CLR_RXBuf(); Break_Sdi_Sensor();// 发送空号和传号 Enable_Usart1_SDI(); u1_printf("%s",tempadd_sdi); delay_ms(8); Enable_SdiRX; delay_ms(500); //osMutexRelease(SDI_MutexID); } //单个传感器测量,判断是否有数据返回 u8 Sdi_Readone(char add) { char temp_sdi[5]={'\0'}; char *subStringP; char *subStringN; USART1_SDI_CLR_RXBuf(); memset(temp_sdi,0,5); sprintf(temp_sdi,"%c%s",add,"D0!"); USART1_SDI_CLR_RXBuf(); Diable_Usart1_SDI(); Break_Sdi_Sensor();// 发送空号和传号 Enable_Usart1_SDI(); u1_printf("%s",temp_sdi); delay_ms(8); Enable_SdiRX; delay_ms(500); subStringP=strstr(USART1_SDI_RX_BUF,"+"); subStringN=strstr(USART1_SDI_RX_BUF,"-"); if((subStringP!=NULL)|(subStringN!=NULL)) return 0; else return 1; } //多个传感器测量 //void Sdi_Read(void) //{ // u8 i=0; // char temp_sdi[5]={'\0'}; // // for(i=1;i<7;i++) // { // USART1_SDI_CLR_RXBuf(); // memset(temp_sdi,0,5); // sprintf(temp_sdi,"%d%s",i,"D0!"); // USART1_SDI_CLR_RXBuf(); // Diable_Usart1_SDI(); // Break_Sdi_Sensor();// 发送空号和传号 // Enable_Usart1_SDI(); // u1_printf("%s",temp_sdi); // delay_ms(8); // Enable_SdiRX; // delay_ms(500); // Sdi_Par(0); // } //} ////多个传感器测量 //void Sdi_Read(void) //{ // u8 i=0; // char temp_sdi[5]={'\0'}; // // for(i=1;i<10;i++) // { // USART1_SDI_CLR_RXBuf(); // memset(temp_sdi,0,5); // sprintf(temp_sdi,"%d%s",i,"D0!"); // USART1_SDI_CLR_RXBuf(); // Diable_Usart1_SDI(); // Break_Sdi_Sensor();// 发送空号和传号 // Enable_Usart1_SDI(); // u1_printf("%s",temp_sdi); // delay_ms(8); // Enable_SdiRX; // delay_ms(500); // Sdi_Par(i); // // } //} uint16_t usMBCRC16( unsigned char * pucFrame, uint16_t usLen ) { static const uint16_t aucCRCHi[] = { 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, 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, 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, 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 }; static const uint16_t aucCRCLo[] = { 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40 }; uint16_t ucCRCHi = 0xFF; uint16_t ucCRCLo = 0xFF; int iIndex; while( usLen-- ) { iIndex = ucCRCLo ^ *( pucFrame++ ); ucCRCLo = ( uint16_t )( ucCRCHi ^ aucCRCHi[iIndex] ); ucCRCHi = aucCRCLo[iIndex]; } return ( uint16_t )( ucCRCHi << 8 | ucCRCLo ); } float hex_to_flota(char data[]) { float *p = (float*)data; return *p; } //解析SDI数据 void Sdi_Par(u8 add) { char *subStringP; char *subStringN; char *subString; char *subStringNext; char pos1_data[10],pos2_data[10],pos3_data[10],Temp[3] = {'\0'}; uint16_t CRC_DATA= 0; float SDI_T = 0,SDI_H = 0,SDI_P =0; int16_t inttofloat = 0; Sdi_Fram_Record_Structs.Flag_finish_DATA=0; CRC_DATA = usMBCRC16(Usart5_Fram_Record_Structs .Usart5_RX_BUF,9); if(((CRC_DATA&0x00ff) == Usart5_Fram_Record_Structs .Usart5_RX_BUF[9]) && (((CRC_DATA >> 8)&0x00ff) == Usart5_Fram_Record_Structs .Usart5_RX_BUF[10])) { memset(pos1_data,0,10); memset(pos2_data,0,10); memset(pos3_data,0,10); /***********判断三个参数的±*************/ inttofloat = Usart5_Fram_Record_Structs .Usart5_RX_BUF[3]; inttofloat = (inttofloat << 8) + Usart5_Fram_Record_Structs .Usart5_RX_BUF[4]; SDI_T = inttofloat*1.0/10; // inttofloat = SDI_T*100; // if((inttofloat % 10) == 0) // { // SDI_T = SDI_T + 0.01; // } sprintf(pos3_data,"%.1f",SDI_T); inttofloat = Usart5_Fram_Record_Structs .Usart5_RX_BUF[5]; inttofloat = (inttofloat << 8) + Usart5_Fram_Record_Structs .Usart5_RX_BUF[6]; SDI_H = inttofloat*1.0/10; // inttofloat = SDI_H*100; // if((inttofloat % 10) == 9) // { // SDI_H = SDI_H + 0.01; // } sprintf(pos1_data,"%.1f",SDI_H); inttofloat = Usart5_Fram_Record_Structs .Usart5_RX_BUF[7]; inttofloat = (inttofloat << 8) + Usart5_Fram_Record_Structs .Usart5_RX_BUF[8]; SDI_P = inttofloat; sprintf(pos2_data,"%.0f",SDI_P); switch (add) { case 1: sprintf(Sdi_Fram_Record_Structs.Ch1_RX_BUF, "%s,%s,%s", pos3_data,pos1_data,pos2_data);break; //获取传感器0数据 case 2: sprintf(Sdi_Fram_Record_Structs.Ch2_RX_BUF, "%s,%s,%s", pos3_data,pos1_data,pos2_data);break;//获取传感器1数据 case 3: sprintf(Sdi_Fram_Record_Structs.Ch3_RX_BUF, "%s,%s,%s", pos3_data,pos1_data,pos2_data);break; //获取传感器2数据 case 4: sprintf(Sdi_Fram_Record_Structs.Ch4_RX_BUF, "%s,%s,%s", pos3_data,pos1_data,pos2_data);break; //获取传感器3数据 case 5: sprintf(Sdi_Fram_Record_Structs.Ch5_RX_BUF, "%s,%s,%s", pos3_data,pos1_data,pos2_data);break; //获取传感器4数据 case 6: sprintf(Sdi_Fram_Record_Structs.Ch6_RX_BUF, "%s,%s,%s", pos3_data,pos1_data,pos2_data);break; //获取传感器5数据 // case 7: sprintf(Sdi_Fram_Record_Structs.Ch7_RX_BUF, "%s,%s,%s", pos1_data,pos2_data,pos3_data);break; //获取传感器6数据 // case 8: sprintf(Sdi_Fram_Record_Structs.Ch8_RX_BUF, "%s,%s,%s", pos1_data,pos2_data,pos3_data);break; //获取传感器7数据 // case 9: sprintf(Sdi_Fram_Record_Structs.Ch9_RX_BUF, "%s,%s,%s", pos1_data,pos2_data,pos3_data);break; //获取传感器8数据 default:break; } Sdi_Fram_Record_Structs.Flag_finish_DATA=1; } else { switch (add) { case 1: sprintf(Sdi_Fram_Record_Structs.Ch1_RX_BUF, "Na,Na,Na" );break; //获取传感器0数据 case 2: sprintf(Sdi_Fram_Record_Structs.Ch2_RX_BUF, "Na,Na,Na");break;//获取传感器1数据 case 3: sprintf(Sdi_Fram_Record_Structs.Ch3_RX_BUF, "Na,Na,Na");break; //获取传感器2数据 case 4: sprintf(Sdi_Fram_Record_Structs.Ch4_RX_BUF, "Na,Na,Na");break; //获取传感器3数据 case 5: sprintf(Sdi_Fram_Record_Structs.Ch5_RX_BUF, "Na,Na,Na");break; //获取传感器4数据 case 6: sprintf(Sdi_Fram_Record_Structs.Ch6_RX_BUF, "Na,Na,Na");break; //获取传感器5数据 // case 7: sprintf(Sdi_Fram_Record_Structs.Ch7_RX_BUF, "Na,Na,Na");break; //获取传感器6数据 // case 8: sprintf(Sdi_Fram_Record_Structs.Ch8_RX_BUF, "Na,Na,Na");break; //获取传感器7数据 // case 9: sprintf(Sdi_Fram_Record_Structs.Ch9_RX_BUF, "Na,Na,Na");break; //获取传感器8数据 default:break; } } } void sdi12_buf_clear(void) { memset(Sdi_Fram_Record_Structs.Ch1_RX_BUF,0,sizeof(Sdi_Fram_Record_Structs.Ch1_RX_BUF)); memset(Sdi_Fram_Record_Structs.Ch2_RX_BUF,0,sizeof(Sdi_Fram_Record_Structs.Ch2_RX_BUF)); memset(Sdi_Fram_Record_Structs.Ch3_RX_BUF,0,sizeof(Sdi_Fram_Record_Structs.Ch3_RX_BUF)); memset(Sdi_Fram_Record_Structs.Ch4_RX_BUF,0,sizeof(Sdi_Fram_Record_Structs.Ch4_RX_BUF)); memset(Sdi_Fram_Record_Structs.Ch5_RX_BUF,0,sizeof(Sdi_Fram_Record_Structs.Ch5_RX_BUF)); memset(Sdi_Fram_Record_Structs.Ch6_RX_BUF,0,sizeof(Sdi_Fram_Record_Structs.Ch6_RX_BUF)); // memset(Sdi_Fram_Record_Structs.Ch7_RX_BUF,0,sizeof(Sdi_Fram_Record_Structs.Ch7_RX_BUF)); // memset(Sdi_Fram_Record_Structs.Ch8_RX_BUF,0,sizeof(Sdi_Fram_Record_Structs.Ch8_RX_BUF)); // memset(Sdi_Fram_Record_Structs.Ch9_RX_BUF,0,sizeof(Sdi_Fram_Record_Structs.Ch9_RX_BUF)); memset(Sdi_Fram_Record_Structs.QXZ_RX_BUF,0,sizeof(Sdi_Fram_Record_Structs.QXZ_RX_BUF)); } void ChangeRs485Addr( char addr) { unsigned char i= 0,NUM = 0, CMD[10] = {'\0'}; uint16_t CRC_Data; memset(Usart5_Fram_Record_Structs .Usart5_RX_BUF,0,sizeof(Usart5_Fram_Record_Structs .Usart5_RX_BUF)); RS485_TX_EN; delay_ms(10); CMD[i++] = 0xfe; CMD[i++] = 0x06; CMD[i++] = 0x00; CMD[i++] = 0x30; CMD[i++] = 0x00; CMD[i++] = 0x02; CRC_Data = usMBCRC16(CMD,6); CMD[i++] = CRC_Data&0x00ff; CMD[i++] = (CRC_Data>>8)&0x00ff; for(NUM = 0; NUM < 8; NUM++) { while(USART_GetFlagStatus(UART5,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕 USART_SendData(UART5,CMD[NUM]); } delay_ms(10); RS485_RX_EN; delay_ms(1000); RS485_TX_EN; delay_ms(10); i = 0; CMD[i++] = Usart5_Fram_Record_Structs .Usart5_RX_BUF[0]; CMD[i++] = 0x06; CMD[i++] = 0x00; CMD[i++] = 0x30; CMD[i++] = 0x00; CMD[i++] = addr; CRC_Data = usMBCRC16(CMD,6); CMD[i++] = CRC_Data&0x00ff; CMD[i++] = (CRC_Data>>8)&0x00ff; for(NUM = 0; NUM < 8; NUM++) { while(USART_GetFlagStatus(UART5,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕 USART_SendData(UART5,CMD[NUM]); } delay_ms(10); RS485_RX_EN; delay_ms(1000); __nop(); } void Get_Sdi_Data(uint8_t Addr_485) { uint16_t CRC_Data; unsigned char i= 0,NUM = 0, CMD[10] = {'\0'}; Usart5_Fram_Record_Structs .InfBit .FramLength = 0; memset(Usart5_Fram_Record_Structs .Usart5_RX_BUF,0,sizeof(Usart5_Fram_Record_Structs .Usart5_RX_BUF)); RS485_TX_EN; delay_ms(10); CMD[i++] = Addr_485; CMD[i++] = 0x03; CMD[i++] = 0x00; CMD[i++] = 0x00; CMD[i++] = 0x00; CMD[i++] = 0x03; CRC_Data = usMBCRC16(CMD,6); CMD[i++] = CRC_Data&0x00ff; CMD[i++] = (CRC_Data>>8)&0x00ff; for(NUM = 0; NUM < 8; NUM++) { while(USART_GetFlagStatus(UART5,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕 USART_SendData(UART5,CMD[NUM]); } delay_ms(10); RS485_RX_EN; delay_ms(1000); __nop(); } // 定义 MODBUS 相关常量 #define MODBUS_SLAVE_ADDR 0x01 // 从机地址 #define MODBUS_FUNC_CODE 0x04 // 功能码(读取输入寄存器) #define MODBUS_START_ADDR 0x0000 // 起始地址 #define MODBUS_NUM_REGISTERS 0x0E // 寄存器数量 // CRC16 计算函数 uint16_t MODBUS_CRC16(uint8_t *data, uint16_t len) { uint16_t crc = 0xFFFF; for (uint16_t i = 0; i < len; i++) { crc ^= data[i]; for (uint8_t j = 0; j < 8; j++) { if (crc & 0x0001) { crc >>= 1; crc ^= 0xA001; } else { crc >>= 1; } } } return crc; } // 发送 MODBUS 读取请求 void MODBUS_SendReadRequest(uint8_t slaveAddr, uint16_t startAddr, uint16_t numRegisters) { uint16_t CRC_Data; //uint8_t request[8]; unsigned char i = 0, NUM = 0, request[10] = {'\0'}; Usart5_Fram_Record_Structs .InfBit .FramLength = 0; memset(Usart5_Fram_Record_Structs .Usart5_RX_BUF,0,sizeof(Usart5_Fram_Record_Structs .Usart5_RX_BUF)); // 切换到发送模式 RS485_TX_EN; // 控制收发引脚为发送模式 delay_ms(10); // 等待稳定 request[i++] = slaveAddr; // 从机地址 request[i++] = MODBUS_FUNC_CODE; // 功能码(读取输入寄存器) request[i++] = (startAddr >> 8) & 0xFF; // 起始地址高字节 request[i++] = startAddr & 0xFF; // 起始地址低字节 request[i++] = (numRegisters >> 8) & 0xFF; // 寄存器数量高字节 request[i++] = numRegisters & 0xFF; // 寄存器数量低字节 // 计算 CRC CRC_Data = MODBUS_CRC16(request, 6); request[i++] = CRC_Data & 0x00FF; // CRC 低字节 request[i++] = (CRC_Data >> 8) & 0x00FF; // CRC 高字节 // // 打印发送的数据 // u5_printf("Sending MODBUS request: "); // for (uint8_t i = 0; i < 8; i++) { // u5_printf("%02X ", request[i]); // } // 发送请求 for (NUM = 0; NUM < 8; NUM++) { while (USART_GetFlagStatus(UART5, USART_FLAG_TC) == RESET); // 等待发送完成 USART_SendData(UART5, request[NUM]); } while (USART_GetFlagStatus(UART5, USART_FLAG_TC) == RESET); //u5_printf("\n"); // 切换回接收模式 //delay_ms(10); RS485_RX_EN; //delay_ms(1000); __nop(); } // 解析 MODBUS 响应 int MODBUS_ParseResponse(uint8_t *response, uint16_t len, SensorData *output) { // // // // 打印原始响应数据 // u5_printf("Response Data: "); // for (uint16_t i = 0; i < len; i++) { // u5_printf("%02X ", response[i]); // } // u5_printf("\n"); // 检查起始标志位 if (response[0] != MODBUS_SLAVE_ADDR) { // 从机地址为 0x01 return -4; } // 校验 CRC uint16_t crc = MODBUS_CRC16(response, len - 2); if ((response[len - 2] != (crc & 0xFF)) || (response[len - 1] != ((crc >> 8) & 0xFF))) { //u5_printf("CRC Error: Expected %04X, Got %02X%02X\n", crc, response[len - 1], response[len - 2]); return -1; } // 检查功能码 if (response[1] != MODBUS_FUNC_CODE) { return -2; } // 获取数据长度 uint8_t dataLen = response[2]; if (dataLen % 4 != 0) { return -3; } // 将字节数据转换为浮点数 for (uint8_t i = 0; i < dataLen; i += 4) { uint32_t temp = ((uint32_t)response[3 + i] << 24) | ((uint32_t)response[4 + i] << 16) | ((uint32_t)response[5 + i] << 8) | (uint32_t)response[6 + i]; float value = *((float *)&temp); // 分段打印 int integerPart = (int)value; int decimalPart = (int)((value - integerPart) * 1000); // 保留 3 位小数 // 整数和小数分别存储到结构体 output[i / 4].integerPart = integerPart; output[i / 4].decimalPart = decimalPart; //u5_printf("Integer: %d, Decimal: %03d\n", integerPart, decimalPart); } return 0; // 解析成功 } // 获取 MODBUS 传感器数据 void Get_MODBUS_SensorData(void) { uint8_t response[256]; uint16_t len = 0; SensorData sensorData[7]; // 传感器返回 7 个数据(温度、湿度、压力、风速、风向、雨量、光照) // 发送 MODBUS 读取请求 MODBUS_SendReadRequest(MODBUS_SLAVE_ADDR, MODBUS_START_ADDR, MODBUS_NUM_REGISTERS); // 等待并接收响应 delay_ms(100); len = Usart5_Fram_Record_Structs.InfBit.FramLength; memcpy(response, Usart5_Fram_Record_Structs.Usart5_RX_BUF, len); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 解析响应 int result = MODBUS_ParseResponse(response, len, sensorData); if (result != 0) { // 处理错误 //sprintf(Sdi_Fram_Record_Structs.Ch1_RX_BUF, "Error: Failed to parse sensor data"); sprintf(Sdi_Fram_Record_Structs.QXZ_RX_BUF, "Na,Na,Na,Na,Na,Na,Na"); return; } // 传感器数据存储到 Ch1_RX_BUF // "qxz-Temperature,qxz-Humidity,qxz-AirPressure,qxz-WindSpeed,qxz-WindDirection,qxz-Rainfall,qxz-Illuminance," // sprintf(Sdi_Fram_Record_Structs.QXZ_RX_BUF, "%d.%01d,%d.%01d,%d.%01d,%d.%02d,%d,%d,%d", sensorData[0].integerPart, sensorData[0].decimalPart / 100, // 温度 sensorData[1].integerPart, sensorData[1].decimalPart / 100, // 湿度 sensorData[2].integerPart, sensorData[2].decimalPart / 100, // 气压 sensorData[3].integerPart, sensorData[3].decimalPart / 10, // 风速 sensorData[4].integerPart, // 风向 sensorData[5].integerPart, // 雨量 sensorData[6].integerPart); // 光照 } void sdi12_process(void) { uint8_t ADDR = 1; delay_ms(500); PWR_CTRL485_H; delay_ms(1000); sdi12_buf_clear(); Get_MODBUS_SensorData();// 获取 MODBUS 传感器数据 // ChangeRs485Addr(1); for(ADDR = 1; ADDR < 7; ADDR++) { //if (ADDR == 1) continue;// 跳过气象传感器 Get_Sdi_Data(ADDR); Sdi_Par(ADDR); } PWR_CTRL485_L; delay_ms(1000); //Sdi_StartMeasure();//启动测量 }