Files
SM-1000M/RTX5_20220316/Driver/sdi12/sdi12.c
2026-04-23 10:50:18 +08:00

731 lines
23 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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();//启动测量
}