调通串口与上位机双向通信

- UART2 TX: 硬件FIFO+DMA+块传输模式,非阻塞发送
- UART2 RX: 硬件FIFO+中断+软件FIFO,状态机解析协议帧
- 协议: [SOF:0xA7][cmd:1][checksum:1],支持自动/手动/调试模式切换
- 更新.gitignore忽略*.log文件
This commit is contained in:
2026-06-07 11:42:15 +08:00
committed by SkyLi
parent f28d129e11
commit d120fa0d17
4 changed files with 165 additions and 86 deletions
+10 -9
View File
@@ -1,10 +1,11 @@
/libraries/sdk/ti_config/excluded /libraries/sdk/ti_config/excluded
/project/keil/Listings/ /project/keil/Listings/
/project/keil/Objects/ /project/keil/Objects/
uv4.log uv4.log
uv4.log.lock uv4.log.lock
keil-assistant.log keil-assistant.log
*.log
CLAUDE.md CLAUDE.md
+137 -65
View File
@@ -1,66 +1,138 @@
#include "Command.h" #include "Command.h"
#include "zf_driver_uart.h" #include "zf_driver_uart.h"
#include "zf_common_interrupt.h" #include "zf_common_interrupt.h"
#include "ti/driverlib/dl_uart_main.h" #include "ti/driverlib/dl_uart_main.h"
#include "zf_common_fifo.h" #include "ti/driverlib/dl_dma.h"
#include "zf_common_fifo.h"
volatile fifo_struct command_fifo = {0}; #include "Beep.h"
volatile uint8_t command_fifo_buffer[COMMAND_FIFO_BUFFER_SIZE] = {0};
uint8_t command_sum(uint8_t* data,int len); volatile fifo_struct command_fifo = {0};
volatile uint8_t command_fifo_buffer[COMMAND_FIFO_BUFFER_SIZE] = {0};
void command_callback(uint32 state, void *ptr) uint8_t command_sum(uint8_t* data,int len);
{
while(false == DL_UART_isRXFIFOEmpty(UART2))//读取到一个数据 void command_callback(uint32 state, void *ptr)
{ {
fifo_write_element((fifo_struct*)&command_fifo,DL_UART_Main_receiveData(UART2));//写入软件FIFO while(false == DL_UART_isRXFIFOEmpty(UART2))//读取到一个数据
} {
} fifo_write_element((fifo_struct*)&command_fifo,DL_UART_Main_receiveData(UART2));//写入软件FIFO
void command_init() }
{ }
uart_init(UART_2,115200,UART2_TX_B15,UART2_RX_B16); void command_init()
uart_set_interrupt_config(UART_2,UART_INTERRUPT_CONFIG_RX_ENABLE); {
interrupt_set_priority(UART2_INT_IRQn,1);//设置为与主要任务平行的优先级 uart_init(UART_2,115200,UART2_TX_B15,UART2_RX_B16);
uart_set_interrupt_config(UART_2,UART_INTERRUPT_CONFIG_RX_ENABLE);
//开启发送DMA interrupt_set_priority(UART2_INT_IRQn,2);//设置为次于主要任务的优先级
//开启硬件FIFO //开启发送DMA
DL_UART_Main_enableFIFOs(UART2); static const DL_DMA_Config dma_tx_config =
DL_UART_Main_setRXFIFOThreshold(UART2,DL_UART_MAIN_RX_FIFO_LEVEL_1_2_FULL); {
.trigger = DMA_UART2_TX_TRIG,
//设置软件FIFO .triggerType = DL_DMA_TRIGGER_TYPE_EXTERNAL,
fifo_init((fifo_struct *)&command_fifo,FIFO_DATA_8BIT,(void*)command_fifo_buffer,COMMAND_FIFO_BUFFER_SIZE); .transferMode = DL_DMA_SINGLE_TRANSFER_MODE,
//设置中断回调 .extendedMode = DL_DMA_NORMAL_MODE,
uart_set_callback(UART_2,command_callback,NULL); .srcWidth = DL_DMA_WIDTH_BYTE,
} .destWidth = DL_DMA_WIDTH_BYTE,
//从软件FIFO中解析数据包并执行 .srcIncrement = DL_DMA_ADDR_INCREMENT,
void command_task() .destIncrement = DL_DMA_ADDR_UNCHANGED,
{ };
DL_DMA_initChannel(DMA, 0, &dma_tx_config);
} DL_UART_Main_enableDMATransmitEvent(UART2);
//DMA发送使用的地址
uint8_t angle_velocity_data[6] = {0}; //开启硬件FIFO
//发送速度前馈 DL_UART_Main_enableFIFOs(UART2);
void command_send_angle_velocity(float* pointer_angle_velocity) DL_UART_Main_setRXFIFOThreshold(UART2,DL_UART_MAIN_RX_FIFO_LEVEL_ONE_ENTRY);
{ DL_UART_Main_setTXFIFOThreshold(UART2,DL_UART_MAIN_TX_FIFO_LEVEL_ONE_ENTRY);
//等待上一次DMA发送完成
//设置软件FIFO
//填充数据 fifo_init((fifo_struct *)&command_fifo,FIFO_DATA_8BIT,(void*)command_fifo_buffer,COMMAND_FIFO_BUFFER_SIZE);
uint8_t* p = (uint8_t*)pointer_angle_velocity; //设置中断回调
angle_velocity_data[0]=0xA1; uart_set_callback(UART_2,command_callback,NULL);
angle_velocity_data[1]=*(p++); }
angle_velocity_data[2]=*(p++); //从软件FIFO中解析数据包并执行
angle_velocity_data[3]=*(p++); void command_task()
angle_velocity_data[4]=*(p++); {
angle_velocity_data[5]=command_sum(angle_velocity_data,5); static uint8_t state = 0;
//DMA发送(非阻塞) static uint8_t cmd;
uint8_t byte;
}
uint8_t command_sum(uint8_t* data,int len) while(fifo_used((fifo_struct*)&command_fifo) > 0)
{ {
uint8_t sum = 0; switch(state)
for(int i=0;i<len;i++) {
{ case 0: // 等待SOF 0xA7
sum+=data[i]; fifo_read_element((fifo_struct*)&command_fifo, &byte, FIFO_READ_AND_CLEAN);
} if(byte == 0xA7) state = 1;
return sum; break;
case 1: // 读取cmd
fifo_read_element((fifo_struct*)&command_fifo, &cmd, FIFO_READ_AND_CLEAN);
state = 2;
break;
case 2: // 校验checksum = SOF + cmd
fifo_read_element((fifo_struct*)&command_fifo, &byte, FIFO_READ_AND_CLEAN);
if(byte == (uint8_t)(0xA7 + cmd))
{
switch(cmd)
{
case 0x01: SwitchToAutoMode(); break;
case 0x02: SwitchToManualMode(); break;
case 0x03: SwitchToDebugMode(); break;
}
}
state = 0;
break;
}
}
}
//切换到自动模式
void SwitchToAutoMode()
{
beep_on_time(100);
}
//切换到手动模式
void SwitchToManualMode()
{
beep_on_time(200);
}
//切换到调试模式
void SwitchToDebugMode()
{
beep_on_time(300);
}
//DMA发送使用的地址
uint8_t angle_velocity_data[6] = {0};
//发送速度前馈
void command_send_angle_velocity(float* pointer_angle_velocity)
{
//等待上一次DMA发送完成
while(DL_DMA_isChannelEnabled(DMA, 0));
//等待UART物理发送完成
while(!DL_UART_isTXFIFOEmpty(UART2));
//填充数据
uint8_t* p = (uint8_t*)pointer_angle_velocity;
angle_velocity_data[0]=0xA9;
angle_velocity_data[1]=*(p++);
angle_velocity_data[2]=*(p++);
angle_velocity_data[3]=*(p++);
angle_velocity_data[4]=*(p++);
angle_velocity_data[5]=command_sum(angle_velocity_data,5);
//DMA发送(非阻塞)
DL_DMA_setSrcAddr(DMA, 0, (uint32_t)angle_velocity_data);
DL_DMA_setDestAddr(DMA, 0, (uint32_t)&UART2->TXDATA);
DL_DMA_setTransferSize(DMA, 0, 6);
DL_DMA_enableChannel(DMA, 0);
// UART TX FIFO为空,DMA触发条件已满足,使能通道即自动开始传输
}
uint8_t command_sum(uint8_t* data,int len)
{
uint8_t sum = 0;
for(int i=0;i<len;i++)
{
sum+=data[i];
}
return sum;
} }
+15 -11
View File
@@ -1,12 +1,16 @@
#ifndef __COMMAND_H #ifndef __COMMAND_H
#define __COMMAND_H #define __COMMAND_H
#define COMMAND_FIFO_BUFFER_SIZE 16 #define COMMAND_FIFO_BUFFER_SIZE 16
#include "zf_common_typedef.h" #include "zf_common_typedef.h"
void command_init(); void command_init();
void command_task(); void command_task();
void command_send_angle_velocity(float* pointer_angle_velocity); void command_send_angle_velocity(float* pointer_angle_velocity);
void SwitchToAutoMode();
void SwitchToManualMode();
void SwitchToDebugMode();
#endif #endif
+3 -1
View File
@@ -46,6 +46,7 @@
#include "Beep.h" #include "Beep.h"
#include "GrayscaleSensor.h" #include "GrayscaleSensor.h"
#include "MotorEncoder.h" #include "MotorEncoder.h"
#include "Command.h"
/* /*
定时器资源分配: 定时器资源分配:
@@ -60,7 +61,7 @@ G6 20Hz任务
0 GPIOA_INT_IRQn 外部中断模拟四倍频正交编码器 0 GPIOA_INT_IRQn 外部中断模拟四倍频正交编码器
1 TIMA0_INT_IRQn 100Hz任务 1 TIMA0_INT_IRQn 100Hz任务
1 TIMA1_INT_IRQn 50Hz任务 1 TIMA1_INT_IRQn 50Hz任务
1 UART2_INT_IRQn Command串口接收中断 2 UART2_INT_IRQn Command串口接收中断
7 TIMG6_INT_IRQn 20Hz任务 7 TIMG6_INT_IRQn 20Hz任务
*/ */
int main (void) int main (void)
@@ -75,6 +76,7 @@ int main (void)
imu_calibrate_gyro(); // IMU 陀螺仪零偏校准 需要在静止状态下调用 imu_calibrate_gyro(); // IMU 陀螺仪零偏校准 需要在静止状态下调用
grayscale_sensor_init();//灰度传感器初始化 grayscale_sensor_init();//灰度传感器初始化
motor_encoder_init();//电机编码器初始化 motor_encoder_init();//电机编码器初始化
command_init();
task_init(); task_init();