串口接收十六进制
时间: 2025-04-07 12:11:47 浏览: 33
### 串口接收十六进制数据的方法
在嵌入式开发中,通过串口接收十六进制数据是一种常见的需求。无论是使用 Arduino 还是 STM32 或者其他平台,都需要理解串口通信的基础以及如何处理接收到的数据。
#### 数据传输基础
当提到“十六进制数据”时,实际上是指二进制流中的每一位被表示为两位十六进制数(0-F)。如果未启用硬件或软件层面的特殊设置,默认情况下串口会以 ASCII 字符形式传递这些数值[^1]。这意味着发送方可能将 `FF` 转化成字符串 `"FF"` 发送出去,在这种场景下接收端需要解析该字符串并将其还原回原始字节数值。
对于某些微控制器环境而言,可以配置其UART模块支持直接操作实际字节而非ASCII编码后的版本;比如Arduino Nano上的Serial类提供了readBytes()方法可以直接读取未经任何转化过的raw bytes[]数组。
#### 实现方式
以下是基于不同框架下的具体实现:
##### 使用Arduino进行十六进制数据接收
下面给出了一段简单的Arduino代码用于演示如何从标准输入获取一系列十六进制字符并将它们解释成为相应的byte值:
```cpp
void setup(){
Serial.begin(9600);
}
unsigned char hexCharToByte(char c){
if(c >= '0' && c <= '9') return (c-'0');
else if(c >= 'A'&& c<='F')return ((c-'A')+10);
else if(c>='a'&&c<='f')return((c-'a')+10);
else return 0;
}
int main(){
while(Serial.available()){
String str=Serial.readStringUntil('\n'); // 假设每组数据后面都有换行符分隔开来的约定
int length=str.length()/2; // 计算有效字节数量
unsigned char buffer[length];
for(int i=0;i<length*2;i+=2){
buffer[i/2]=hexCharToByte(str.charAt(i))*16+hexCharToByte(str.charAt(i+1));
}
/* 对buffer做进一步处理 */
}
}
```
上述程序片段展示了怎样把来自PC或者其他设备传过来的一连串代表HEX码的文字转换成本地内存里的BYTE序列。
##### 利用STM32CubeMX生成项目并通过HAL库函数完成类似功能
假设我们已经在STM32CubeMX里完成了基本外设初始化工作,则可以在应用层编写如下逻辑来达成目标效果:
```c
uint8_t UART_RX_BUF[128];
while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_RXNE)){
uint8_t temp=__HAL_UART_RECEIVE_IT(&huart1,(uint8_t*)&temp,1);
if(temp=='\r'||temp=='\n'){
ProcessHexData(UART_RX_BUF);
memset(UART_RX_BUF,'\0',sizeof(UART_RX_BUF));
}else{
strcat((char*)UART_RX_BUF,&temp);
}
}
// 处理已收集到的全部字符组成的字符串
void ProcessHexData(uint8_t *pData){
uint16_t resultValue=(hexCharToDec(*pData)*16)+hexCharToDec(*(pData+1));
printf("%d\n",resultValue);
}
uint8_t hexCharToDec(uint8_t ch){
if(ch >= '0' && ch <= '9') return (ch - '0');
else if(ch >= 'A' && ch <= 'F') return (ch - 'A'+10);
else if(ch >= 'a' && ch <= 'f') return (ch - 'a'+10);
else return 0;
}
```
这里采用中断驱动模式不断累积新到达的信息直到遇到特定终止标志为止才调用专门负责解码工作的子过程去分析整个缓冲区的内容[^2]。
#### C++环境下借助第三方库简化流程
假如是在桌面应用程序或者服务器后台运行的服务进程当中需要用到类似的机制,那么可以选择一些成熟的跨平台解决方案如Boost.Asio等工具包辅助构建网络服务端点的同时也能够轻松应对本地TTY连接管理任务。例如:
```cpp
#include<boost/array.hpp>
#include<boost/asio.hpp>
using namespace boost::asio;
io_service io;
serial_port port(io,"COM3");
std::array<unsigned char ,256> buf;
size_t len =port.read_some(buffer(buf));
for(auto &b:buf){
std::cout<<std::uppercase<<std::setfill('0')<<std::setw(2)<<std::hex<<(int)b<<"\t";
}
std::cout<<std::endl;
```
这段示范利用了boost.asio提供的便利接口快速实现了同步阻塞式的单次批量抓取消息的功能,并且自动按照指定宽度打印出了对应的十六进制表现形式[^3]。
### 注意事项
无论采取哪种途径都需要注意几个要点:
- 确认波特率一致;
- 设置好奇偶校验位参数;
- 正确区分大小写敏感度高的字母表项;
- 预留足够的存储空间容纳最大预期长度的消息体。
阅读全文
相关推荐


















