[应用相关] 基于STM32F030的ADC功能实现

[复制链接]
2344|7
 楼主| 梅花香自123 发表于 2021-3-22 23:33 | 显示全部楼层 |阅读模式
在网上看到的关于stm32的adc功能的例程,大多数是stmf103的,基于stm32f030的相当少。而我就是用stm32f030,在开发过程中,颇为遇到一些坑,所以总结一下。

本文关于ADC的内容,分为下面几部分:

1,ADC的初始化;
2,读取ADC值;
3,ADC值的解析;

先简单介绍下开发环境,芯片类型是stm32F030C8,集成开发环境用的是Keil5 MDK-ARM,仿真器使用JLINK。
————————————————

 楼主| 梅花香自123 发表于 2021-3-22 23:36 | 显示全部楼层
一,ADC的初始化
ADC设置的一般步骤如下:
1、时钟配置,包括ADC时钟与GPIO时钟;
2、GPIO设置;
3、ADC参数配置;
4、中断的配置(若有必要就配置,本文未涉及)。

为了比较好对比读取数据的变化,我在这个函数中,考虑到了3种ADC数据源:
内部温度传感器,通道号为 ADC_Channel_16 
内部参考电压,通道号为 ADC_Channel_17
一个gpio输入,PA5,通道号为 ADC_Channel_5
只需要在 ADC_ChannelConfig() 中指定好相应的ADC通道号即可。
内部温度传感器与内部参考电压,每个stm32芯片都支持,方便测试运行。
而对于gpio输出,就需要有相应的硬件支持了。否则,读取的值不知道意义。
 楼主| 梅花香自123 发表于 2021-3-22 23:36 | 显示全部楼层
ADC初始化的代码如下:
  1. void initADC(void)
  2. {
  3.     
  4.     GPIO_InitTypeDef GPIO_InitStructure;
  5.     ADC_InitTypeDef ADC_InitStructure;

  6.     uint32_t adc_clk = RCC_ADCCLK_PCLK_Div4; 

  7.     log("initADC: to GPIO_Configuration\n");

  8.     
  9.     /* Config System clocks, GPIO ports -----------------------------------------------------*/
  10.     RCC_ADCCLKConfig(adc_clk);//配置ADC的时钟频率

  11.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
  12.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
  13.         
  14.     GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;         
  15.     GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AN;
  16.     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;//
  17.     GPIO_Init(GPIOA,&GPIO_InitStructure);

  18.             
  19.     /* Config ADC1 --------------------------------------------------------------*/
  20.     ADC_DeInit(ADC1);
  21.     ADC_InitStructure.ADC_Resolution = ADC_Resolution_8b;//ADC_Resolution_12b
  22.     ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//不开启连续转换模式 
  23.     ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; //不使用外部触发转换  
  24.     ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //采集数据右对齐 
  25.     ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward; //扫描方向
  26.     ADC_Init(ADC1, &ADC_InitStructure);
  27.         

  28.     ADC_TempSensorCmd(ENABLE);//使能内部温度传感器
  29.     ADC_VrefintCmd(ENABLE);     //使能内部参考电压   

  30.     //按 频率=8/1/4=2M 来计算,t=(71.5+12.5)/2M=42us

  31. //    ADC_ChannelConfig(ADC1, ADC_Channel_16, ADC_SampleTime_71_5Cycles);//内部温度传感器
  32.     ADC_ChannelConfig(ADC1, ADC_Channel_17, ADC_SampleTime_71_5Cycles);//内部参考电压        
  33. //    ADC_ChannelConfig(ADC1, ADC_Channel_5, ADC_SampleTime_71_5Cycles);//配置ADC1通道5的采样周期   PA5

  34.         
  35.     ADC_GetCalibrationFactor(ADC1);//Active the Calibration operation   返回校准因子  //The Calibration can be initiated only when ADC is still in the reset configuration (ADEN must be equal to 0).
  36.         
  37.     ADC_Cmd(ADC1,ENABLE);//ADEN set to 1
  38.      
  39.     while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN));    

  40. }
 楼主| 梅花香自123 发表于 2021-3-22 23:37 | 显示全部楼层
二,读取ADC值
本例程采用的是手动启动ADC,然后等待ADC转换完成,然后读取ADC值。

具体代码如下:
  1. void startADC(void)
  2. {
  3.     uint16_t ADC_ConvertedValue=0;
  4.     
  5.     ADC_StartOfConversion(ADC1);
  6.             
  7.     while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)!=1){} //等待ADC转换完成
  8.     
  9.     ADC_ConvertedValue = ADC_GetConversionValue(ADC1);
  10.         
  11.     log("ADC_ConvertedValue=%d\r\n",ADC_ConvertedValue);
  12.     
  13.     ADC_StopOfConversion(ADC1);
  14.     
  15. }

评论

由于是一个demo例程,这里只关心了如何读取到值,具体这个值的意义,就需要另外来分析了。  发表于 2021-3-22 23:38
 楼主| 梅花香自123 发表于 2021-3-22 23:38 | 显示全部楼层
三,ADC值的解析
这里分析了3种值得解析:
1,内部温度传感器,通道号为 ADC_Channel_16 
由于我对精度并没有很高的期望,所以配置为8位精度,ADC_Resolution_8b
取值范围:0-255
利用下列公式得出温度
温度(°C) = {(V25 - VSENSE) / Avg_Slope} + 25
这里:
V25 = VSENSE在25°C时的数值
Avg_Slope = 温度与VSENSE曲线的平均斜率(单位为mV/ °C 或 μV/ °C)
参考数据手册的电气特性章节中V25 和Avg_Slope的实际值。

 vol = (float)adcx*(3.3/256);       //电压值 
 temperate = (1.43-vol)/0.0043+25;   //转换为温度值  
 楼主| 梅花香自123 发表于 2021-3-22 23:39 | 显示全部楼层
2,内部参考电压,通道号为 ADC_Channel_17
取值范围:0-255,总共有256个取值
电压最大值对应3.3V

那么,计算公式就是:
V=3.3*value/256
 楼主| 梅花香自123 发表于 2021-3-22 23:40 | 显示全部楼层
3,一个gpio输入,PA5,通道号为 ADC_Channel_5
如果是测量电压,则其与内部参考电压的计算是一样的;
V=3.3*value/256

 

这个demo的工程代码,可以从如下地址获取:
https://download.csdn.net/download/lintax/12070601
————————————————
版权声明:本文为CSDN博主「lintax」的原创**,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lintax/article/details/103790785
您需要登录后才可以回帖 登录 | 注册

本版积分规则

102

主题

1216

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部