micro_climate/frt_protocol.c

385 lines
10 KiB
C
Raw Permalink 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 "frt_protocol.h"
#include "cmsis_os.h"
#include "assertions.h"
#include "inflash.h"
#include "anemometer_dev.h"
#include "sht30.h"
extern u_int8_t rs485_out_buff[50];
/* 静态函数申明 */
static void send_uart_pack(device_handle device,FRT_MsgFunctionCode_e cmd_type, const void *data, u_int16_t len);
static void FRT_MsgProc_ReadRegister(device_handle device, void *pMsg);
static u_int16_t FRT_ReadReg(unsigned char regId);
static u_int16_t FRT_ReadRegMinWindDiretion(void *pMsg);
static u_int16_t FRT_ReadRegAverageWindDirection(void *pMsg);
static u_int16_t FRT_ReadRegMaxWindDirection(void *pMsg);
static u_int16_t FRT_ReadRegMinWindSpeed(void *pMsg);
static u_int16_t FRT_ReadRegAverageWindSpeed(void *pMsg);
static u_int16_t FRT_ReadRegMaxWindSpeed(void *pMsg);
static u_int16_t FRT_ReadRegTemperature(void *pMsg);
static u_int16_t FRT_ReadRegHumidity(void *pMsg);
static u_int16_t FRT_ReadRegPressure(void *pMsg);
static u_int16_t FRT_ReadRegRain(void *pMsg);
static u_int16_t FRT_ReadRegPrecipitationIntensity(void *pMsg);
static u_int16_t FRT_ReadRegDeviceAddr(void *pMsg);
static void pdebug_mcs_info();
/* 功能码处理表 */
FRT_FuncionMsgProcTable_s g_MsgTbl[] =
{
{ FRT_FUNCTION_CODE_READ_REGISTER, FRT_MsgProc_ReadRegister },
// { FRT_FUNCTION_CODE_WRITE_REGISTER, FRT_MsgProc_WriteRegister },
};
/* 寄存器处理表 */
FRT_RegProcTable_s g_RegTbl[] =
{
{ FRT_REGISTER_MIN_WIND_DIRECTION, FRT_ReadRegMinWindDiretion },
{ FRT_REGISTER_AVERAGE_WIND_DIRECTION, FRT_ReadRegAverageWindDirection },
{ FRT_REGISTER_MAX_WIND_DIRECTION, FRT_ReadRegMaxWindDirection },
{ FRT_REGISTER_MIN_WIND_SPEED, FRT_ReadRegMinWindSpeed },
{ FRT_REGISTER_AVERAGE_WIND_SPEED, FRT_ReadRegAverageWindSpeed },
{ FRT_REGISTER_MAX_WIND_SPEED, FRT_ReadRegMaxWindSpeed },
{ FRT_REGISTER_TEMPERATURE, FRT_ReadRegTemperature },
{ FRT_REGISTER_HUMIDITY, FRT_ReadRegHumidity },
{ FRT_REGISTER_PRESSURE, FRT_ReadRegPressure },
{ FRT_REGISTER_RAIN, FRT_ReadRegRain },
{ FRT_REGISTER_PRECIPITATION_INTENSITY, FRT_ReadRegPrecipitationIntensity },
{ FRT_REGISTER_DEVICE_ADDR, FRT_ReadRegDeviceAddr },
// { FRT_REGISTER_COMMU_BAUDRATE, FRT_ReadRegCommuBaudRate },
// { FRT_REGISTER_SPEED_AVERAGE_TIME, FRT_ReadRegSpeedAverageTime },
// { FRT_REGISTER_TEMPHUM_UPDATE_TIME, FRT_ReadRegTempHumUpdateTime },
// { FRT_REGISTER_RAIN_POWER_CONTROL, FRT_ReadRegRainPowerCtl },
};
/**
* @brief modbus crc16算法
* @param
* @retval
*/
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
*/
static u_int16_t FRT_ReadRegMinWindDiretion(void *pMsg)
{
u_int16_t value = (u_int16_t)g_stMcs_Para.min_wind_direction *10;
return value;
}
/**
* @brief 读平均风向寄存器值
* @param
* @retval
*/
static u_int16_t FRT_ReadRegAverageWindDirection(void *pMsg)
{
u_int16_t value = (u_int16_t)g_stMcs_Para.average_wind_direction *10;
return value;
}
/**
* @brief 读最大风向寄存器值
* @param
* @retval
*/
static u_int16_t FRT_ReadRegMaxWindDirection(void *pMsg)
{
u_int16_t value=(u_int16_t)g_stMcs_Para.max_wind_direction *10;
return value;
}
/**
* @brief 读最小风速寄存器值
* @param
* @retval
*/
static u_int16_t FRT_ReadRegMinWindSpeed(void *pMsg)
{
u_int16_t value=(u_int16_t)g_stMcs_Para.min_wind_speed *10;
return value;
}
/**
* @brief 读平均风速寄存器值
* @param
* @retval
*/
static u_int16_t FRT_ReadRegAverageWindSpeed(void *pMsg)
{
u_int16_t value=(u_int16_t)g_stMcs_Para.average_wind_speed *10;
return value;
}
/**
* @brief 读最大风速寄存器值
* @param
* @retval
*/
static u_int16_t FRT_ReadRegMaxWindSpeed(void *pMsg)
{
u_int16_t value=(u_int16_t)g_stMcs_Para.max_wind_speed *10;
return value;
}
/**
* @brief 读温度寄存器值
* @param
* @retval
*/
static u_int16_t FRT_ReadRegTemperature(void *pMsg)
{
u_int16_t value= (u_int16_t)g_stMcs_Para.temperature*10;
return value;
}
/**
* @brief 读湿度寄存器值
* @param
* @retval
*/
static u_int16_t FRT_ReadRegHumidity(void *pMsg)
{
u_int16_t value=(u_int16_t)g_stMcs_Para.humidity*10;
return value;
}
/**
* @brief 读气压寄存器值
* @param
* @retval
*/
static u_int16_t FRT_ReadRegPressure(void *pMsg)
{
u_int16_t value=8;
return value;
}
/**
* @brief 读雨量寄存器值
* @param
* @retval
*/
static u_int16_t FRT_ReadRegRain(void *pMsg)
{
u_int16_t value=9;
return value;
}
/**
* @brief 读光辐射强度寄存器值
* @param
* @retval
*/
static u_int16_t FRT_ReadRegPrecipitationIntensity(void *pMsg)
{
u_int16_t value=10;
return value;
}
/**
* @brief 读设备地址寄存器值
* @param
* @retval
*/
static u_int16_t FRT_ReadRegDeviceAddr(void *pMsg)
{
u_int16_t value=g_stConfigInfo.addr;
return value;
}
/**
* @brief 封装协议发送
* @param
* @retval 数据正确返回TRUE数据异常返回FALSE
*/
static void send_uart_pack(device_handle device,FRT_MsgFunctionCode_e cmd_type, const void *data, u_int16_t len)
{
memset(rs485_out_buff,0,sizeof(rs485_out_buff));
frt_climate_pack_resp *pack = (frt_climate_pack_resp*)rs485_out_buff;
pack->addr = g_stConfigInfo.addr;
pack->func = FRT_FUNCTION_CODE_READ_REGISTER;
pack->data_len = len;
memcpy(pack->data, data, len);
*(u_int16_t*)&pack->data[len] = CRC16((u_int8_t *)&pack->addr,pack->data_len+3);
uart_dev_write(device,(u_int8_t*)pack,pack->data_len+5);
}
/**
* @brief 遍历处理寄存器
* @param
* @retval
*/
u_int16_t FRT_ReadReg(unsigned char regId)
{
for(u_int16_t i = 0; i < sizeof(g_RegTbl) / sizeof(FRT_RegProcTable_s); i++){
//term_printf("regId:%d, g_RegTbl.regId :%d\r\n",regId,g_RegTbl[i].regId);
if (regId == g_RegTbl[i].regId){
return g_RegTbl[i].pRegProc(NULL);
}
}
return 0;
}
/**
* @brief 处理读取寄存器数据
* @param
* @retval
*/
void FRT_MsgProc_ReadRegister(device_handle device, void *pMsg)
{
static u_int8_t reg_value_buff[2*100]={0x00};
memset(reg_value_buff,0,sizeof(reg_value_buff));
frt_climate_pack *pack = (frt_climate_pack*)pMsg;
u_int16_t start_reg_addr = (pack->addr_begin_high_byte<<8)| pack->addr_begin_low_byte;
u_int16_t reg_num= (pack->regnum_begin_high_byte<<8)| pack->regnum_begin_low_byte;
AssertError(start_reg_addr < 100,return, "读取寄存器起始地址错误%d",start_reg_addr);
AssertError(reg_num < 100,return, "读取寄存器数量错误%d",reg_num);
/* 采集sht30数据 */
AssertError(get_temp_humi_data(&g_stMcs_Para.temperature, &g_stMcs_Para.humidity),g_stMcs_Para.temperature=0;g_stMcs_Para.humidity=0,"采集sht30温湿度数据失败" );
/* 调试信息 */
pdebug_mcs_info();
for(u_int16_t pos=0; pos <reg_num; pos++){
*(u_int16_t*)&reg_value_buff[pos*2] = FRT_ReadReg((start_reg_addr+pos));
}
send_uart_pack(device, FRT_FUNCTION_CODE_READ_REGISTER, (u_int8_t*)&reg_value_buff, reg_num*2);
}
/**
* @brief 读取串口数据
* @param
* @retval
*/
static int uart_read_frt_climate_pack(device_handle uart_handle,u_int8_t *buff, u_int32_t buff_size)
{
u_int32_t offset = 0;
char c = 0;
frt_climate_pack *pack = (frt_climate_pack *)buff;
buff_size--; //预留一个'\0'位置
for (offset = 0; offset < buff_size;){
c = uart_dev_in_char(uart_handle);
buff[offset++] = c;
if (offset == sizeof(pack->addr)){
if (pack->addr != g_stConfigInfo.addr){
memcpy(buff, buff+1, offset-1);
offset--;
buff_size--;
}
}else if (offset == FRT_CLIMATE_PACK_SIZE(pack)){
return offset;
}
}
return 0;
}
/**
* @brief 处理一条消息
* @param
* @retval
*/
void FRT_MsgHandler(device_handle device, u_int8_t *pMsg, u_int32_t MsgLen)
{
frt_climate_pack *pack = (frt_climate_pack*)pMsg;
//AssertErrorNoPrint((CRC16(pMsg, MsgLen-2) == FRT_CLIMATE_PACK_CRC16(pHeader)),return);
AssertError((CRC16(pMsg, MsgLen-2) == FRT_CLIMATE_PACK_CRC16(pack)),return,"crc16校验失败");
AssertError((pack->func == FRT_FUNCTION_CODE_READ_REGISTER) ||\
(pack->func == FRT_FUNCTION_CODE_WRITE_REGISTER),return,"crc16校验失败");
for (u_int16_t i = 0; i < sizeof(g_MsgTbl) / sizeof(FRT_FuncionMsgProcTable_s); i++){
if (pack->func == g_MsgTbl[i].msgId){
g_MsgTbl[i].pMsgProc(device, pMsg);
}
}
}
/**
* @brief 读取并解析串口数据
* @param
* @retval
*/
static u_int8_t rs485_buff[50]={0x00};
void read_and_process_uart_data(device_handle device)
{
if(uart_dev_char_present(device)){
osDelay(20);
memset(rs485_buff,0,sizeof(rs485_buff));
int ret = uart_read_frt_climate_pack(device, rs485_buff, sizeof(rs485_buff));
if(ret > 0){
FRT_MsgHandler(device, rs485_buff, ret);
}
}
}
/* 打印微气象数据 */
static void pdebug_mcs_info()
{
term_printf("min_wind_direction: %.2f\r\n", g_stMcs_Para.min_wind_direction);
term_printf("average_wind_direction: %.2f\r\n", g_stMcs_Para.average_wind_direction);
term_printf("max_wind_direction: %.2f\r\n", g_stMcs_Para.max_wind_direction);
term_printf("min_wind_speed: %.2f\r\n", g_stMcs_Para.min_wind_speed);
term_printf("average_wind_speed: %.2f\r\n", g_stMcs_Para.average_wind_speed);
term_printf("max_wind_speed: %.2f\r\n", g_stMcs_Para.max_wind_speed);
term_printf("temperature: %.2f\r\n", g_stMcs_Para.temperature);
term_printf("humidity: %.2f\r\n", g_stMcs_Para.humidity);
term_printf("precipitation: %.2f\r\n", g_stMcs_Para.precipitation);
term_printf("precipitation_intensity: %.2f\r\n", g_stMcs_Para.precipitation_intensity);
}
// 30 03 00 00 00 0B 00 2C