You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 22:37:14