目录:
实现功能
主要代码逻辑
#实现功能:
将采集到的蓄电池信息数据上报到电脑上位机,可以直观的显示电池数据状态,上报数据模块连接上位机效果如下:

#主要代码逻辑:
新建工程后在api_common.c文件中st_BatInfo 添加需要上报的电池数据,包括电池电压、电流、温度、soc状态等等。默认初始值如下
ST_SIGCELL_Info st_CellInfo[16] = {
{
.cellVolt = 3720, // mV
.cellTemp = 23, // 温度
},
{
.cellVolt = 3877, // mV
.cellTemp = 25, // 温度
},
{
.cellVolt = 4203, // mV
.cellTemp = 27, // 温度
},
};
ST_BAT_INFO st_BatInfo =
{
.cum_volt = 12.7f, // V
.total_volt = 24.2f, // V
.curr = 42.3f, // A
.soc = 0.654f, // 56.4%
.maxMumCellVolt = 4273, // mV
.nembMaxCellVolt = 1, // id
.minMumCellVolt = 3735, // mV
.nembMinCellVolt = 5, // id
.maxMumCellTemp = 24, // 温度
.nembMaxCellTemp = 4, // id
.minMumCellTemp = 10, // 温度
.nembMinCellTemp = 2, // id
.changeStatus = 1, // 0 静止 1 充电 2 放电
.changeMosSt = 1, // 充电mos管状态
.dischangeMosSt = 1, // 放电mos管状态
.bmsCycle = 0x00, // bms life
.remainCapacity = 5327, // 剩余容量mAh
.numbBatt = 10, // 电池串数
.numbTemp = 10, // 温度个数
.changerStatus = 1, // 充电器状态
.loadStatus = 1, // 负载状态
// Byte4:Bit 0: DI1 state Bit 1: DI2 state Bit 2: DI3 state Bit 3: DI4 state Bit 4: DO1 state Bit 5: DO2 state Bit 6: DO3 state Bit 7: DO4 state
.DiDoStatus = 0x00,
.p_sigCell = st_CellInfo,
.numbSigCellVolt = 0x01, // 单体id
.sigCellVolt = 3854, // mV
.numbSigCellTemp = 0x01, // 单体id
.sigCellTemp = 21, // 温度
};
{
.cellVolt = 3720, // mV
.cellTemp = 23, // 温度
},
{
.cellVolt = 3877, // mV
.cellTemp = 25, // 温度
},
{
.cellVolt = 4203, // mV
.cellTemp = 27, // 温度
},
};
ST_BAT_INFO st_BatInfo =
{
.cum_volt = 12.7f, // V
.total_volt = 24.2f, // V
.curr = 42.3f, // A
.soc = 0.654f, // 56.4%
.maxMumCellVolt = 4273, // mV
.nembMaxCellVolt = 1, // id
.minMumCellVolt = 3735, // mV
.nembMinCellVolt = 5, // id
.maxMumCellTemp = 24, // 温度
.nembMaxCellTemp = 4, // id
.minMumCellTemp = 10, // 温度
.nembMinCellTemp = 2, // id
.changeStatus = 1, // 0 静止 1 充电 2 放电
.changeMosSt = 1, // 充电mos管状态
.dischangeMosSt = 1, // 放电mos管状态
.bmsCycle = 0x00, // bms life
.remainCapacity = 5327, // 剩余容量mAh
.numbBatt = 10, // 电池串数
.numbTemp = 10, // 温度个数
.changerStatus = 1, // 充电器状态
.loadStatus = 1, // 负载状态
// Byte4:Bit 0: DI1 state Bit 1: DI2 state Bit 2: DI3 state Bit 3: DI4 state Bit 4: DO1 state Bit 5: DO2 state Bit 6: DO3 state Bit 7: DO4 state
.DiDoStatus = 0x00,
.p_sigCell = st_CellInfo,
.numbSigCellVolt = 0x01, // 单体id
.sigCellVolt = 3854, // mV
.numbSigCellTemp = 0x01, // 单体id
.sigCellTemp = 21, // 温度
};
新建api_comm_thread_func子线程,用于采集电池温度、读取电压信息数据(暂没有外设硬件部分,电池生命状态值通过读取xTaskGetTickCount()获得,soc值随变量更新而更新)
static void api_comm_thread_func(void)
{
ST_BAT_INFO *pBatInfo = &st_BatInfo;
static uint32_t cnt_tim = 0;
for(;;)
{
pBatInfo->bmsCycle = 0xFF & (xTaskGetTickCount() / configTICK_RATE_HZ);
pBatInfo->soc = (float)pBatInfo->bmsCycle / 0xFF;
// uart_print_user_msg((uint8_t *)"\r api_comm_thread_func cnt data !\n");
cnt_tim ++;
cnt_tim = cnt_tim % 10000;
vTaskDelay(200);
}
}
void api_comm_thread_create(void)
{
comm_thread = xTaskCreateStatic (
(TaskFunction_t)api_comm_thread_func,
(const char*) "Uart Thread", COMM_STACK_SIZE/4, // world
NULL,
1,
(StackType_t*) &comm_thread_stack,
(StaticTask_t*) &comm_thread_memory
);
if (NULL == comm_thread)
{
rtos_startup_err_callback (comm_thread, 0);
}
}
{
ST_BAT_INFO *pBatInfo = &st_BatInfo;
static uint32_t cnt_tim = 0;
for(;;)
{
pBatInfo->bmsCycle = 0xFF & (xTaskGetTickCount() / configTICK_RATE_HZ);
pBatInfo->soc = (float)pBatInfo->bmsCycle / 0xFF;
// uart_print_user_msg((uint8_t *)"\r api_comm_thread_func cnt data !\n");
cnt_tim ++;
cnt_tim = cnt_tim % 10000;
vTaskDelay(200);
}
}
void api_comm_thread_create(void)
{
comm_thread = xTaskCreateStatic (
(TaskFunction_t)api_comm_thread_func,
(const char*) "Uart Thread", COMM_STACK_SIZE/4, // world
NULL,
1,
(StackType_t*) &comm_thread_stack,
(StaticTask_t*) &comm_thread_memory
);
if (NULL == comm_thread)
{
rtos_startup_err_callback (comm_thread, 0);
}
}
通过uart_thread_create新建uart线程用于上报数据,线程创建为静态分配内存空间,[size=13.3333px]uart_thread_func用于解析串口命令后做出应答
static uint8_t uart_thread_stack[UART_STACK_SIZE] BSP_PLACE_IN_SECTION(BSP_UNINIT_SECTION_PREFIX ".stack.uart_thread") BSP_ALIGN_VARIABLE(BSP_STACK_ALIGNMENT);
StaticSemaphore_t g_fsp_uart_initialized_semaphore_memory;
void uart_thread_create(void)
{
uart_thread = xTaskCreateStatic (
(TaskFunction_t)uart_thread_func,
(const char*) "Uart Thread", UART_STACK_SIZE/4, // world
NULL,
1,
(StackType_t*) &uart_thread_stack,
(StaticTask_t*) &uart_thread_memory
);
if (NULL == uart_thread)
{
rtos_startup_err_callback (uart_thread, 0);
}
SemCountUART = xSemaphoreCreateCountingStatic(256, 1, &g_fsp_uart_initialized_semaphore_memory);
}
在串口子线程中等待信号量SemCountUART释放后立即执行组命令包逻辑,在接收到信号量之前线程一直处于等待状态
static void uart_thread_func(void)
{
CMD_BUFF_t* p_recv = &UsartCmdBuff;
USART_SEND_BUFF_u *p_respSend = &usartSendBuf;
ST_BAT_INFO *pBatInfo = &st_BatInfo;
uart_print_user_msg((uint8_t *)"\r start uart_thread_func !\n");
for(;;)
{
xSemaphoreTake(SemCountUART, portMAX_DELAY);
if (p_recv->addr != 0x40)
{
continue;
}
p_respSend->sendData.Head = p_recv->Head;
p_respSend->sendData.addr = 0x01;
p_respSend->sendData.id = p_recv->id;
p_respSend->sendData.Length = p_recv->Length;
memset(p_respSend->sendData.pdata, 0, UART_DATA_SIZE);
switch (p_recv->id)
{
case 0x90:
p_respSend->sendData.pdata[0] = (uint8_t) ((uint32_t)(pBatInfo->cum_volt * 10) >> 8) & 0xFF;
p_respSend->sendData.pdata[1] = (uint8_t) (pBatInfo->cum_volt * 10) & 0xFF;
p_respSend->sendData.pdata[2] = (uint8_t) ((uint32_t)(pBatInfo->total_volt * 10) >> 8) & 0xFF;
p_respSend->sendData.pdata[3] = (uint8_t) (pBatInfo->total_volt * 10) & 0xFF;
p_respSend->sendData.pdata[4] = (uint8_t) ((uint32_t)((pBatInfo->curr + 3000.0f) * 10) >> 8) & 0xFF;
p_respSend->sendData.pdata[5] = (uint8_t) ((pBatInfo->curr + 3000.0f) * 10) & 0xFF;
p_respSend->sendData.pdata[6] = (uint8_t) ((uint32_t)(pBatInfo->soc * 1000) >> 8) & 0xFF;
p_respSend->sendData.pdata[7] = (uint8_t) (pBatInfo->soc * 1000) & 0xFF;
break;
case 0x91:
p_respSend->sendData.pdata[0] = (uint8_t) ((uint32_t)(pBatInfo->maxMumCellVolt) >> 8) & 0xFF;
p_respSend->sendData.pdata[1] = (uint8_t) (pBatInfo->maxMumCellVolt) & 0xFF;
p_respSend->sendData.pdata[2] = (uint8_t) (pBatInfo->nembMaxCellVolt) & 0xFF;
p_respSend->sendData.pdata[3] = (uint8_t) ((uint32_t)(pBatInfo->minMumCellVolt) >> 8) & 0xFF;
p_respSend->sendData.pdata[4] = (uint8_t) pBatInfo->minMumCellVolt & 0xFF;
p_respSend->sendData.pdata[5] = (uint8_t) pBatInfo->nembMinCellVolt & 0xFF;
break;
case 0x92:
p_respSend->sendData.pdata[0] = (uint8_t) (pBatInfo->maxMumCellTemp + 40) & 0xFF;
p_respSend->sendData.pdata[1] = (uint8_t) pBatInfo->nembMaxCellTemp & 0xFF;
p_respSend->sendData.pdata[2] = (uint8_t) (pBatInfo->minMumCellTemp + 40) & 0xFF;
p_respSend->sendData.pdata[3] = (uint8_t) pBatInfo->nembMinCellTemp & 0xFF;
break;
case 0x93:
p_respSend->sendData.pdata[0] = (uint8_t) pBatInfo->changeStatus & 0xFF;
p_respSend->sendData.pdata[1] = (uint8_t) pBatInfo->changeMosSt & 0xFF;
p_respSend->sendData.pdata[2] = (uint8_t) pBatInfo->dischangeMosSt & 0xFF;
p_respSend->sendData.pdata[3] = (uint8_t) pBatInfo->bmsCycle & 0xFF;
p_respSend->sendData.pdata[4] = (uint8_t) (pBatInfo->remainCapacity >> 24) & 0xFF;
p_respSend->sendData.pdata[5] = (uint8_t) (pBatInfo->remainCapacity >> 16) & 0xFF;
p_respSend->sendData.pdata[6] = (uint8_t) (pBatInfo->remainCapacity >> 8) & 0xFF;
p_respSend->sendData.pdata[7] = (uint8_t) pBatInfo->remainCapacity & 0xFF;
break;
case 0x94:
p_respSend->sendData.pdata[0] = (uint8_t) pBatInfo->numbBatt & 0xFF;
p_respSend->sendData.pdata[1] = (uint8_t) pBatInfo->numbTemp & 0xFF;
p_respSend->sendData.pdata[2] = (uint8_t) pBatInfo->changerStatus & 0xFF;
p_respSend->sendData.pdata[3] = (uint8_t) pBatInfo->loadStatus & 0xFF;
p_respSend->sendData.pdata[4] = (uint8_t) pBatInfo->DiDoStatus & 0xFF;
break;
case 0x95:
// cell volt
p_respSend->sendData.pdata[0] = (uint8_t) pBatInfo->numbSigCellVolt & 0xFF;
p_respSend->sendData.pdata[1] = (uint8_t) (pBatInfo->p_sigCell[0].cellVolt >> 8) & 0xFF;
p_respSend->sendData.pdata[2] = (uint8_t) pBatInfo->p_sigCell[0].cellVolt & 0xFF;
p_respSend->sendData.pdata[3] = (uint8_t) (pBatInfo->p_sigCell[1].cellVolt >> 8) & 0xFF;
p_respSend->sendData.pdata[4] = (uint8_t) pBatInfo->p_sigCell[1].cellVolt & 0xFF;
p_respSend->sendData.pdata[5] = (uint8_t) (pBatInfo->p_sigCell[2].cellVolt >> 8) & 0xFF;
p_respSend->sendData.pdata[6] = (uint8_t) pBatInfo->p_sigCell[2].cellVolt & 0xFF;
break;
case 0x96:
// cell temp
p_respSend->sendData.pdata[0] = (uint8_t) pBatInfo->numbSigCellTemp & 0xFF;
p_respSend->sendData.pdata[1] = (uint8_t) (pBatInfo->p_sigCell[0].cellTemp + 40) & 0xFF;
p_respSend->sendData.pdata[2] = (uint8_t) (pBatInfo->p_sigCell[1].cellTemp + 40) & 0xFF;
p_respSend->sendData.pdata[3] = (uint8_t) (pBatInfo->p_sigCell[2].cellTemp + 40) & 0xFF;
break;
case 0x97:
// bat balance
p_respSend->sendData.pdata[0] = (uint8_t) 0x03;
break;
case 0x98:
// warning
p_respSend->sendData.pdata[0] = (uint8_t) 0x11;
p_respSend->sendData.pdata[1] = (uint8_t) 0x11;
p_respSend->sendData.pdata[2] = (uint8_t) 0x11;
p_respSend->sendData.pdata[3] = (uint8_t) 0x11;
break;
default:
break;
}
api_usart_Send_BMS_Info(&usartSendBuf);
vTaskDelay(10);
}
}
{
CMD_BUFF_t* p_recv = &UsartCmdBuff;
USART_SEND_BUFF_u *p_respSend = &usartSendBuf;
ST_BAT_INFO *pBatInfo = &st_BatInfo;
uart_print_user_msg((uint8_t *)"\r start uart_thread_func !\n");
for(;;)
{
xSemaphoreTake(SemCountUART, portMAX_DELAY);
if (p_recv->addr != 0x40)
{
continue;
}
p_respSend->sendData.Head = p_recv->Head;
p_respSend->sendData.addr = 0x01;
p_respSend->sendData.id = p_recv->id;
p_respSend->sendData.Length = p_recv->Length;
memset(p_respSend->sendData.pdata, 0, UART_DATA_SIZE);
switch (p_recv->id)
{
case 0x90:
p_respSend->sendData.pdata[0] = (uint8_t) ((uint32_t)(pBatInfo->cum_volt * 10) >> 8) & 0xFF;
p_respSend->sendData.pdata[1] = (uint8_t) (pBatInfo->cum_volt * 10) & 0xFF;
p_respSend->sendData.pdata[2] = (uint8_t) ((uint32_t)(pBatInfo->total_volt * 10) >> 8) & 0xFF;
p_respSend->sendData.pdata[3] = (uint8_t) (pBatInfo->total_volt * 10) & 0xFF;
p_respSend->sendData.pdata[4] = (uint8_t) ((uint32_t)((pBatInfo->curr + 3000.0f) * 10) >> 8) & 0xFF;
p_respSend->sendData.pdata[5] = (uint8_t) ((pBatInfo->curr + 3000.0f) * 10) & 0xFF;
p_respSend->sendData.pdata[6] = (uint8_t) ((uint32_t)(pBatInfo->soc * 1000) >> 8) & 0xFF;
p_respSend->sendData.pdata[7] = (uint8_t) (pBatInfo->soc * 1000) & 0xFF;
break;
case 0x91:
p_respSend->sendData.pdata[0] = (uint8_t) ((uint32_t)(pBatInfo->maxMumCellVolt) >> 8) & 0xFF;
p_respSend->sendData.pdata[1] = (uint8_t) (pBatInfo->maxMumCellVolt) & 0xFF;
p_respSend->sendData.pdata[2] = (uint8_t) (pBatInfo->nembMaxCellVolt) & 0xFF;
p_respSend->sendData.pdata[3] = (uint8_t) ((uint32_t)(pBatInfo->minMumCellVolt) >> 8) & 0xFF;
p_respSend->sendData.pdata[4] = (uint8_t) pBatInfo->minMumCellVolt & 0xFF;
p_respSend->sendData.pdata[5] = (uint8_t) pBatInfo->nembMinCellVolt & 0xFF;
break;
case 0x92:
p_respSend->sendData.pdata[0] = (uint8_t) (pBatInfo->maxMumCellTemp + 40) & 0xFF;
p_respSend->sendData.pdata[1] = (uint8_t) pBatInfo->nembMaxCellTemp & 0xFF;
p_respSend->sendData.pdata[2] = (uint8_t) (pBatInfo->minMumCellTemp + 40) & 0xFF;
p_respSend->sendData.pdata[3] = (uint8_t) pBatInfo->nembMinCellTemp & 0xFF;
break;
case 0x93:
p_respSend->sendData.pdata[0] = (uint8_t) pBatInfo->changeStatus & 0xFF;
p_respSend->sendData.pdata[1] = (uint8_t) pBatInfo->changeMosSt & 0xFF;
p_respSend->sendData.pdata[2] = (uint8_t) pBatInfo->dischangeMosSt & 0xFF;
p_respSend->sendData.pdata[3] = (uint8_t) pBatInfo->bmsCycle & 0xFF;
p_respSend->sendData.pdata[4] = (uint8_t) (pBatInfo->remainCapacity >> 24) & 0xFF;
p_respSend->sendData.pdata[5] = (uint8_t) (pBatInfo->remainCapacity >> 16) & 0xFF;
p_respSend->sendData.pdata[6] = (uint8_t) (pBatInfo->remainCapacity >> 8) & 0xFF;
p_respSend->sendData.pdata[7] = (uint8_t) pBatInfo->remainCapacity & 0xFF;
break;
case 0x94:
p_respSend->sendData.pdata[0] = (uint8_t) pBatInfo->numbBatt & 0xFF;
p_respSend->sendData.pdata[1] = (uint8_t) pBatInfo->numbTemp & 0xFF;
p_respSend->sendData.pdata[2] = (uint8_t) pBatInfo->changerStatus & 0xFF;
p_respSend->sendData.pdata[3] = (uint8_t) pBatInfo->loadStatus & 0xFF;
p_respSend->sendData.pdata[4] = (uint8_t) pBatInfo->DiDoStatus & 0xFF;
break;
case 0x95:
// cell volt
p_respSend->sendData.pdata[0] = (uint8_t) pBatInfo->numbSigCellVolt & 0xFF;
p_respSend->sendData.pdata[1] = (uint8_t) (pBatInfo->p_sigCell[0].cellVolt >> 8) & 0xFF;
p_respSend->sendData.pdata[2] = (uint8_t) pBatInfo->p_sigCell[0].cellVolt & 0xFF;
p_respSend->sendData.pdata[3] = (uint8_t) (pBatInfo->p_sigCell[1].cellVolt >> 8) & 0xFF;
p_respSend->sendData.pdata[4] = (uint8_t) pBatInfo->p_sigCell[1].cellVolt & 0xFF;
p_respSend->sendData.pdata[5] = (uint8_t) (pBatInfo->p_sigCell[2].cellVolt >> 8) & 0xFF;
p_respSend->sendData.pdata[6] = (uint8_t) pBatInfo->p_sigCell[2].cellVolt & 0xFF;
break;
case 0x96:
// cell temp
p_respSend->sendData.pdata[0] = (uint8_t) pBatInfo->numbSigCellTemp & 0xFF;
p_respSend->sendData.pdata[1] = (uint8_t) (pBatInfo->p_sigCell[0].cellTemp + 40) & 0xFF;
p_respSend->sendData.pdata[2] = (uint8_t) (pBatInfo->p_sigCell[1].cellTemp + 40) & 0xFF;
p_respSend->sendData.pdata[3] = (uint8_t) (pBatInfo->p_sigCell[2].cellTemp + 40) & 0xFF;
break;
case 0x97:
// bat balance
p_respSend->sendData.pdata[0] = (uint8_t) 0x03;
break;
case 0x98:
// warning
p_respSend->sendData.pdata[0] = (uint8_t) 0x11;
p_respSend->sendData.pdata[1] = (uint8_t) 0x11;
p_respSend->sendData.pdata[2] = (uint8_t) 0x11;
p_respSend->sendData.pdata[3] = (uint8_t) 0x11;
break;
default:
break;
}
api_usart_Send_BMS_Info(&usartSendBuf);
vTaskDelay(10);
}
}
接收串口数据按一帧13byte,分别由命令头、命令id、命令地址、长度、命令内容8byte和命令检验和组成,收到数据后,粘包处理如下,最终存储到g_uart_recv_buffer[DATA_LENGTH]中
void user_uart_callback(uart_callback_args_t *p_args)
{
/* Logged the event in global variable */
g_uart_event = (uint8_t)p_args->event;
BaseType_t xHigherPriorityTaskWoken = pdTRUE;
static uint32_t bufferIdx = 0;
uint8_t *pUsartCmd = g_uart_recv_buffer;
if(UART_EVENT_RX_CHAR == p_args->event)
{
*(pUsartCmd + bufferIdx) = (uint8_t ) p_args->data;
if (bufferIdx > 0)
{
if ((*(pUsartCmd + bufferIdx - 1) == 0xA5) && (*(pUsartCmd + bufferIdx) == 0x40))
{
if (bufferIdx != 1)
{
bufferIdx = 1;
*(pUsartCmd + 0) = 0xA5;
*(pUsartCmd + 1) = 0x40;
}
}
}
if ((*(pUsartCmd + bufferIdx) != CARRIAGE_ASCII) && (bufferIdx < (DATA_LENGTH - 1u)))
{
bufferIdx++;
}
else
{
if (api_check_cmd_data(g_uart_recv_buffer) == true)
{
xSemaphoreGiveFromISR(SemCountUART, &xHigherPriorityTaskWoken);
}
bufferIdx = 0;
}
}
}
{
/* Logged the event in global variable */
g_uart_event = (uint8_t)p_args->event;
BaseType_t xHigherPriorityTaskWoken = pdTRUE;
static uint32_t bufferIdx = 0;
uint8_t *pUsartCmd = g_uart_recv_buffer;
if(UART_EVENT_RX_CHAR == p_args->event)
{
*(pUsartCmd + bufferIdx) = (uint8_t ) p_args->data;
if (bufferIdx > 0)
{
if ((*(pUsartCmd + bufferIdx - 1) == 0xA5) && (*(pUsartCmd + bufferIdx) == 0x40))
{
if (bufferIdx != 1)
{
bufferIdx = 1;
*(pUsartCmd + 0) = 0xA5;
*(pUsartCmd + 1) = 0x40;
}
}
}
if ((*(pUsartCmd + bufferIdx) != CARRIAGE_ASCII) && (bufferIdx < (DATA_LENGTH - 1u)))
{
bufferIdx++;
}
else
{
if (api_check_cmd_data(g_uart_recv_buffer) == true)
{
xSemaphoreGiveFromISR(SemCountUART, &xHigherPriorityTaskWoken);
}
bufferIdx = 0;
}
}
}
存储的数据再去匹配比对校验和,匹配ok则存储到结构体UsartCmdBuff中等待使用,最后一步便是释放信号量后,串口线程则开始解析命令内容
uint8_t api_check_cmd_data(uint8_t* p_recvdata)
{
uint8_t checksum = 0x00;
uint8_t i = 0;
if ((*(p_recvdata + 0) == UsartCmdBuff.Head) && (*(p_recvdata + 1) == UsartCmdBuff.addr)) {
for(i = 0; i < 12; i ++) {
checksum += *(p_recvdata + i);
checksum = 0xFF & checksum;
}
if (*(p_recvdata + 12) == checksum)
{
UsartCmdBuff.id = *(p_recvdata + 2);
UsartCmdBuff.Length = *(p_recvdata + 3);
for(i = 0; i < 8; i ++)
{
UsartCmdBuff.pdata = *(p_recvdata + i + 4);
}
UsartCmdBuff.checksum = *(p_recvdata + 12);
return true;
}
else {
return false;
}
}
return false;
}
{
uint8_t checksum = 0x00;
uint8_t i = 0;
if ((*(p_recvdata + 0) == UsartCmdBuff.Head) && (*(p_recvdata + 1) == UsartCmdBuff.addr)) {
for(i = 0; i < 12; i ++) {
checksum += *(p_recvdata + i);
checksum = 0xFF & checksum;
}
if (*(p_recvdata + 12) == checksum)
{
UsartCmdBuff.id = *(p_recvdata + 2);
UsartCmdBuff.Length = *(p_recvdata + 3);
for(i = 0; i < 8; i ++)
{
UsartCmdBuff.pdata = *(p_recvdata + i + 4);
}
UsartCmdBuff.checksum = *(p_recvdata + 12);
return true;
}
else {
return false;
}
}
return false;
}
串口组包ok后则通过fsp_err_t uart_send_bytes(uint8_t *p_msg,uint8_t msg_len)发送出去一帧数据,回应给上位机。
fsp_err_t uart_send_bytes(uint8_t *p_msg, uint8_t msg_len)
{
fsp_err_t err = FSP_SUCCESS;
uint32_t local_timeout = (DATA_LENGTH * UINT16_MAX);
/* Reset callback capture variable */
g_uart_event = RESET_VALUE;
/* Writing to terminal */
err = R_SCI_UART_Write (&g_uart0_ctrl, p_msg, msg_len);
if (FSP_SUCCESS != err)
{
return err;
}
/* Check for event transfer complete */
while ((UART_EVENT_TX_COMPLETE != g_uart_event) && (--local_timeout))
{
/* Check if any error event occurred */
if (UART_ERROR_EVENTS == g_uart_event)
{
return FSP_ERR_TRANSFER_ABORTED;
}
}
if(RESET_VALUE == local_timeout)
{
err = FSP_ERR_TIMEOUT;
}
return err;
}
{
fsp_err_t err = FSP_SUCCESS;
uint32_t local_timeout = (DATA_LENGTH * UINT16_MAX);
/* Reset callback capture variable */
g_uart_event = RESET_VALUE;
/* Writing to terminal */
err = R_SCI_UART_Write (&g_uart0_ctrl, p_msg, msg_len);
if (FSP_SUCCESS != err)
{
return err;
}
/* Check for event transfer complete */
while ((UART_EVENT_TX_COMPLETE != g_uart_event) && (--local_timeout))
{
/* Check if any error event occurred */
if (UART_ERROR_EVENTS == g_uart_event)
{
return FSP_ERR_TRANSFER_ABORTED;
}
}
if(RESET_VALUE == local_timeout)
{
err = FSP_ERR_TIMEOUT;
}
return err;
}
硬件连接如下:

调试串口数据时使用发命令方式验证效果ok,如下:

最终上位机看到数据上报效果ok
