RT-Thread论坛
直播中

胡秋阳

14年用户 1664经验值
私信 关注
[问答]

f103c8t6使用adc采样时程序无法正常工作怎么解决?

我在学习使用STM32f103c8t6的adc的使用时遇到了这个问题。
是按照教程一步一步操作的:这是教程地址:https://blog.csdn.net/WTF___000/article/details/129649963
但是我复现以后,出现的问题是有一个startup 的警告,另外就是下载到单片机运行时无法正常进行。
不同的点是教程使用的板子和我的不同
这是报错内容

这是运行以后串口终端的显示内容

回帖(1)

温暖镜头

2025-10-20 18:21:00

针对您在STM32F103C8T6上使用ADC时程序无法正常运行的问题,结合startup警告和串口输出异常,以下是系统的解决方案:


核心问题分析



  1. 启动文件警告:STM32F103C8T6属于中等容量(Medium Density)设备,若使用HD(High Density)或CL(Connectivity Line)启动文件会导致硬件不匹配。

  2. ADC配置问题:时钟分频、采样时间、校准流程错误会导致ADC无法工作。

  3. 串口无输出:系统崩溃或阻塞导致串口无法输出调试信息。




解决方案


1. 修复启动文件(关键步骤)



  • 正确启动文件:使用 startup_stm32f10x_md.s(MD = Medium Density)

  • 操作步骤

    1. 移除现有启动文件(如 startup_stm32f10x_hd.s

    2. 添加MD启动文件路径:STM32F10x_StdPeriph_Lib_V3.5.0LibrariesCMSISCM3DeviceSupportSTSTM32F10xstartuparm

    3. KEIL工程配置:

      • 启用 STM32F10X_MD 宏定义(Options for Target → C/C++ → Preprocessor Symbols)
        KEIL宏定义设置




2. ADC关键配置修复


// ADC初始化修正代码
void ADC1_Init(void) {
  GPIO_InitTypeDef GPIO_InitStructure;
  ADC_InitTypeDef ADC_InitStructure;

  // 1. 时钟配置
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE);
  RCC_ADCCLKConfig(RCC_PCLK2_Div6); // 72MHz/6=12MHz (<14MHz上限)

  // 2. GPIO配置(PA1为ADC输入)
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; // 模拟输入模式
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  // 3. ADC参数配置
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;    // 单通道禁用扫描
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;// 连续转换
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 1;
  ADC_Init(ADC1, &ADC_InitStructure);

  // 4. 通道采样时间配置(关键!)
  ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5);

  // 5. 校准流程(必须执行)
  ADC_Cmd(ADC1, ENABLE);
  ADC_ResetCalibration(ADC1);
  while(ADC_GetResetCalibrationStatus(ADC1));
  ADC_StartCalibration(ADC1);
  while(ADC_GetCalibrationStatus(ADC1));

  // 6. 启动转换
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}

3. 串口调试修复


// 确保串口初始化正确(USART1示例)
void USART1_Init(uint32_t baudrate) {
  GPIO_InitTypeDef GPIO_InitStruct;
  USART_InitTypeDef USART_InitStruct;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);

  // TX (PA9)
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStruct);

  // RX (PA10)
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStruct);

  USART_InitStruct.USART_BaudRate = baudrate;
  USART_InitStruct.USART_WordLength = USART_WordLength_8b;
  USART_InitStruct.USART_StopBits = USART_StopBits_1;
  USART_InitStruct.USART_Parity = USART_Parity_No;
  USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
  USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_Init(USART1, &USART_InitStruct);

  USART_Cmd(USART1, ENABLE);
}

// 重定向printf
int fputc(int ch, FILE *f) {
  USART_SendData(USART1, (uint8_t)ch);
  while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
  return ch;
}

4. 主函数逻辑优化


int main(void) {
  uint16_t adc_value;

  // 初始化顺序很重要!
  SystemInit(); // 系统时钟初始化(默认72MHz)
  USART1_Init(115200);
  ADC1_Init();

  printf("System Startedrn"); // 测试串口

  while(1) {
    if(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)) {
      adc_value = ADC_GetConversionValue(ADC1);
      printf("ADC: %drn", adc_value); // 打印采样值
      ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
    }
    Delay_ms(100); // 简单延时
  }
}



调试技巧




  1. 最小系统测试



    • 暂时注释ADC代码,只保留串口输出"Hello World",验证基础系统

    • 用万用表测量PA1引脚电压(0~3.3V)








































  2. 常见错误排查表 现象 可能原因 解决措施
    程序完全不运行 启动文件错误 替换为MD启动文件
    ADC返回值始终为0 GPIO未配置为模拟模式 检查GPIO_Mode_AIN
    ADC值固定为4095 输入电压超过3.3V 检查传感器供电
    采样值跳动剧烈 未执行校准 添加ADC校准流程
    串口输出乱码 波特率不匹配 核对终端和代码波特率设置



  3. 硬件检查



    • 确保BOOT0引脚接地(正常启动模式)

    • 检查NRST复位电路(10K电阻+104电容)

    • ADC输入电压范围:0~3.3V(严禁超过)





经过上述修正后,90%以上的ADC异常问题可解决。如果仍有问题,建议使用ST-Link单步调试,观察ADC寄存器状态(特别是ADC_CR2和ADC_SR寄存器)。


举报

更多回帖

发帖
×
20
完善资料,
赚取积分