关键代码
/* Includes ------------------------------------------------------------------*/
#include "MyApplication.h"
/* Private define-------------------------------------------------------------*/
#define FunctionCode_Read_Register (uint8_t)0x03
#define FunctionCode_Write_Register (uint8_t)0x06
#define Modbus_Order_LENGTH (uint8_t)8
/* Private variables----------------------------------------------------------*/
/* Private function prototypes------------------------------------------------*/
static void Protocol_Analysis(UART_t*); //协议分析
static void Modbus_Read_Register(UART_t*); //读寄存器
static void Modbus_Wrtie_Register(UART_t*); //写寄存器
/* Public variables-----------------------------------------------------------*/
Modbus_t Modbus =
{
1,
Protocol_Analysis
};
/*
* [url=home.php?mod=space&uid=139335]@name[/url] Protocol_Analysis
* [url=home.php?mod=space&uid=247401]@brief[/url] 协议分析
* @param UART -> 串口指针
* @retval None
*/
static void Protocol_Analysis(UART_t* UART)
{
UART_t* const COM = UART;
uint8_t i = 0,Index = 0;
//串口3停止DMA接收
HAL_UART_DMAStop(&huart3);
//过滤干扰数据,首字节为modbus地址,共8字节
for(i=0;i<UART3_Rec_LENGTH;i++)
{
//检测键值起始数据Modbus.Addr
if(Index == 0)
{
if(*(COM->pucRec_Buffer+i) != Modbus.Addr)
continue;
}
*(COM->pucRec_Buffer+Index) = *(COM->pucRec_Buffer+i);
//已读取7个字节
if(Index == Modbus_Order_LENGTH)
break;
Index++;
}
//计算CRC-16
CRC_16.CRC_Value = CRC_16.CRC_Check(COM->pucRec_Buffer,6); //计算CRC值
CRC_16.CRC_H = (uint8_t)(CRC_16.CRC_Value >> 8);
CRC_16.CRC_L = (uint8_t)CRC_16.CRC_Value;
//校验CRC-16
if(((*(COM->pucRec_Buffer+6) == CRC_16.CRC_L) && (*(COM->pucRec_Buffer+7) == CRC_16.CRC_H))
||
((*(COM->pucRec_Buffer+6) == CRC_16.CRC_H) && (*(COM->pucRec_Buffer+7) == CRC_16.CRC_L)))
{
//校验地址
if((*(COM->pucRec_Buffer+0)) == Modbus.Addr)
{
//处理数据
if((*(COM->pucRec_Buffer+1)) == FunctionCode_Read_Register)
{
Modbus_Read_Register(COM);
}
else if((*(COM->pucRec_Buffer+1)) == FunctionCode_Write_Register)
{
Modbus_Wrtie_Register(COM);
}
}
}
//清缓存
for(i=0;i<UART3_Rec_LENGTH;i++)
{
*(COM->pucRec_Buffer+i) = 0x00;
}
}
/*
* @name Modbus_Read_Register
* @brief 读寄存器
* @param UART -> 串口指针
* @retval None
*/
static void Modbus_Read_Register(UART_t* UART)
{
UART_t* const COM = UART;
//校验地址
if((*(COM->pucRec_Buffer+2) == 0x9C) && (*(COM->pucRec_Buffer+3) == 0x41))
{
回应数据
//地址码
*(COM->pucSend_Buffer+0) = Modbus.Addr;
//功能码
*(COM->pucSend_Buffer+1) = FunctionCode_Read_Register;
//数据长度
*(COM->pucSend_Buffer+2) = 8;
//SHT30温度
*(COM->pucSend_Buffer+3) = ((uint16_t)((SHT30.fTemperature+40)*10))/256;
*(COM->pucSend_Buffer+4) = ((uint16_t)((SHT30.fTemperature+40)*10))%256;
//SHT30湿度
*(COM->pucSend_Buffer+5) = 0;
*(COM->pucSend_Buffer+6) = SHT30.ucHumidity;
//继电器状态
*(COM->pucSend_Buffer+7) = 0;
*(COM->pucSend_Buffer+8) = Relay.Status;
//蜂鸣器状态
*(COM->pucSend_Buffer+9) = 0;
*(COM->pucSend_Buffer+10) = Buzzer.Status;
//插入CRC
CRC_16.CRC_Value = CRC_16.CRC_Check(COM->pucSend_Buffer,11); //计算CRC值
CRC_16.CRC_H = (uint8_t)(CRC_16.CRC_Value >> 8);
CRC_16.CRC_L = (uint8_t)CRC_16.CRC_Value;
*(COM->pucSend_Buffer+11) = CRC_16.CRC_L;
*(COM->pucSend_Buffer+12) = CRC_16.CRC_H;
//发送数据
UART3.SendArray(COM->pucSend_Buffer,13);
}
}
/*
* @name Modbus_Read_Register
* @brief 写寄存器
* @param UART -> 串口指针
* @retval None
*/
static void Modbus_Wrtie_Register(UART_t* UART)
{
UART_t* const COM = UART;
uint8_t i;
回应数据
//准备数据
for(i=0;i<8;i++)
{
*(COM->pucSend_Buffer+i) = *(COM->pucRec_Buffer+i);
}
//发送数据
UART3.SendArray(COM->pucSend_Buffer,8);
//提取数据
//校验地址 -> 继电器
if((*(COM->pucRec_Buffer+2) == 0x9C) && (*(COM->pucRec_Buffer+3) == 0x43))
{
//控制继电器
if(*(COM->pucRec_Buffer+5) == 0x01)
{
Relay.Relay_ON();
}
else
{
Relay.Relay_OFF();
}
}
//校验地址 -> 蜂鸣器
if((*(COM->pucRec_Buffer+2) == 0x9C) && (*(COM->pucRec_Buffer+3) == 0x44))
{
//控制蜂鸣器
if(*(COM->pucRec_Buffer+5) == 0x01)
{
Buzzer.ON();
}
else
{
Buzzer.OFF();
}
}
}
/********************************************************
End Of File
********************************************************/
|