forked from gary/BCU
2
0
Fork 0

优化远程配置驱动--目前支持全部读取和单个写入,上个版本问题未解决

This commit is contained in:
Carl 2025-06-06 11:11:58 +08:00
parent 857a4b434d
commit ccd6ea6432
7 changed files with 7751 additions and 9276 deletions

View File

@ -10,6 +10,8 @@
//#define TX_DMA_BUFFER_SIZE 800
extern uint8_t dma_tx_buffer[];
extern volatile uint8_t dma_tx_busy;
extern volatile uint8_t current_buffer;
const GpioArray io_array[kGpioType_End] =
{
@ -97,6 +99,14 @@ const GpioArray io_array[kGpioType_End] =
kGpioMode_Input_Floating, kGpioStatus_High, GPIO_PORT_PIN(kGpioPort_G, 15), kGpioPort_G, kGpioPin_15 , //W5500_INT
};
void reset_dma_tx_state(void)
{
__disable_irq();
dma_tx_busy = 0;
current_buffer = 0;
__enable_irq();
}
void drv_wireless_dma_init(void)
{
// 使能 DMA1 和 USART2 的时钟
@ -122,6 +132,11 @@ void drv_wireless_dma_init(void)
DMA_SxCR_TEIE | // 建议添加传输错误中断
(0 << 16); // 优先级
reset_dma_tx_state();
DMA1_Stream6->CR |= (1 << 0); // 启用FIFO
DMA1_Stream6->FCR = (0x3 << 0); // 全FIFO模式
NVIC_EnableIRQ(DMA1_Stream6_IRQn);
}

View File

@ -50,7 +50,7 @@
<InvalidFlash>1</InvalidFlash>
</TargetStatus>
<OutputDirectory>.\Objects\</OutputDirectory>
<OutputName>BCU10</OutputName>
<OutputName>BCU11</OutputName>
<CreateExecutable>1</CreateExecutable>
<CreateLib>0</CreateLib>
<CreateHexFile>1</CreateHexFile>
@ -83,7 +83,7 @@
<AfterMake>
<RunUserProg1>0</RunUserProg1>
<RunUserProg2>0</RunUserProg2>
<UserProg1Name>D:\CodeHvStack\BCU\app\stm32fxxx_app\hex2bin.exe D:\CodeHvStack\BCU\app\stm32fxxx_app\prj\Objects\BCU10.hex</UserProg1Name>
<UserProg1Name>D:\CodeHvStack\BCU\app\stm32fxxx_app\hex2bin.exe D:\CodeHvStack\BCU\app\stm32fxxx_app\prj\Objects\BCU11.hex</UserProg1Name>
<UserProg2Name></UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>

File diff suppressed because it is too large Load Diff

View File

@ -834,6 +834,20 @@ BspMdExCode bcu_modbus_485_0x04_fun(uint16_t start_addr, uint16_t reg_num, uint8
}
return err;
}
/*
modbus读取数据接口和读取并发送单个数据到mqtt的代码
3000 3
3010 1
3017 1
3041 1
3068 2
3092 1
3156 1
4000 72
4198 72
+
*/
void bcu_data_set_0x06_msg(uint16_t address,uint16_t data)
{
@ -1206,7 +1220,7 @@ BspMdExCode bcu_modbus_485_0x06_fun(uint16_t start_addr, uint16_t reg_num, uint8
data = (buf[0] << 8) + buf[1];
//kit_time_dly_ms(50);
if((start_addr >= 3000) && (start_addr <= 3169))
if((start_addr >= 3000) && (start_addr <= 3149))
{
bcu_data_set_0x06_msg(start_addr, data);
*len = reg_num << 1;

File diff suppressed because it is too large Load Diff

View File

@ -30,9 +30,26 @@ WifiBleItem qfc41dItem = {
.sendCall = NULL,
};
typedef struct {
uint16_t start_addr;
uint16_t reg_num;
} RegSegment;
RegSegment segments[] = {
{3000, 3}, //BMU个数电芯总数温感总数
{3010, 1}, //Can通讯协议
{3017, 1}, //设备地址
{3041, 1}, //SOC
{3068, 2}, //SOC满放校准电压满充校准电压
{3092, 1}, //充电末端降流电压
{4000, 72}, //放电欠压值
{4198, 72} //充电过压值
};
const uint8_t segment_count = sizeof(segments) / sizeof(segments[0]);
void parse_mqtt_message(char* message)
{
// 示例消息: +QMTRECV: 0,31,"bluesun/bms/control/123",11,"MQ3156+1MQ"
// +QMTRECV: 0,31,"bluesun/bms/control/123",11,"MQ3156+1MQ"
uint16_t first = 0;
uint16_t second = 0;
uint8_t buffer[5];
@ -95,7 +112,6 @@ void parse_mqtt_message(char* message)
first = atoi(processed);
second = atoi(plus_pos + 1);
current_buffer = 1;
if(strstr(message, "control") != NULL)
{
buffer[0] = (second >> 8) & 0xFF;
@ -118,17 +134,49 @@ void parse_mqtt_message(char* message)
}
else if (strstr(message, "read") != NULL)
{
data = bcu_modbus_485_0x03_fun(first, 1, buffer, &length);
char data_str[650] = {0};
uint8_t is_first_data = 1; // 标记是否为第一个数据
uint8_t read_success = 1;
if (data == 0 && length >= 2)
for (uint8_t i = 0; i < segment_count; i++)
{
uint16_t value = (buffer[0] << 8) | buffer[1];
uint16_t start_addr = segments[i].start_addr;
uint16_t reg_num = segments[i].reg_num;
uint16_t length = 0;
uint8_t read_buffer[150] = {0};
snprintf(data_str, sizeof(data_str), "%u", value);
drv_mqtt_publish_read_no_respose(data_str, strlen(data_str));
uint8_t err = bcu_modbus_485_0x03_fun(start_addr, reg_num, read_buffer, &length);
if (err != 0 || length != (reg_num << 1))
{
read_success = 0;
break;
}
for (uint16_t j = 0; j < reg_num; j++)
{
uint16_t value = (read_buffer[j * 2] << 8) | read_buffer[j * 2 + 1];
if (!is_first_data)
{
strcat(data_str, "+");
}
else
{
is_first_data = 0;
}
char val_str[6];
snprintf(val_str, sizeof(val_str), "%u", value);
strcat(data_str, val_str);
}
}
if (read_success && strlen(data_str) > 0)
{
drv_mqtt_publish_read_no_respose(data_str, strlen(data_str));
}
}
current_buffer = 0;
}
static void drv_qfc41d_push_data(WifiBleItem* item, uint8_t *buf, uint16_t len)
@ -179,35 +227,37 @@ void drv_wireless_send_string(const char *str)
void drv_wireless_send_string_dma_high_priority(const char *str)
{
uint32_t timeout = 0;
uint32_t start_time = kit_time_get_tick();
uint32_t start_time = kit_time_get_tick();
while (dma_tx_busy && current_buffer == 0)
{
if (kit_time_get_tick() - start_time > 100)
if (kit_time_get_tick() - start_time > 180)
{
DMA1_Stream6->CR &= ~DMA_SxCR_EN;
while (DMA1_Stream6->CR & DMA_SxCR_EN);
// 清除可能的中断标志
DMA1->HIFCR |= DMA_HIFCR_CTCIF6 | DMA_HIFCR_CTEIF6;
dma_tx_busy = 0;
current_buffer = 0;
USART2->CR3 &= ~USART_CR3_DMAT;
break;
}
__disable_irq();
if (DMA1_Stream6->CR & DMA_SxCR_EN)
{
DMA1_Stream6->CR &= ~DMA_SxCR_EN;
while (DMA1_Stream6->CR & DMA_SxCR_EN);
DMA1->HIFCR |= DMA_HIFCR_CTCIF6 | DMA_HIFCR_CTEIF6;
}
dma_tx_busy = 0;
current_buffer = 0;
USART2->CR3 &= ~USART_CR3_DMAT;
__enable_irq();
break;
}
}
uint16_t len = 0;
while (*str && len < TX_DMA_BUFFER_SIZE - 2) {
uint16_t len = 0;
while (*str && len < TX_DMA_BUFFER_SIZE - 2)
{
dma_tx_buffer[1][len++] = *str++;
}
dma_tx_buffer[1][len++] = '\r';
dma_tx_buffer[1][len++] = '\n';
// 设置 DMA 参数并启动
__disable_irq();
// 确保DMA已停止
DMA1_Stream6->CR &= ~DMA_SxCR_EN;
while (DMA1_Stream6->CR & DMA_SxCR_EN);
@ -217,25 +267,37 @@ void drv_wireless_send_string_dma_high_priority(const char *str)
dma_tx_busy = 1;
current_buffer = 1;
DMA1_Stream6->CR |= DMA_SxCR_EN;
USART2->CR3 |= USART_CR3_DMAT; // 开启 DMA 发送
USART2->CR3 |= USART_CR3_DMAT;
__enable_irq();
}
void drv_wireless_send_string_dma(const char *str)
{
if (dma_tx_busy || current_buffer == 1) return; // 正在发送或高优先级发送中,丢弃
bsp_task_delay_ms(250);
uint16_t len = 0;
__disable_irq();
if (dma_tx_busy || current_buffer == 1)
{
__enable_irq();
return;
}
__enable_irq();
// 拷贝数据到 DMA 缓冲区
bsp_task_delay_ms(250);
uint16_t len = 0;
while (*str && len < TX_DMA_BUFFER_SIZE - 2)
{
dma_tx_buffer[0][len++] = *str++;
}
dma_tx_buffer[0][len++] = '\r';
dma_tx_buffer[0][len++] = '\n';
// 设置 DMA 参数并启动
__disable_irq();
if (dma_tx_busy || current_buffer == 1)
{
__enable_irq();
return;
}
DMA1_Stream6->CR &= ~DMA_SxCR_EN;
while (DMA1_Stream6->CR & DMA_SxCR_EN);
@ -245,7 +307,8 @@ void drv_wireless_send_string_dma(const char *str)
dma_tx_busy = 1;
current_buffer = 0;
DMA1_Stream6->CR |= DMA_SxCR_EN;
USART2->CR3 |= USART_CR3_DMAT; // 开启 DMA 发送
USART2->CR3 |= USART_CR3_DMAT;
__enable_irq();
}

View File

@ -279,13 +279,14 @@ void DMA1_Stream5_IRQHandler(void)
void DMA1_Stream6_IRQHandler(void)
{
__disable_irq();
if (DMA1->HISR & DMA_HISR_TCIF6)
{
DMA1->HIFCR |= DMA_HIFCR_CTCIF6;
dma_tx_busy = 0;
USART2->CR3 &= ~USART_CR3_DMAT; // 传输完成后关闭DMA请求
USART2->CR3 &= ~USART_CR3_DMAT;
// 如果是高优先级缓冲区发送完成,切换回正常缓冲区
if (current_buffer == 1)
{
current_buffer = 0;
@ -295,8 +296,10 @@ void DMA1_Stream6_IRQHandler(void)
{
DMA1->HIFCR |= DMA_HIFCR_CTEIF6;
dma_tx_busy = 0;
current_buffer = 0; // 发生错误也切换回正常缓冲区
current_buffer = 0;
}
__enable_irq();
}
void DMA1_Channel6_IRQHandler(void)