野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 296|回复: 1

STM32F407的ADC独立模式中断读取和USART串口控制RGB灯的冲突

[复制链接]
发表于 2025-4-10 11:22:44 | 显示全部楼层 |阅读模式
如题,我在学习STM32F407的ADC独立模式中断读取的课程,我基于USART串口控制RGB灯的冲突的keil工程进行ADC程序设计,实际操作后发现程序不能实时读取电压信号,需要在串口调试助手主动输入例如“1” LED变为红灯,程序检测电压信号并通过串口输出此时的电压数值

而我将while(1) 循环里的 ch=getchar(); printf("接收到字符: %c\n",ch); 以及switch(ch) 语句屏蔽后,就能实现ADC时刻检测并输出电压数值,如下图

这种情况是什么愿意造成的?能不能通过合理的设计,既能基于USART串口控制RGB灯,也能实现ADC时刻检测并输出电压数值?

main.c 程序代码见下:

#include <stdio.h>
#include "stm32f4xx.h"
#include "./rcc/bsp_clkconfig.h"
#include "./led/bsp_led.h"
#include "./key/bsp_exti.h"
#include "./systick/bsp_SysTick.h"
#include "./usart/bsp_usart.h"
#include "./adc/bsp_adc.h"

static void Show_Message(void);

// ADC转换的电压值通过MDA方式传到SRAM
__IO uint16_t ADC_ConvertedValue;

// 局部变量,用于保存转换计算后的电压值      
float ADC_Vol;

void Delay(__IO u32 nCount);

/**
  * @brief  主函数
  * @param  无
  * @retval 无
  */
int main(void)
{   
   
/* RCC Setting ********************************************************************************/   
    // MCO GPIO  初始化
  MCO1_GPIO_Config();
  MCO2_GPIO_Config();   
  
  // MCO1 输出PLLCLK   
  RCC_MCO1Config(RCC_MCO1Source_PLLCLK, RCC_MCO1Div_1);
   
    // MCO2 输出SYSCLK
    RCC_MCO2Config(RCC_MCO2Source_SYSCLK, RCC_MCO1Div_1);
    // 程序来到main函数之前,启动文件:statup_stm32f4xx.s已经调用
    // SystemInit()函数把系统时钟初始化成72MHZ
    // SystemInit()在system_stm32f4xx.c中定义
    // 如果用户想修改系统时钟,可自行编写程序修改   
    // 重新设置系统时钟,这时候可以选择使用HSE还是HSI
   
    /*  注意 :由于在 PLL 使能后主 PLL 配置参数便不可更改,而系统上电后会
     *  自动进行初始化,因此在对HES重新初始化之前,需要将system_stm32f4xx.c      
     *  中的line514:SetSysClock();注释掉,否则HSE重新初始化之后不生效。
     */
   
    // 使用HSE,配置系统时钟为168M
    HSE_SetSysClock(25, 336, 2, 7);
   
    //系统时钟超频到216M爽一下,最高是216M,别往死里整
  //HSE_SetSysClock(25, 432, 2, 9);
   
    // 使用HSI,配置系统时钟为168M
    //HSI_SetSysClock(16, 336, 2, 7);

    // LED 端口初始化
    LED_GPIO_Config();
   
    // SysTick初始化
    SysTick_Init();
/********************************************************************************* RCC Setting */   


/* USART Setting ********************************************************************************/   
    /* 初始化 USART 配置模式为 115200 8-N-1,中断接收 */
    Debug_USART_Config();
    //Usart_SendByte( DEBUG_USART, 'A');
    //Usart_SendString( DEBUG_USART, "野火STM32F407串口实验\n");
    //printf("This is a serial port interrupt acceptance readback experiment\n");
   
    /* 打印指令输入提示信息 */
    Show_Message();
   
    char ch;
/********************************************************************************* USART Setting */   


/* ADC Setting ********************************************************************************/   
    // ADC Initialization
    Rheostat_Init();
/******************************************************************************** ADC Setting */   

    while (1)
    {
         /* 获取字符指令 */
    ch=getchar();
    printf("接收到字符:%c\n",ch);
        
        /* 根据字符指令控制RGB彩灯颜色 */
    switch(ch)
    {
      case '1':
        LED_RED;
      break;
      case '2':
        LED_GREEN;
      break;
      case '3':
        LED_BLUE;
      break;
      case '4':
        LED_YELLOW;
      break;
      case '5':
        LED_PURPLE;
      break;
      case '6':
        LED_CYAN;
      break;
      case '7':
        LED_WHITE;
      break;
      case '8':
        LED_RGBOFF;
      break;
      default:
        /* 如果不是指定指令字符,打印提示信息 */
        Show_Message();
        break;  
        }
        
        ADC_Vol =(float) ADC_ConvertedValue/4096*(float)3.3; // 读取转换的AD值

    printf("\r\n The current AD value = 0x%04X \r\n", ADC_ConvertedValue);
    printf("\r\n The current AD value = %f V \r\n",ADC_Vol);   
        
    Delay(0xffffee);
        LED_RED;
        Delay(0xffffee);
        LED_CYAN;

    }
}

/**
  * @brief  简单的延时函数
  * @param  无
  * @retval 无
  */
void Delay(__IO uint32_t nCount)     
{
    for(; nCount != 0; nCount--);
}

/**
  * @brief  打印指令输入提示信息
  * @param  无
  * @retval 无
  */
static void Show_Message(void)
{
  printf("\r\n   这是一个通过串口通信指令控制RGB彩灯实验 \n");
  printf("使用  USART1  参数为:%d 8-N-1 \n",DEBUG_USART_BAUDRATE);
  printf("开发板接到指令后控制RGB彩灯颜色,指令对应如下:\n");
  printf("   指令   ------ 彩灯颜色 \n");
  printf("     1    ------    红 \n");
  printf("     2    ------    绿 \n");
  printf("     3    ------    蓝 \n");
  printf("     4    ------    黄 \n");
  printf("     5    ------    紫 \n");
  printf("     6    ------    青 \n");
  printf("     7    ------    白 \n");
  printf("     8    ------    灭 \n");  
}

/*********************************************END OF FILE**********************/


野火论坛202504101120462670..png
回复

使用道具 举报

发表于 2025-4-11 17:07:49 | 显示全部楼层
ch=getchar(); 是读取串口输入字符函数,因为没有输入,所以软件一直在这里等待输入,你去掉或是输入字符自然软件能正常执行,
规避方法也有很多,你可以打开UART输入中断,借助中断来判断是否收到UART输入,无输入则跳过此步.
也可以自己改写getchar()函数加入一个参数时间,作为最大处理时间,时间超过则退出这个函数,也可以实现现在这个功能
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2025-4-22 02:19 , Processed in 0.127504 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表