1. SmartFusion2 UART通信实现指南
在嵌入式系统开发中,UART通信是最基础也最常用的外设接口之一。作为Microsemi(现为Microchip)推出的混合信号FPGA,SmartFusion2系列器件集成了ARM Cortex-M3硬核处理器和可编程逻辑资源,其UART控制器功能完善但配置过程对新手来说仍存在不少坑点。本文将基于实际项目经验,详细解析SmartFusion2 UART通信的实现方法、关键参数配置和典型问题解决方案。
2. 硬件设计与接口连接
2.1 SmartFusion2 UART硬件特性
SmartFusion2器件内部包含最多4个UART控制器(具体数量取决于器件型号),每个控制器具有以下硬件特性:
- 全双工异步通信
- 可编程波特率(最高支持3Mbps)
- 5-9位数据位长度可选
- 1或2位停止位
- 可配置的奇偶校验(奇校验/偶校验/无校验)
- 独立的发送和接收FIFO(深度16字节)
- 支持DMA传输
2.2 典型硬件连接方案
以开发板连接PC为例,常见硬件连接方式有两种:
方案一:通过板载FTDI芯片转换
code复制SmartFusion2 UART TX ---- FTDI芯片 RX
SmartFusion2 UART RX ---- FTDI芯片 TX
FTDI芯片 USB接口 ---- PC USB端口
注意:使用此方案时,开发板通常已集成电平转换电路,无需额外处理3.3V与5V电平转换问题
方案二:直接连接USB-UART转换器
code复制SmartFusion2 UART TX ---- CP2102模块 RX
SmartFusion2 UART RX ---- CP2102模块 TX
CP2102模块 USB接口 ---- PC USB端口
关键细节:必须确保两端共地,连接GND线缆
3. 软件环境配置
3.1 Libero开发环境设置
- 创建新项目时选择正确的器件型号(如M2S010)
- 在"Design Flow"选项卡中勾选"SoftConsole"选项
- 完成FPGA设计后,通过"Export Hardware"生成硬件描述文件
3.2 驱动安装与验证
对于常见的USB-UART转换芯片,需要安装对应驱动:
- FTDI系列(FT232R/FT231X):从官网获取最新驱动
- CP210x系列:Silicon Labs提供通用驱动
- CH340:需单独安装驱动
验证驱动是否安装成功:
- 连接设备到PC
- 打开设备管理器
- 查看"端口(COM和LPT)"项中是否出现新设备
- 记录分配的COM端口号(如COM3)
4. UART控制器配置详解
4.1 使用MSS Configurator配置UART
在Libero环境中通过以下步骤配置UART外设:
- 打开"MSS Configurator"工具
- 在"Peripherals"选项卡中选择UART0/1/2/3
- 关键参数配置:
- Baud rate:115200(常用值)
- Data bits:8
- Parity:None
- Stop bits:1
- FIFO:Enable
- 生成配置代码
4.2 寄存器级配置详解
对于需要精细控制的场景,可直接操作寄存器:
c复制// 波特率设置示例(系统时钟100MHz,目标波特率115200)
#define BAUD_RATE 115200
#define SYS_CLK 100000000
void UART_Init(void) {
// 关闭UART使能
MSS_UART_disable(&g_mss_uart0);
// 计算分频值
uint32_t divisor = SYS_CLK / (16 * BAUD_RATE);
MSS_UART_init(&g_mss_uart0,
BAUD_RATE,
MSS_UART_DATA_8_BITS,
MSS_UART_NO_PARITY,
MSS_UART_ONE_STOP_BIT);
// 使能FIFO
g_mss_uart0.hw_reg->UART_IFLS = 0x12; // 设置FIFO触发阈值
g_mss_uart0.hw_reg->UART_LCR_H |= 0x10; // 使能FIFO
// 重新使能UART
MSS_UART_enable(&g_mss_uart0);
}
5. 通信协议实现
5.1 基础数据收发
c复制// 发送单个字符
void UART_SendChar(char c) {
while(MSS_UART_tx_full(&g_mss_uart0)); // 等待发送缓冲区空闲
MSS_UART_polled_tx(&g_mss_uart0, c);
}
// 发送字符串
void UART_SendString(const char *str) {
while(*str) {
UART_SendChar(*str++);
}
}
// 接收处理(轮询方式)
char UART_GetChar(void) {
if(MSS_UART_rx_ready(&g_mss_uart0)) {
return MSS_UART_get_rx(&g_mss_uart0);
}
return 0;
}
5.2 中断驱动实现
- 配置中断控制器:
c复制void UART_Int_Init(void) {
// 初始化UART
MSS_UART_init(&g_mss_uart0, ...);
// 使能接收中断
MSS_UART_set_rx_handler(&g_mss_uart0,
UART_Rx_Handler,
MSS_UART_FIFO_SINGLE_BYTE);
// 配置NVIC
NVIC_EnableIRQ(UART0_IRQn);
NVIC_SetPriority(UART0_IRQn, 1);
}
- 实现中断服务例程:
c复制void UART0_IRQHandler(void) {
MSS_UART_irq_handler(&g_mss_uart0);
}
void UART_Rx_Handler(mss_uart_instance_t *this_uart) {
uint8_t data = MSS_UART_get_rx(this_uart);
// 处理接收数据
ProcessRxData(data);
}
6. 调试技巧与常见问题
6.1 典型问题排查表
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 无数据收发 | 线缆连接错误 | 检查TX-RX交叉连接 |
| 乱码 | 波特率不匹配 | 核对两端波特率设置 |
| 数据丢失 | 未处理流控 | 启用硬件流控或降低波特率 |
| 只能单次收发 | 未清除状态标志 | 检查并清除错误标志位 |
| 中断不触发 | NVIC未配置 | 检查中断优先级和使能设置 |
6.2 逻辑分析仪调试技巧
-
连接信号线:
- 通道1:UART TX
- 通道2:UART RX
- 共地连接
-
设置解码参数:
- 协议类型:UART
- 波特率:与代码设置一致
- 数据位:8
- 停止位:1
- 校验位:None
-
典型波形分析:
- 起始位:低电平
- 数据位:LSB先发送
- 停止位:高电平
经验:当通信异常时,首先用逻辑分析仪捕获实际波形,确认物理层信号是否符合预期
7. 性能优化进阶
7.1 DMA传输配置
c复制void UART_DMA_Init(void) {
// 配置DMA控制器
DMAC_init(MSS_DMA_BASE);
// 设置UART发送DMA
MSS_UART_set_tx_dma_handler(&g_mss_uart0,
UART_Tx_DMA_Handler,
MSS_UART_DMA_BYTE);
// 配置DMA通道
mss_dma_channel_config_t tx_config;
tx_config.src_addr = (uint32_t)send_buffer;
tx_config.dest_addr = (uint32_t)&g_mss_uart0.hw_reg->UART_DR;
tx_config.transfer_size = BUFFER_SIZE;
// ...其他DMA参数配置
MSS_DMA_set_transfer_size(MSS_DMA_CHANNEL_0, BUFFER_SIZE);
MSS_DMA_start(MSS_DMA_CHANNEL_0);
}
7.2 波特率误差计算
SmartFusion2 UART波特率计算公式:
[
\text{BRD} = \frac{\text{SYS_CLK}}{16 \times \text{BAUD_RATE}}
]
实际波特率误差:
[
\text{Error} = \left| \frac{\text{Actual} - \text{Desired}}{\text{Desired}} \right| \times 100%
]
关键指标:误差应小于2%(RS-232标准要求),当系统时钟为100MHz、目标波特率115200时,实际误差约0.16%
8. 项目实战:构建可靠通信协议
8.1 帧结构设计
典型通信帧格式:
code复制[Header][Length][Data][CRC][Footer]
- Header:0xAA(1字节)
- Length:数据长度(1字节)
- Data:有效载荷(N字节)
- CRC:CRC8校验(1字节)
- Footer:0x55(1字节)
8.2 状态机实现
c复制typedef enum {
STATE_IDLE,
STATE_HEADER,
STATE_LENGTH,
STATE_DATA,
STATE_CRC,
STATE_FOOTER
} uart_state_t;
void UART_Protocol_Handler(uint8_t data) {
static uart_state_t state = STATE_IDLE;
static uint8_t length = 0;
static uint8_t counter = 0;
static uint8_t buffer[MAX_FRAME];
static uint8_t crc = 0;
switch(state) {
case STATE_IDLE:
if(data == 0xAA) {
state = STATE_HEADER;
crc = CRC8_Init();
}
break;
// ...其他状态处理
case STATE_FOOTER:
if(data == 0x55) {
if(crc == 0) {
ProcessFrame(buffer, length);
}
}
state = STATE_IDLE;
break;
}
}
9. 跨平台通信测试
9.1 PC端测试工具配置
推荐使用以下工具进行测试:
- Tera Term(Windows)
- minicom(Linux)
- CoolTerm(Mac)
关键配置参数:
- 波特率:与设备端一致
- 数据位:8
- 停止位:1
- 校验位:None
- 流控:None
9.2 自动化测试脚本示例(Python)
python复制import serial
import time
def uart_test():
ser = serial.Serial(
port='COM3',
baudrate=115200,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=1
)
# 发送测试数据
test_data = b"SmartFusion2 UART Test\n"
ser.write(test_data)
# 接收回显
response = ser.readline()
print("Received:", response.decode())
ser.close()
if __name__ == "__main__":
uart_test()
10. 低功耗设计考量
10.1 睡眠模式下的UART唤醒
- 配置UART唤醒中断:
c复制MSS_UART_enable_wakeup(&g_mss_uart0);
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
- 进入低功耗模式:
c复制__WFI(); // 等待中断唤醒
10.2 动态波特率调整
根据通信需求动态调整波特率以降低功耗:
c复制void UART_Set_Low_Speed(void) {
MSS_UART_disable(&g_mss_uart0);
MSS_UART_init(&g_mss_uart0, 9600, ...);
MSS_UART_enable(&g_mss_uart0);
}
void UART_Set_High_Speed(void) {
MSS_UART_disable(&g_mss_uart0);
MSS_UART_init(&g_mss_uart0, 115200, ...);
MSS_UART_enable(&g_mss_uart0);
}
在实际项目中,UART通信的稳定性往往取决于细节处理。我在多个SmartFusion2项目中发现,当通信距离超过1米时,添加RS-232电平转换芯片能显著提高抗干扰能力。另外,对于关键数据传输,建议实现应用层应答机制,确保数据完整性和可靠性。
