CubeIDE下STM32F4-Discovery UART中断计算器无响应问题求助
STM32F4 UART中断计算器无响应问题修复
问题描述
我是CubeIDE新手,基于STM32F4-Discovery开发板开发UART中断模式的计算器项目,项目代码如下:
#include "main.h" #include <stdio.h> #include <string.h> #include <math.h> uint8_t gelendata[4]; void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){ HAL_UART_Receive_IT(huart, gelendata, 1); } #define TOPLAMA 1 #define CIKARMA 2 UART_HandleTypeDef huart2; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART2_UART_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART2_UART_Init(); uint8_t state = 0; uint8_t data[] = "lutfen islem seciniz.\n"; uint8_t data1[] = "1.toplama\n"; uint8_t data2[]= "2.cikarma\n "; uint8_t islem = 0; uint16_t birincisayi = 0; uint16_t ikincisayi = 0; uint16_t sonuc[1]; while (1) { if(state == 0) { HAL_UART_Transmit(&huart2, data, sizeof(data), 1000); HAL_Delay(300); HAL_UART_Transmit(&huart2, data1, sizeof(data1), 1000); HAL_Delay(300); HAL_UART_Transmit(&huart2, data2, sizeof(data2), 1000); HAL_Delay(300); state = 1; } if(state == 1 && gelendata[0] != 0) { if(gelendata[0] == 1) { *data = "toplama islemi icin birinci sayiyi giriniz.\n"; HAL_UART_Transmit(&huart2, data, sizeof(data), 1000); state = 2; gelendata[0] =0; islem = TOPLAMA; } if(gelendata[0] == 2) { *data = "cikarma islemi icin birinci sayiyi giriniz.\n"; HAL_UART_Transmit(&huart2, data, sizeof(data), 1000); state = 2; gelendata[0] =0; islem = CIKARMA; } } if(state == 2 && gelendata[0] != 0) { if(gelendata[0] == 2) { *data = "ikinci sayiyi giriniz.\n"; HAL_UART_Transmit(&huart2, data, sizeof(data), 1000); state = 3; birincisayi = gelendata[0]; gelendata[0] =0; } } if(state == 3 && gelendata[0] != 0) { ikincisayi = gelendata[0]; if(islem == TOPLAMA) { sonuc[0] = birincisayi + ikincisayi; HAL_UART_Transmit(&huart2, sonuc, sizeof(sonuc), 1000); } if(islem == CIKARMA) { sonuc[0] = birincisayi - ikincisayi; HAL_UART_Transmit(&huart2, sonuc, sizeof(sonuc), 1000); } } } }
目前终端仅能显示初始提示信息:lutfen islem seciniz.、1.toplama、2.cikarma,但输入1或2后无任何后续响应。
修复步骤
1. 开启首次UART中断接收
初始化后没有启动第一个中断接收任务,导致gelendata永远无法获取输入。在MX_USART2_UART_Init()之后添加:
HAL_UART_Receive_IT(&huart2, gelendata, 1);
2. 修正ASCII字符判断逻辑
终端输入的数字是ASCII字符('1'对应0x31,'2'对应0x32),代码里直接判断数值1/2完全错误,要改成字符判断:
// 状态1的判断修改为 if(gelendata[0] == '1') // 和 if(gelendata[0] == '2')
3. 修复字符串赋值错误
代码中*data = "字符串"的写法是非法的,会覆盖数组指针地址导致内存错误。可以将data改为指针类型:
// 替换原来的uint8_t data[] = "xxx"; uint8_t *data = "lutfen islem seciniz.\n";
之后直接赋值字符串即可:
data = "toplama islemi icin birinci sayiyi giriniz.\n";
4. 修正状态2的逻辑错误
状态2的作用是接收第一个运算数字,当前代码错误地判断输入等于2才切换状态,应该直接将输入字符转为数值并切换状态:
if(state == 2 && gelendata[0] != 0) { birincisayi = gelendata[0] - '0'; // ASCII字符转数值 data = "ikinci sayiyi giriniz.\n"; HAL_UART_Transmit(&huart2, (uint8_t*)data, strlen((char*)data), 1000); state = 3; gelendata[0] = 0; }
5. 修复结果输出逻辑
直接发送数值sonuc会输出ASCII控制字符,需要先将数值转为字符串再发送:
// 替换原来的结果发送代码 char sonuc_str[10]; if(islem == TOPLAMA) { sprintf(sonuc_str, "%d\n", birincisayi + ikincisayi); HAL_UART_Transmit(&huart2, (uint8_t*)sonuc_str, strlen(sonuc_str), 1000); } if(islem == CIKARMA) { sprintf(sonuc_str, "%d\n", birincisayi - ikincisayi); HAL_UART_Transmit(&huart2, (uint8_t*)sonuc_str, strlen(sonuc_str), 1000); }
内容的提问来源于stack exchange,提问作者Łemma
相关产品推荐
相关产品推荐

