micro_climate/Drivers/RainLight/rain.c

252 lines
6.0 KiB
C

#include "rain.h"
#include "gpio.h"
#include "main.h"
#include "cmsis_os.h"
#include "anemometer_dev.h"
//开电
void rainLightPowerOn(void)
{
HAL_GPIO_WritePin(GPIO_RAIN_PWR_CTRL_GPIO_Port, GPIO_RAIN_PWR_CTRL_Pin, GPIO_PIN_SET);
}
//关电
void rainLightPowerOff(void)
{
HAL_GPIO_WritePin(GPIO_RAIN_PWR_CTRL_GPIO_Port, GPIO_RAIN_PWR_CTRL_Pin, GPIO_PIN_RESET);
}
//获取雨量指令,返回的雨量是十倍,两个字节
void getRainData(void)
{
uint8_t getRainDataCmd[] = {0x01, 0x03, 0x00, 0x03, 0x00, 0x01, 0x74, 0x0A};
uart_dev_write(g_rain_uart_handle, getRainDataCmd, sizeof(getRainDataCmd));
}
//清空雨量指令
void clearRainData(void)
{
uint8_t getRainDataCmd[] = {0x01, 0x06, 0x01, 0x05, 0x00, 0x00, 0x98, 0x37};
uart_dev_write(g_rain_uart_handle, getRainDataCmd, sizeof(getRainDataCmd));
}
//获取光照指令,返回一倍光照,四个字节
void getLightData(void)
{
uint8_t getRainDataCmd[] = {0x01, 0x03, 0x00, 0x05, 0x00, 0x02, 0xD4, 0x0A};
uart_dev_write(g_rain_uart_handle, getRainDataCmd, sizeof(getRainDataCmd));
}
//同时获取光照雨量指令,返回一倍光照,四个字节;十倍雨量两个字节
void getLightRainData(void)
{
uint8_t getRainDataCmd[] = {0x01, 0x03, 0x00, 0x03, 0x00, 0x04, 0xB4, 0x09};
uart_dev_write(g_rain_uart_handle, getRainDataCmd, sizeof(getRainDataCmd));
}
/**
* @brief 读取串口数据
* @param
* @retval
*/
static int read_rain_pack(device_handle uart_handle,u_int8_t *buff, u_int32_t buff_size)
{
u_int32_t offset = 0;
char c = 0;
unsigned char new_buff[50];
buff_size--; //预留一个'\0'位置
for (int offset = 0; offset < buff_size;)
{
// 逐字符读取
c = uart_dev_in_char(uart_handle);
buff[offset++] = c;
// 判断首字符是否是地址,是地址再开始读取,不是则将索引退一步
if(offset == sizeof(unsigned char))
{
if(buff[0] != 0x01)
{
memcpy(buff, buff + 1, offset - 1);
offset--;
buff_size--;
}
}
// 判断功能码对不对,不对缩一位
else if(buff[1] != 0x06 && buff[1] != 0x03)
{
memcpy(buff, buff + 1, offset - 1);
offset--;
buff_size--;
}
// 读雨量
else if (buff[1] == 0x03 && buff[2] == 0x02 && offset == 7)
{
return offset;
}
// 读光照
else if (buff[1] == 0x03 && buff[2] == 0x04 && offset == 9)
{
return offset;
}
// 读光照雨量
else if (buff[1] == 0x03 && buff[2] == 0x08 && offset == 13)
{
return offset;
}
// 清除雨量
else if (buff[1] == 0x06 & offset == 8)
{
return offset;
}
}
return 0;
}
/**
* @brief 处理光照数据
* @param
* @retval
*/
static void processLightData(u_int8_t *pMsg)
{
uint32_t lightVal = pMsg[0]<<24|pMsg[1]<<16|pMsg[2]<<8|pMsg[3];
g_stMcs_Para.lightIntensity = lightVal;
// term_printf("lightVal:%d", lightVal);
}
/**
* @brief 处理雨量数据
* @param
* @retval
*/
static void processRainData(u_int8_t *pMsg)
{
uint32_t rainVal = pMsg[0]<<8|pMsg[1];
g_stMcs_Para.precipitation = rainVal;
// term_printf("lightVal:%d", rainVal);
}
/**
* @brief 处理光照雨量数据
* @param
* @retval
*/
static void processLightRainData(u_int8_t *lightMsg, u_int8_t *rainMsg)
{
uint32_t rainVal = rainMsg[0]<<8|rainMsg[1];
uint32_t lightVal = lightMsg[0]<<24|lightMsg[1]<<16|lightMsg[2]<<8|lightMsg[3];
g_stMcs_Para.precipitation = rainVal;
g_stMcs_Para.lightIntensity = lightVal;
// term_printf("lightVal:%d", rainVal);
}
/**
* @brief 处理雨量清零数据
* @param
* @retval
*/
static void process0RainData(u_int8_t *pMsg)
{
}
/**
* @brief modbus crc16算法
* @param
* @retval
*/
static unsigned short CRC16(unsigned char *arr_buff, unsigned char len)
{
unsigned short crc=0xFFFF;
unsigned char i, j;
for ( j=0; j<len; j++){
crc=crc ^*arr_buff++;
for ( i=0; i<8; i++){
if( ( crc&0x0001) >0){
crc=crc>>1;
crc=crc^ 0xa001;
}else{
crc=crc>>1;
}
}
}
return crc;
}
/**
* @brief 处理一条消息
* @param
* @retval
*/
#define RAIN_BUFF_CRC16(x) ((x[MsgLen - 2]) | (x[MsgLen - 1] << 8))
static void rainMsgHandler(device_handle device, u_int8_t *pMsg, u_int32_t MsgLen)
{
if(CRC16(pMsg, MsgLen-2) != RAIN_BUFF_CRC16(pMsg))
{
// term_printf("CRC不过");
return;
}
if((pMsg[1] != 0x03) && (pMsg[1] != 0x06))
{
// term_printf("功能码不过");
return;
}
uint8_t msgData[4] = {0};
switch(MsgLen)
{
//雨量数据
case 7:
msgData[0] = pMsg[3];
msgData[1] = pMsg[4];
processRainData(msgData);
break;
//清空雨量返回
case 8:
msgData[0] = pMsg[4];
msgData[1] = pMsg[5];
process0RainData(msgData);
break;
//数据光照
case 9:
msgData[0] = pMsg[3];
msgData[1] = pMsg[4];
msgData[2] = pMsg[5];
msgData[3] = pMsg[6];
processLightData(msgData);
break;
//数据光照雨量
case 13:
msgData[0] = pMsg[7];
msgData[1] = pMsg[8];
msgData[2] = pMsg[9];
msgData[3] = pMsg[10];
uint8_t rainMsg[] = {pMsg[3], pMsg[4]};//雨量
processLightRainData(msgData, rainMsg);
break;
default:
break;
}
}
/**
* @brief 读取并解析串口数据
* @param
* @retval
*/
static u_int8_t rs485_buff[20]={0x00};
void readProcessRainData(device_handle device)
{
if(uart_dev_char_present(device))
{
osDelay(20);
memset(rs485_buff,0,sizeof(rs485_buff));
int ret = read_rain_pack(device, rs485_buff, sizeof(rs485_buff));
if(ret > 0)
{
rainMsgHandler(device, rs485_buff, ret);
}
}
}