无法读取UART数据:基于NXP KL27与Kinetis 1.2.0的技术求助
实现KL27 UART2读取GPS ASCII数据的完整方案
嘿,你已经完成了关键的引脚复用配置,接下来咱们一步步把UART读取的功能补全,搞定GPS数据接收:
1. 补全UART配置结构体
你给出的g_uartConfig没写完,GPS一般用8位数据位,完整配置应该是这样:
uart_user_config_t g_uartConfig = { .baudRate = 9600u, .parityMode = kUartParityDisabled, .stopBitCount = kUartOneStopBit, .bitCount = kUart8Bits, // GPS标准数据位配置 .isMsb = false // ASCII默认小端传输,保持默认即可 };
2. 初始化UART2外设
先给UART2开时钟,再调用HAL库完成初始化:
// 启用UART2的时钟(KL27的UART2时钟由SIM模块管控) SIM_HAL_EnableClock(SIM, kSimClockGateUart2); // 初始化UART2外设 UART_HAL_Init(UART2, &g_uartConfig); // 显式启用接收功能(避免默认配置异常) UART_HAL_EnableRx(UART2);
3. 选择读取方式:轮询或中断
GPS是连续输出数据的,推荐用中断方式读取(不占CPU资源),如果只是快速验证功能,轮询方式也能快速搞定。
方式一:轮询读取(快速测试用)
适合初期验证硬件连接是否正常:
#define RX_BUFFER_SIZE 128 uint8_t g_uartRxBuffer[RX_BUFFER_SIZE]; uint32_t rxIndex = 0; void UART_Polling_Read(void) { while(1) { // 检查是否有新的接收数据 if(UART_HAL_GetStatusFlag(UART2, kUartRxDataRegFull)) { // 读取一个字节到缓冲区 g_uartRxBuffer[rxIndex++] = UART_HAL_ReadDataReg(UART2); // 缓冲区满或遇到换行符(GPS NMEA语句以\r\n结尾)时处理数据 if(rxIndex >= RX_BUFFER_SIZE || g_uartRxBuffer[rxIndex-1] == '\n') { g_uartRxBuffer[rxIndex] = '\0'; // 添加字符串结束符 printf("收到GPS数据:%s", g_uartRxBuffer); rxIndex = 0; // 重置缓冲区索引 } } } }
方式二:中断读取(实际项目推荐)
避免CPU空等,适合嵌入式项目的常规用法:
步骤1:配置并启用接收中断
// 设置UART2中断优先级(根据你的项目需求调整数值,数值越小优先级越高) NVIC_SetPriority(UART2_IRQn, 2); // 启用UART2的中断通道 NVIC_EnableIRQ(UART2_IRQn); // 开启"接收数据寄存器满"中断(有新数据就触发中断) UART_HAL_SetIntMode(UART2, kUartIntRxDataRegFull, true);
步骤2:实现UART2中断服务函数
uint8_t g_uartRxByte; uint8_t g_rxBuffer[RX_BUFFER_SIZE]; uint32_t g_rxBufferIndex = 0; void UART2_IRQHandler(void) { // 确认是"接收数据寄存器满"中断触发 if(UART_HAL_GetIntStatus(UART2, kUartIntRxDataRegFull)) { // 读取接收到的字节 g_uartRxByte = UART_HAL_ReadDataReg(UART2); // 清除中断标志,避免重复触发 UART_HAL_ClearIntStatus(UART2, kUartIntRxDataRegFull); // 存储数据到缓冲区,处理换行符 g_rxBuffer[g_rxBufferIndex++] = g_uartRxByte; if(g_rxBufferIndex >= RX_BUFFER_SIZE || g_uartRxByte == '\n') { g_rxBuffer[g_rxBufferIndex] = '\0'; // 注意:中断里别做耗时操作,建议把数据放到队列,主循环再解析 // 比如可以调用一个数据处理函数,或者把数据存入环形队列 g_rxBufferIndex = 0; } } }
4. 几个关键注意事项
- 时钟配置:要确保UART2的时钟源配置正确,KL27的UART时钟来自总线时钟或OSC时钟,需要在
system_MKL27Z644.c里正确配置SIM模块的分频参数,否则波特率会不准。 - 电平匹配:KL27是3.3V器件,确认GPS的Tx输出是3.3V,如果是5V电平的GPS,必须加电平转换模块,不然会烧引脚。
- NMEA数据解析:GPS输出的是NMEA格式的ASCII字符串,比如
$GPGGA是定位核心语句,你可以在数据接收完成后,根据$开头的标识来解析经纬度、时间等有效信息。
内容的提问来源于stack exchange,提问作者CountMurphy
相关产品推荐
相关产品推荐

