2024-12-18 09:43:14 +00:00
|
|
|
|
|
|
|
|
|
#include "interruptSend.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define RS485_MAX_PACK_DATA_LEN 60
|
|
|
|
|
|
|
|
|
|
static uint8_t dataLocation1[RS485_MAX_PACK_DATA_LEN];
|
|
|
|
|
static uint8_t dataLocation2[RS485_MAX_PACK_DATA_LEN];
|
|
|
|
|
static uint8_t dataLocation3[RS485_MAX_PACK_DATA_LEN];
|
|
|
|
|
|
|
|
|
|
extern UART_HandleTypeDef huart2;
|
|
|
|
|
extern UART_HandleTypeDef huart3;
|
|
|
|
|
|
|
|
|
|
#define GW485_huart huart2
|
|
|
|
|
#define BAT485_huart huart3
|
|
|
|
|
|
|
|
|
|
/* 指定对齐方式为1字节 */
|
|
|
|
|
#pragma pack(push,1)
|
|
|
|
|
|
|
|
|
|
typedef struct _send_data_info{
|
|
|
|
|
device_handle device;
|
|
|
|
|
BOOL dataState; //储存数据的状态,TRUE:有数据,FALSE:无数据
|
|
|
|
|
uint8_t dataLen; //数据长度
|
|
|
|
|
uint8_t Counter; //已经发送的长度
|
|
|
|
|
uint8_t *data; //储存数据的内容
|
|
|
|
|
}send_data_info;
|
|
|
|
|
|
|
|
|
|
typedef struct _uart_send_info {
|
|
|
|
|
uint8_t insertState; //能否插入指示,大于0代表能插入
|
|
|
|
|
// uint8_t sendStateGw:1; //能否发送指示,1:需要发送,0:不需要发送
|
|
|
|
|
// uint8_t sendStateBat:1; //能否发送指示
|
|
|
|
|
// uint8_t sendOverStateGw:1; //发送完成指示,1:发送完成,0:发送中
|
|
|
|
|
// uint8_t sendOverStateBat:1; //发送完成指示
|
|
|
|
|
// uint8_t GwState:1; //向上通信485总线空闲状态,1:空闲,0:繁忙
|
|
|
|
|
// uint8_t idleStateGw:1; //向上通信空闲状态,1:没数据到来,0:有数据到来
|
|
|
|
|
// uint8_t BatState:1; //向下通信485总线空闲状态
|
|
|
|
|
// uint8_t idleStateBat:1; //向下通信空闲状态
|
|
|
|
|
|
|
|
|
|
BOOL sendStateGw; //能否发送指示,TRUE:需要发送,FALSE:不需要发送
|
|
|
|
|
BOOL sendStateBat; //能否发送指示
|
|
|
|
|
BOOL sendOverStateGw; //发送完成指示,TRUE:发送完成,FALSE:发送中
|
|
|
|
|
BOOL sendOverStateBat; //发送完成指示
|
|
|
|
|
BOOL GwState; //向上通信485总线空闲状态,TRUE:空闲,FALSE:繁忙
|
|
|
|
|
BOOL idleStateGw; //向上通信空闲状态,TRUE:没数据到来,FALSE:有数据到来
|
|
|
|
|
BOOL BatState; //向下通信485总线空闲状态
|
|
|
|
|
BOOL idleStateBat; //向下通信空闲状态
|
|
|
|
|
|
|
|
|
|
send_data_info *insertData; //通过该指针写入数据
|
|
|
|
|
send_data_info *sendDataGw; //通过该指针发送数据
|
|
|
|
|
send_data_info *sendDataBat; //通过该指针发送数据
|
|
|
|
|
send_data_info data1; //储存数据的第1个位置
|
|
|
|
|
send_data_info data2; //储存数据的第2个位置
|
|
|
|
|
send_data_info data3; //储存数据的第3个位置
|
|
|
|
|
}uart_send_info;
|
|
|
|
|
/* 恢复默认的对齐设置 */
|
|
|
|
|
#pragma pack(pop)
|
|
|
|
|
|
|
|
|
|
static uart_send_info uart_send = {0};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief 串口中断发送的初始化,通过空闲中断来判断总线空闲状态
|
|
|
|
|
* @param
|
|
|
|
|
* @retval
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
void send_init(void)
|
|
|
|
|
{
|
|
|
|
|
/* 指定数据储存位置 */
|
|
|
|
|
uart_send.data1.data = dataLocation1;
|
|
|
|
|
uart_send.data2.data = dataLocation2;
|
|
|
|
|
uart_send.data3.data = dataLocation3;
|
|
|
|
|
|
|
|
|
|
/* 初始化插入位置为data1 */
|
|
|
|
|
uart_send.insertData = &uart_send.data1;
|
|
|
|
|
uart_send.sendDataGw = NULL;
|
|
|
|
|
uart_send.sendDataBat = NULL;
|
|
|
|
|
|
|
|
|
|
//有3个位置可以写入数据
|
|
|
|
|
uart_send.insertState = 3;
|
|
|
|
|
|
|
|
|
|
//没有数据能够发送
|
|
|
|
|
uart_send.sendStateGw = FALSE;
|
|
|
|
|
uart_send.sendStateBat = FALSE;
|
|
|
|
|
|
|
|
|
|
//发送完成
|
|
|
|
|
uart_send.sendOverStateBat = TRUE;
|
|
|
|
|
uart_send.sendOverStateGw = TRUE;
|
|
|
|
|
|
|
|
|
|
//485总线空闲
|
|
|
|
|
uart_send.GwState = TRUE;
|
|
|
|
|
uart_send.idleStateGw = TRUE;
|
|
|
|
|
uart_send.BatState = TRUE;
|
|
|
|
|
uart_send.idleStateBat = TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief GW485串口接收到数据后调用该函数,设置485总线空闲状态
|
|
|
|
|
* @param
|
|
|
|
|
* @retval
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
void setIdleStateGw(void)
|
|
|
|
|
{
|
|
|
|
|
if (uart_send.idleStateGw == FALSE) {
|
|
|
|
|
uart_send.idleStateGw = TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief BAT485串口接收到数据后调用该函数,设置485总线空闲状态
|
|
|
|
|
* @param
|
|
|
|
|
* @retval
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
void setIdleStateBat(void)
|
|
|
|
|
{
|
|
|
|
|
if (uart_send.idleStateBat == FALSE) {
|
|
|
|
|
uart_send.idleStateBat = TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief GW485串口设置485总线空闲状态,间隔10ms使用
|
|
|
|
|
* @param
|
|
|
|
|
* @retval
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
void setGwState(void)
|
|
|
|
|
{
|
|
|
|
|
if (uart_send.idleStateGw == FALSE) {
|
|
|
|
|
uart_send.GwState = TRUE;
|
|
|
|
|
} else {
|
|
|
|
|
uart_send.GwState = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uart_send.idleStateGw = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief BAT485串口设置485总线空闲状态,间隔10ms使用
|
|
|
|
|
* @param
|
|
|
|
|
* @retval
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
void setBatState(void)
|
|
|
|
|
{
|
|
|
|
|
if (uart_send.idleStateBat == FALSE) {
|
|
|
|
|
uart_send.BatState = TRUE;
|
|
|
|
|
} else {
|
|
|
|
|
uart_send.BatState = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uart_send.idleStateBat = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief GW485串口发送完成后,调用该函数
|
|
|
|
|
* @param
|
|
|
|
|
* @retval
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
void setSendOverStateGw(void)
|
|
|
|
|
{
|
|
|
|
|
uart_send.sendOverStateGw = TRUE;
|
|
|
|
|
uart_send.sendStateGw = FALSE;
|
|
|
|
|
uart_send.sendDataGw->dataState = FALSE;
|
|
|
|
|
uart_send.sendDataGw = NULL;
|
|
|
|
|
uart_send.insertState++;
|
|
|
|
|
|
|
|
|
|
/* 插入指针指向为空时 */
|
|
|
|
|
if (uart_send.data1.dataState == FALSE) {
|
|
|
|
|
uart_send.insertData = &uart_send.data1;
|
|
|
|
|
}
|
|
|
|
|
else if (uart_send.data2.dataState == FALSE) {
|
|
|
|
|
uart_send.insertData = &uart_send.data2;
|
|
|
|
|
}
|
|
|
|
|
else if (uart_send.data3.dataState == FALSE) {
|
|
|
|
|
uart_send.insertData = &uart_send.data3;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief BAT485串口发送完成后,调用该函数
|
|
|
|
|
* @param
|
|
|
|
|
* @retval
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
void setSendOverStateBat(void)
|
|
|
|
|
{
|
|
|
|
|
uart_send.sendOverStateBat = TRUE;
|
|
|
|
|
uart_send.sendStateBat = FALSE;
|
|
|
|
|
uart_send.sendDataBat->dataState = FALSE;
|
|
|
|
|
uart_send.sendDataBat = NULL;
|
|
|
|
|
uart_send.insertState++;
|
|
|
|
|
|
|
|
|
|
/* 插入指针指向为空时 */
|
|
|
|
|
if (uart_send.data1.dataState == FALSE) {
|
|
|
|
|
uart_send.insertData = &uart_send.data1;
|
|
|
|
|
}
|
|
|
|
|
else if (uart_send.data2.dataState == FALSE) {
|
|
|
|
|
uart_send.insertData = &uart_send.data2;
|
|
|
|
|
}
|
|
|
|
|
else if (uart_send.data3.dataState == FALSE) {
|
|
|
|
|
uart_send.insertData = &uart_send.data3;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief 检测是否有数据需要发送
|
|
|
|
|
* @param
|
|
|
|
|
* @retval
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
void check_sendState(void)
|
|
|
|
|
{
|
|
|
|
|
/* 向上通信总线空闲时,检测到有数据需要发送,同时上一次数据发送完成 */
|
|
|
|
|
if (uart_send.GwState && uart_send.sendStateGw && uart_send.sendOverStateGw) {
|
|
|
|
|
/* 将数据塞入中断发送 */
|
|
|
|
|
HAL_UART_Transmit_IT(&GW485_huart, uart_send.sendDataGw->data, uart_send.sendDataGw->dataLen);
|
|
|
|
|
uart_send.sendOverStateGw = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 向下通信总线空闲时,检测到有数据需要发送,同时上一次数据发送完成 */
|
|
|
|
|
if (uart_send.BatState && uart_send.sendStateBat && uart_send.sendOverStateBat) {
|
|
|
|
|
HAL_UART_Transmit_IT(&BAT485_huart, uart_send.sendDataBat->data, uart_send.sendDataBat->dataLen);
|
|
|
|
|
uart_send.sendOverStateBat = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (uart_send.sendDataGw == NULL) {
|
|
|
|
|
if (uart_send.data1.dataState) {
|
|
|
|
|
if (uart_send.data1.device == g_gw485_uart2_handle) {
|
|
|
|
|
uart_send.sendStateGw = TRUE;
|
|
|
|
|
uart_send.sendDataGw = &uart_send.data1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (uart_send.data2.dataState) {
|
|
|
|
|
if (uart_send.data2.device == g_gw485_uart2_handle) {
|
|
|
|
|
uart_send.sendStateGw= TRUE;
|
|
|
|
|
uart_send.sendDataGw = &uart_send.data2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (uart_send.data3.dataState) {
|
|
|
|
|
if (uart_send.data3.device == g_gw485_uart2_handle) {
|
|
|
|
|
uart_send.sendStateGw = TRUE;
|
|
|
|
|
uart_send.sendDataGw = &uart_send.data3;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (uart_send.sendDataBat == NULL) {
|
|
|
|
|
if (uart_send.data1.dataState) {
|
|
|
|
|
if (uart_send.data1.device == g_bat485_uart3_handle) {
|
|
|
|
|
uart_send.sendStateBat = TRUE;
|
|
|
|
|
uart_send.sendDataBat = &uart_send.data1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (uart_send.data2.dataState) {
|
|
|
|
|
if (uart_send.data2.device == g_bat485_uart3_handle) {
|
|
|
|
|
uart_send.sendStateBat= TRUE;
|
|
|
|
|
uart_send.sendDataBat = &uart_send.data2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (uart_send.data3.dataState) {
|
|
|
|
|
if (uart_send.data3.device == g_bat485_uart3_handle) {
|
|
|
|
|
uart_send.sendStateBat = TRUE;
|
|
|
|
|
uart_send.sendDataBat = &uart_send.data3;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief 串口中断发送函数
|
|
|
|
|
* @param
|
|
|
|
|
* @retval
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
void uart_interruptSend(device_handle device, uint8_t buff[], uint8_t len)
|
|
|
|
|
{
|
|
|
|
|
/* 拷贝数据到发送 */
|
|
|
|
|
do {
|
|
|
|
|
if (uart_send.insertState > 0 && uart_send.insertData != NULL) {
|
|
|
|
|
// memcpy(uart_send.insertData->data, buff, len);
|
|
|
|
|
for (int var = 0; var < len; ++var) {
|
|
|
|
|
uart_send.insertData->data[var] = buff[var];
|
|
|
|
|
// printf(" %x ", uart_send.insertData->data[var]);
|
|
|
|
|
}
|
|
|
|
|
uart_send.insertData->Counter = 0;
|
|
|
|
|
uart_send.insertData->dataLen = len;
|
|
|
|
|
uart_send.insertData->device = device;
|
|
|
|
|
// uart_send.insertData->dataState = 1;
|
|
|
|
|
// uart_send.insertState--;
|
2024-12-24 06:43:20 +00:00
|
|
|
|
|
|
|
|
|
uart_send.insertData->dataState = TRUE;
|
|
|
|
|
uart_send.insertState--;
|
2024-12-18 09:43:14 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
2024-12-24 06:43:20 +00:00
|
|
|
|
/* 0执行一次, 1一直循环直到能插入 */
|
|
|
|
|
} while (0);
|
2024-12-18 09:43:14 +00:00
|
|
|
|
|
|
|
|
|
/* 可插入数据大于0时,将插入指针指向空的储存位置,否则指向NULL */
|
|
|
|
|
if (uart_send.insertState > 0) {
|
|
|
|
|
if (uart_send.data1.dataState == FALSE) {
|
|
|
|
|
uart_send.insertData = &uart_send.data1;
|
|
|
|
|
}
|
|
|
|
|
else if (uart_send.data2.dataState == FALSE) {
|
|
|
|
|
uart_send.insertData = &uart_send.data2;
|
|
|
|
|
}
|
|
|
|
|
else if (uart_send.data3.dataState == FALSE) {
|
|
|
|
|
uart_send.insertData = &uart_send.data3;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
uart_send.insertData = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|