feat: 添加modbbus
修改内容:整个protocol文件 影响范围:485通讯 测试结果:简易测试ok,可回复指定内容 修改时间:250806 修改人员:DCY
This commit is contained in:
parent
eb0c71de03
commit
decc3ad725
|
@ -0,0 +1,20 @@
|
|||
/* USER CODE END Header */
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __PROTOCOL_H__
|
||||
#define __PROTOCOL_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
#include "receive_data.h"
|
||||
|
||||
void read_and_process_485_data(uart_device_info *device);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __PROTOCOL_H__ */
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/* USER CODE END Header */
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __RECEIVEDATA_H__
|
||||
#define __RECEIVEDATA_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
#include "ring_queue.h"
|
||||
|
||||
typedef struct _uart_device_info{
|
||||
uint8_t init; //该设备是否初始化准备接收数据标志
|
||||
RingQueue uart_ring_queue; //用于维护设备的接收缓存的循环队列
|
||||
}uart_device_info;
|
||||
|
||||
uart_device_info* get_handle_485(void);//获取485操作句柄
|
||||
//串口设备缓冲区是否有数据
|
||||
int uart_dev_char_present(uart_device_info device);
|
||||
//串口设备从缓冲区读入一个数据
|
||||
char rs485_dev_in_char(uart_device_info *device);
|
||||
|
||||
void IRQHandler_485_process(uint8_t c);
|
||||
void init_ring_queue(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __RECEIVEDATA_H__ */
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef _RING_QUEUE_H_
|
||||
#define _RING_QUEUE_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "main.h"
|
||||
|
||||
#define RQ_OK 1
|
||||
#define RQ_ERROR 0
|
||||
#define RQ_OVERFLOW -2
|
||||
typedef uint8_t RQ_ElementType;//元素类型
|
||||
|
||||
typedef struct _ring_queue
|
||||
{
|
||||
RQ_ElementType *elems;
|
||||
int size;
|
||||
volatile int front, rear;
|
||||
}RingQueue;
|
||||
|
||||
//初始化队列,需传入保存队列状态的结构q,队列使用的buffer和buffer大小
|
||||
int InitRingQueue(RingQueue *q, RQ_ElementType *buff, int size);
|
||||
|
||||
#define RingQueueFull(q) (((q)->rear+1) % (q)->size == (q)->front)
|
||||
#define RingQueueEmpty(q) ((q)->front == (q)->rear)
|
||||
|
||||
//遍历队列,
|
||||
//消费者使用,故对生产者可能修改的rear先读取缓存
|
||||
int ShowRingQueue(RingQueue *q);
|
||||
|
||||
//向队尾插入元素e
|
||||
int InRingQueue(RingQueue *q,RQ_ElementType e);
|
||||
|
||||
//从队首删除元素
|
||||
int OutRingQueue(RingQueue *q, RQ_ElementType *e);
|
||||
|
||||
//队列中的元素个数
|
||||
int RingQueueLength(RingQueue *q);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,98 @@
|
|||
#include "protocol.h"
|
||||
#include "string.h"
|
||||
#include "receive_data.h"
|
||||
#include "usart.h"
|
||||
|
||||
#define CLIMATE_BUFF_CRC16(x) ((x[8 - 2]) | (x[8 - 1] << 8))
|
||||
|
||||
uint8_t rs485_pack_buff[30] = {0};
|
||||
|
||||
uint16_t tmp_tmp = 60000;
|
||||
|
||||
static uint8_t uart_read_climate_pack(uart_device_info *device, uint8_t buffsize)
|
||||
{
|
||||
uint8_t offset = 0;
|
||||
uint8_t c = 0;
|
||||
buffsize--; //预留一个'\0'位置
|
||||
|
||||
for(uint8_t offset = 0; offset < buffsize ;)
|
||||
{
|
||||
//逐字节读取
|
||||
c = rs485_dev_in_char(device);
|
||||
rs485_pack_buff[offset++] = c;
|
||||
if(rs485_pack_buff[0] != 0x30)
|
||||
{
|
||||
memcpy(rs485_pack_buff, rs485_pack_buff + 1, offset - 1);
|
||||
offset--;
|
||||
buffsize--;
|
||||
}
|
||||
}
|
||||
for(uint8_t i = 0; i < buffsize ;)
|
||||
{
|
||||
if(rs485_pack_buff[1] != 0x03 || rs485_pack_buff[0] != 0x30)
|
||||
{
|
||||
memcpy(rs485_pack_buff, rs485_pack_buff + 1, buffsize - i);
|
||||
offset--;
|
||||
buffsize--;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint16_t 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;
|
||||
}
|
||||
|
||||
uint8_t MsgHandler(uart_device_info *device)
|
||||
{
|
||||
if(CRC16(rs485_pack_buff, 6) != CLIMATE_BUFF_CRC16(rs485_pack_buff))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if(rs485_pack_buff[2] == 0x00 && rs485_pack_buff[3] == 0x00 &&rs485_pack_buff[4] == 0x00 &&rs485_pack_buff[5] == 0x01)
|
||||
{
|
||||
uint8_t ret_buf[] = {0x30, 0x03, 0x02, 0x00, 0x00, 0x45, 0x45};
|
||||
ret_buf[3] = (tmp_tmp >> 8)&0x00FF;
|
||||
ret_buf[4] = tmp_tmp & 0x00FF;
|
||||
uint16_t ret_crc = CRC16(ret_buf, 5);
|
||||
ret_buf[5] = ret_crc & 0x00FF;
|
||||
ret_buf[6] = (ret_crc >> 8)&0x00FF;
|
||||
HAL_UART_Transmit_IT(&huart3, ret_buf, 7);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t rs485_wait_t = 0;
|
||||
void read_and_process_485_data(uart_device_info *device)
|
||||
{
|
||||
//进入两次再解析
|
||||
if(uart_dev_char_present(*device))
|
||||
{
|
||||
rs485_wait_t++;
|
||||
if(rs485_wait_t > 1)
|
||||
{
|
||||
rs485_wait_t = 0;
|
||||
memset(rs485_pack_buff,0,sizeof(rs485_pack_buff));
|
||||
|
||||
int ret = uart_read_climate_pack(device, sizeof(rs485_pack_buff));
|
||||
if(ret > 0)
|
||||
{
|
||||
MsgHandler(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
#include "receive_data.h"
|
||||
#include "ring_queue.h"
|
||||
|
||||
uint8_t uart_485_rx_buff[20] = {0};
|
||||
|
||||
static uart_device_info device_485;
|
||||
//返回设备操作句柄
|
||||
uart_device_info* get_handle_485(void)
|
||||
{
|
||||
return &device_485;
|
||||
}
|
||||
|
||||
void init_ring_queue(void)
|
||||
{
|
||||
InitRingQueue(&device_485.uart_ring_queue, uart_485_rx_buff, sizeof(uart_485_rx_buff)); //初始化环形队列缓存
|
||||
device_485.init = 1;//初始化标志
|
||||
}
|
||||
|
||||
|
||||
void IRQHandler_485_process(uint8_t c)
|
||||
{
|
||||
uart_device_info *dev = get_handle_485();
|
||||
if(!RingQueueFull(&dev->uart_ring_queue))
|
||||
{
|
||||
InRingQueue(&dev->uart_ring_queue, c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//串口设备缓冲区是否有数据
|
||||
int uart_dev_char_present(uart_device_info device)
|
||||
{
|
||||
if(!device.init)
|
||||
return 0;
|
||||
return !RingQueueEmpty(&device.uart_ring_queue);
|
||||
}
|
||||
|
||||
//串口设备从缓冲区读入一个数据
|
||||
char rs485_dev_in_char(uart_device_info *device)
|
||||
{
|
||||
char c = 0;
|
||||
if (uart_dev_char_present(*device)) //等待环形队列缓存区有数据
|
||||
OutRingQueue(&device->uart_ring_queue, (uint8_t*)&c);
|
||||
return c;
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
|
||||
//循环队列
|
||||
#include "ring_queue.h"
|
||||
|
||||
|
||||
//初始化队列
|
||||
int InitRingQueue(RingQueue *q, RQ_ElementType *buff, int size)
|
||||
{
|
||||
q->elems = buff;
|
||||
q->size = size;
|
||||
q->front=q->rear=0;
|
||||
return RQ_OK;
|
||||
}
|
||||
|
||||
//遍历队列,
|
||||
//消费者使用,故对生产者可能修改的rear先读取缓存
|
||||
int ShowRingQueue(RingQueue *q)
|
||||
{
|
||||
int rear = q->rear;
|
||||
|
||||
if(q->front == rear)
|
||||
{
|
||||
return RQ_ERROR;
|
||||
}
|
||||
|
||||
return RQ_OK;
|
||||
}
|
||||
|
||||
//向队尾插入元素e
|
||||
int InRingQueue(RingQueue *q,RQ_ElementType e)
|
||||
{
|
||||
if(RingQueueFull(q))
|
||||
{
|
||||
return(RQ_OVERFLOW);
|
||||
}
|
||||
q->elems[q->rear] = e;
|
||||
q->rear = (q->rear+1) % q->size;
|
||||
return RQ_OK;
|
||||
}
|
||||
|
||||
//从队首取回并删除元素
|
||||
int OutRingQueue(RingQueue *q, RQ_ElementType *e)
|
||||
{
|
||||
if(RingQueueEmpty(q))
|
||||
{
|
||||
return RQ_ERROR;
|
||||
}
|
||||
*e = q->elems[q->front];
|
||||
q->front = (q->front+1) % q->size;
|
||||
return RQ_OK;
|
||||
}
|
||||
|
||||
//队列中的元素个数
|
||||
int RingQueueLength(RingQueue *q)
|
||||
{
|
||||
return ((q->rear - q->front) + q->size) % q->size;
|
||||
}
|
||||
|
|
@ -43,6 +43,7 @@ void MX_TIM7_Init(void);
|
|||
/* USER CODE BEGIN Prototypes */
|
||||
void tim7_clock_update(void);
|
||||
|
||||
extern uint8_t g_tim7_100ms_flag;
|
||||
extern uint8_t g_tim7_200ms_flag;
|
||||
extern uint8_t g_tim7_500ms_flag;
|
||||
extern uint8_t g_tim7_1000ms_flag;
|
||||
|
|
|
@ -41,7 +41,7 @@ extern UART_HandleTypeDef huart3;
|
|||
void MX_USART3_UART_Init(void);
|
||||
|
||||
/* USER CODE BEGIN Prototypes */
|
||||
|
||||
extern uint8_t rx_uart3_buf[1];
|
||||
/* USER CODE END Prototypes */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "heat.h"
|
||||
#include "ring_queue.h"
|
||||
#include "receive_data.h"
|
||||
#include "protocol.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
|
@ -93,14 +96,25 @@ int main(void)
|
|||
/* USER CODE BEGIN 2 */
|
||||
//<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD>رռ<D8B1><D5BC><EFBFBD>
|
||||
stop_heat();
|
||||
init_ring_queue();
|
||||
uart_device_info *device_485 = get_handle_485();//485设备
|
||||
|
||||
HAL_TIM_Base_Start_IT(&htim7);
|
||||
HAL_UART_Receive_IT(&huart3, rx_uart3_buf, 1);
|
||||
/* USER CODE END 2 */
|
||||
|
||||
/* Infinite loop */
|
||||
/* USER CODE BEGIN WHILE */
|
||||
while (1)
|
||||
{
|
||||
// 100ms<6D><73><EFBFBD><EFBFBD>
|
||||
if(g_tim7_100ms_flag)
|
||||
{
|
||||
g_tim7_100ms_flag = 0;
|
||||
|
||||
//处理485数据
|
||||
read_and_process_485_data(device_485);
|
||||
}
|
||||
// 200ms<6D><73><EFBFBD><EFBFBD>
|
||||
if(g_tim7_200ms_flag)
|
||||
{
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
/* USER CODE BEGIN Includes */
|
||||
#include "tim.h"
|
||||
#include "usart.h"
|
||||
#include "receive_data.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
|
@ -210,7 +211,10 @@ void USART3_IRQHandler(void)
|
|||
/* USER CODE END USART3_IRQn 0 */
|
||||
HAL_UART_IRQHandler(&huart3);
|
||||
/* USER CODE BEGIN USART3_IRQn 1 */
|
||||
uint8_t c = rx_uart3_buf[0];
|
||||
IRQHandler_485_process(c);
|
||||
|
||||
HAL_UART_Receive_IT(&huart3, rx_uart3_buf, 1);
|
||||
/* USER CODE END USART3_IRQn 1 */
|
||||
}
|
||||
|
||||
|
|
|
@ -100,20 +100,28 @@ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
|
|||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
static uint8_t tim7_clock_100ms = 0;
|
||||
static uint8_t tim7_clock_200ms = 0;
|
||||
static uint8_t tim7_clock_500ms = 0;
|
||||
static uint8_t tim7_clock_1000ms = 0;
|
||||
|
||||
uint8_t g_tim7_100ms_flag = 0;
|
||||
uint8_t g_tim7_200ms_flag = 0;
|
||||
uint8_t g_tim7_500ms_flag = 0;
|
||||
uint8_t g_tim7_1000ms_flag = 0;
|
||||
// 10ms+1
|
||||
void tim7_clock_update(void)
|
||||
{
|
||||
tim7_clock_100ms++;
|
||||
tim7_clock_200ms++;
|
||||
tim7_clock_500ms++;
|
||||
tim7_clock_1000ms++;
|
||||
|
||||
if(tim7_clock_100ms >= 10)
|
||||
{
|
||||
g_tim7_100ms_flag = 1;
|
||||
tim7_clock_100ms = 0;
|
||||
}
|
||||
if(tim7_clock_200ms >= 20)
|
||||
{
|
||||
g_tim7_200ms_flag = 1;
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "usart.h"
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
uint8_t rx_uart3_buf[1] = {0};
|
||||
/* USER CODE END 0 */
|
||||
|
||||
UART_HandleTypeDef huart3;
|
||||
|
@ -66,7 +66,6 @@ void MX_USART3_UART_Init(void)
|
|||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN USART3_Init 2 */
|
||||
|
||||
/* USER CODE END USART3_Init 2 */
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
# 温度读取协议
|
||||
|
||||
> 采样MODBUS协议类似微气象
|
||||
|
||||
## 读取帧
|
||||
|
||||
|地址码 |功能码 |起始地址(高字节在前) |寄存器数量(高字节在前) |CRC检验位(低字节在前) |
|
||||
|---|---|---|---|---|
|
||||
|1 Byte |1 Byte |2 Bytes |2 Bytes |2 Bytes |
|
||||
|30 |03 |0000 |0001 |802B |
|
||||
|
||||
## 读取应答帧
|
||||
|
||||
|地址码 |功能码 |字节数 |寄存器数据(高位在前) |CRC校验位(低字节在前) |
|
||||
|---|---|---|---|---|
|
||||
|1 Byte |1 Byte |1 Byte |2 \* N Byte |2 Bytes |
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1431,6 +1431,15 @@
|
|||
<file>
|
||||
<name>$PROJ_DIR$\..\APP\src\heat.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\APP\src\protocol.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\APP\src\receive_data.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\APP\src\ring_queue.c</name>
|
||||
</file>
|
||||
</group>
|
||||
<group>
|
||||
<name>Application</name>
|
||||
|
@ -1459,6 +1468,9 @@
|
|||
<file>
|
||||
<name>$PROJ_DIR$\..\Core\Src\tim.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\Core\Src\usart.c</name>
|
||||
</file>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
|
@ -1517,6 +1529,12 @@
|
|||
<file>
|
||||
<name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_tim_ex.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_uart.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\Drivers\STM32G4xx_HAL_Driver\Src\stm32g4xx_hal_uart_ex.c</name>
|
||||
</file>
|
||||
</group>
|
||||
</group>
|
||||
</project>
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -3,17 +3,17 @@
|
|||
<StLinkDriver>
|
||||
<stlinkserialNo>0669FF3434584D3043103844</stlinkserialNo>
|
||||
<stlinkfoundProbes />
|
||||
<stlinkResetStyle>0</stlinkResetStyle>
|
||||
<stlinkResetStrategy>2</stlinkResetStrategy>
|
||||
<LeaveTargetRunning>_ 0</LeaveTargetRunning>
|
||||
<CStepIntDis>_ 0</CStepIntDis>
|
||||
<stlinkResetStyle>0</stlinkResetStyle>
|
||||
<stlinkResetStrategy>2</stlinkResetStrategy>
|
||||
</StLinkDriver>
|
||||
<PlDriver>
|
||||
<FirstRun>0</FirstRun>
|
||||
<MemConfigValue>D:\Program Files\IAR Systems\arm\config\debugger\ST\STM32G431RB.ddf</MemConfigValue>
|
||||
</PlDriver>
|
||||
<DebugChecksum>
|
||||
<Checksum>622187173</Checksum>
|
||||
<Checksum>4077576522</Checksum>
|
||||
</DebugChecksum>
|
||||
<Exceptions>
|
||||
<StopOnUncaught>_ 0</StopOnUncaught>
|
||||
|
@ -69,8 +69,8 @@
|
|||
<ITMlogFile>$PROJ_DIR$\ITM.log</ITMlogFile>
|
||||
</SWOTraceHWSettings>
|
||||
<ArmDriver>
|
||||
<EnforceMemoryConfiguration>1</EnforceMemoryConfiguration>
|
||||
<EnableCache>0</EnableCache>
|
||||
<EnforceMemoryConfiguration>1</EnforceMemoryConfiguration>
|
||||
</ArmDriver>
|
||||
<Trace2>
|
||||
<Enabled>0</Enabled>
|
||||
|
@ -117,6 +117,20 @@
|
|||
<ShowTimeSum>1</ShowTimeSum>
|
||||
<SumSortOrder>0</SumSortOrder>
|
||||
</EventLog>
|
||||
<DisassembleMode>
|
||||
<mode>0</mode>
|
||||
</DisassembleMode>
|
||||
<Breakpoints2>
|
||||
<Count>0</Count>
|
||||
</Breakpoints2>
|
||||
<TermIOLog>
|
||||
<LoggingEnabled>_ 0</LoggingEnabled>
|
||||
<LogFile>_ ""</LogFile>
|
||||
</TermIOLog>
|
||||
<Aliases>
|
||||
<Count>0</Count>
|
||||
<SuppressDialog>0</SuppressDialog>
|
||||
</Aliases>
|
||||
<DriverProfiling>
|
||||
<Enabled>0</Enabled>
|
||||
<Mode>3</Mode>
|
||||
|
@ -124,18 +138,4 @@
|
|||
<Symbiont>0</Symbiont>
|
||||
<Exclusions />
|
||||
</DriverProfiling>
|
||||
<TermIOLog>
|
||||
<LoggingEnabled>_ 0</LoggingEnabled>
|
||||
<LogFile>_ ""</LogFile>
|
||||
</TermIOLog>
|
||||
<DisassembleMode>
|
||||
<mode>0</mode>
|
||||
</DisassembleMode>
|
||||
<Breakpoints2>
|
||||
<Count>0</Count>
|
||||
</Breakpoints2>
|
||||
<Aliases>
|
||||
<Count>0</Count>
|
||||
<SuppressDialog>0</SuppressDialog>
|
||||
</Aliases>
|
||||
</settings>
|
||||
|
|
Loading…
Reference in New Issue