STM32与Arduino串口通信问题:ADC值接收结果不符求助
解决STM32通过UART发送ADC值到Arduino的接收异常问题
问题背景
STM32端通过UART发送ADC值的代码如下:
sprintf(data,"\f ADC1= %d ADC2= %d \r\n",adcData[0],adcData[1]);//calisiyor HAL_UART_Transmit(&huart2,(uint8_t*)data,strlen(data),1000); //calisiyor HAL_Delay(500);
该数据在Tera Term中可正常显示ADC数值,但Arduino使用以下接收代码时,结果与发送值不符:
incomingByte = Serial.read(); // read the incoming byte: String myString = String(incomingByte); Serial.print(" I received:"); Serial.println(myString);
问题原因
STM32发送的是完整的字符串行(包含前缀、ADC数值、换行符),而当前Arduino代码仅单次读取一个字节,并且将字节的ASCII码值直接转为字符串,而非读取完整的一行数据并解析其中的数字,因此无法正确获取ADC数值。
解决方案
1. 确保UART参数一致
确认STM32和Arduino的UART配置完全匹配:
- 波特率(如9600、115200)
- 数据位(通常8位)
- 停止位(通常1位)
- 奇偶校验(通常无)
2. 修改Arduino接收代码,读取完整行并解析
以下是两种可行的实现方式:
方式一:使用readStringUntil读取整行并解析
void setup() { Serial.begin(9600); // 匹配STM32的波特率 } void loop() { if (Serial.available() > 0) { // 读取直到换行符的整行数据 String receivedLine = Serial.readStringUntil('\n'); // 清理掉回车符和换页符 receivedLine.trim(); // 解析ADC1的值:找到"ADC1="的位置,截取后续数字 int adc1Start = receivedLine.indexOf("ADC1=") + 5; int adc1End = receivedLine.indexOf(" ", adc1Start); int adc1Value = receivedLine.substring(adc1Start, adc1End).toInt(); // 解析ADC2的值:找到"ADC2="的位置,截取后续数字 int adc2Start = receivedLine.indexOf("ADC2=") + 5; int adc2End = receivedLine.indexOf(" ", adc2Start); int adc2Value = receivedLine.substring(adc2Start, adc2End).toInt(); // 输出解析后的结果 Serial.print("ADC1: "); Serial.print(adc1Value); Serial.print(" | ADC2: "); Serial.println(adc2Value); } }
方式二:逐字节读取拼接字符串(适合内存有限的情况)
void setup() { Serial.begin(9600); } void loop() { static String receivedBuffer = ""; while (Serial.available() > 0) { char c = Serial.read(); if (c == '\n') { // 遇到换行符表示一行结束 // 解析逻辑同方式一 int adc1Start = receivedBuffer.indexOf("ADC1=") + 5; int adc1End = receivedBuffer.indexOf(" ", adc1Start); int adc1Value = receivedBuffer.substring(adc1Start, adc1End).toInt(); int adc2Start = receivedBuffer.indexOf("ADC2=") + 5; int adc2End = receivedBuffer.indexOf(" ", adc2Start); int adc2Value = receivedBuffer.substring(adc2Start, adc2End).toInt(); Serial.print("ADC1: "); Serial.print(adc1Value); Serial.print(" | ADC2: "); Serial.println(adc2Value); receivedBuffer = ""; // 清空缓冲区准备下一行 } else { receivedBuffer += c; // 逐字节拼接字符串 } } }
说明
- 两种方式都能完整接收STM32发送的一行数据,并通过字符串截取提取ADC数值。
- 如果发送的字符串格式有变化(比如去掉换页符
\f),只需调整解析时的索引位置即可。
内容的提问来源于stack exchange,提问作者MrElectronicEngineer
相关产品推荐
相关产品推荐

