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

- 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
/project/keil/Listings/
/project/keil/Objects/
uv4.log
uv4.log.lock
keil-assistant.log
/libraries/sdk/ti_config/excluded
/project/keil/Listings/
/project/keil/Objects/
uv4.log
uv4.log.lock
keil-assistant.log
*.log
CLAUDE.md
+137 -65
View File
@@ -1,66 +1,138 @@
#include "Command.h"
#include "zf_driver_uart.h"
#include "zf_common_interrupt.h"
#include "ti/driverlib/dl_uart_main.h"
#include "zf_common_fifo.h"
volatile fifo_struct command_fifo = {0};
volatile uint8_t command_fifo_buffer[COMMAND_FIFO_BUFFER_SIZE] = {0};
uint8_t command_sum(uint8_t* data,int len);
void command_callback(uint32 state, void *ptr)
{
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);
uart_set_interrupt_config(UART_2,UART_INTERRUPT_CONFIG_RX_ENABLE);
interrupt_set_priority(UART2_INT_IRQn,1);//设置为与主要任务平行的优先级
//开启发送DMA
//开启硬件FIFO
DL_UART_Main_enableFIFOs(UART2);
DL_UART_Main_setRXFIFOThreshold(UART2,DL_UART_MAIN_RX_FIFO_LEVEL_1_2_FULL);
//设置软件FIFO
fifo_init((fifo_struct *)&command_fifo,FIFO_DATA_8BIT,(void*)command_fifo_buffer,COMMAND_FIFO_BUFFER_SIZE);
//设置中断回调
uart_set_callback(UART_2,command_callback,NULL);
}
//从软件FIFO中解析数据包并执行
void command_task()
{
}
//DMA发送使用的地址
uint8_t angle_velocity_data[6] = {0};
//发送速度前馈
void command_send_angle_velocity(float* pointer_angle_velocity)
{
//等待上一次DMA发送完成
//填充数据
uint8_t* p = (uint8_t*)pointer_angle_velocity;
angle_velocity_data[0]=0xA1;
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发送(非阻塞)
}
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;
#include "Command.h"
#include "zf_driver_uart.h"
#include "zf_common_interrupt.h"
#include "ti/driverlib/dl_uart_main.h"
#include "ti/driverlib/dl_dma.h"
#include "zf_common_fifo.h"
#include "Beep.h"
volatile fifo_struct command_fifo = {0};
volatile uint8_t command_fifo_buffer[COMMAND_FIFO_BUFFER_SIZE] = {0};
uint8_t command_sum(uint8_t* data,int len);
void command_callback(uint32 state, void *ptr)
{
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);
uart_set_interrupt_config(UART_2,UART_INTERRUPT_CONFIG_RX_ENABLE);
interrupt_set_priority(UART2_INT_IRQn,2);//设置为次于主要任务的优先级
//开启发送DMA
static const DL_DMA_Config dma_tx_config =
{
.trigger = DMA_UART2_TX_TRIG,
.triggerType = DL_DMA_TRIGGER_TYPE_EXTERNAL,
.transferMode = DL_DMA_SINGLE_TRANSFER_MODE,
.extendedMode = DL_DMA_NORMAL_MODE,
.srcWidth = DL_DMA_WIDTH_BYTE,
.destWidth = DL_DMA_WIDTH_BYTE,
.srcIncrement = DL_DMA_ADDR_INCREMENT,
.destIncrement = DL_DMA_ADDR_UNCHANGED,
};
DL_DMA_initChannel(DMA, 0, &dma_tx_config);
DL_UART_Main_enableDMATransmitEvent(UART2);
//开启硬件FIFO
DL_UART_Main_enableFIFOs(UART2);
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);
//设置软件FIFO
fifo_init((fifo_struct *)&command_fifo,FIFO_DATA_8BIT,(void*)command_fifo_buffer,COMMAND_FIFO_BUFFER_SIZE);
//设置中断回调
uart_set_callback(UART_2,command_callback,NULL);
}
//从软件FIFO中解析数据包并执行
void command_task()
{
static uint8_t state = 0;
static uint8_t cmd;
uint8_t byte;
while(fifo_used((fifo_struct*)&command_fifo) > 0)
{
switch(state)
{
case 0: // 等待SOF 0xA7
fifo_read_element((fifo_struct*)&command_fifo, &byte, FIFO_READ_AND_CLEAN);
if(byte == 0xA7) state = 1;
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
#define __COMMAND_H
#define COMMAND_FIFO_BUFFER_SIZE 16
#include "zf_common_typedef.h"
void command_init();
void command_task();
void command_send_angle_velocity(float* pointer_angle_velocity);
#ifndef __COMMAND_H
#define __COMMAND_H
#define COMMAND_FIFO_BUFFER_SIZE 16
#include "zf_common_typedef.h"
void command_init();
void command_task();
void command_send_angle_velocity(float* pointer_angle_velocity);
void SwitchToAutoMode();
void SwitchToManualMode();
void SwitchToDebugMode();
#endif
+3 -1
View File
@@ -46,6 +46,7 @@
#include "Beep.h"
#include "GrayscaleSensor.h"
#include "MotorEncoder.h"
#include "Command.h"
/*
定时器资源分配:
@@ -60,7 +61,7 @@ G6 20Hz任务
0 GPIOA_INT_IRQn 外部中断模拟四倍频正交编码器
1 TIMA0_INT_IRQn 100Hz任务
1 TIMA1_INT_IRQn 50Hz任务
1 UART2_INT_IRQn Command串口接收中断
2 UART2_INT_IRQn Command串口接收中断
7 TIMG6_INT_IRQn 20Hz任务
*/
int main (void)
@@ -75,6 +76,7 @@ int main (void)
imu_calibrate_gyro(); // IMU 陀螺仪零偏校准 需要在静止状态下调用
grayscale_sensor_init();//灰度传感器初始化
motor_encoder_init();//电机编码器初始化
command_init();
task_init();