你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32 ADC程序示例

[复制链接]
STMCU小助手 发布时间:2022-6-15 17:00
01. ADC简介
STM32F4xx 系列一般都有 3 个 ADC,这些 ADC 可以独立使用,也可以使用双重/三重模式(提高采样率)。STM32F4 的 ADC 是 12 位逐次逼近型的模拟数字转换器。它有 19 个通道,可测量 16 个外部源、2 个内部源和 Vbat 通道的信号。这些通道的 A/D 转换可以单次、连续、扫描或间断模式执行。ADC 的结果可以左对齐或右对齐方式存储在 16 位数据寄存器中。 模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。

STM32F407ZGT6 包含有 3 个 ADC。STM32F4 的 ADC 最大的转换速率为 2.4Mhz,也就是转换时间为 0.41us(在 ADCCLK=36M,采样周期为 3 个 ADC 时钟下得到),不要让 ADC 的时钟超过 36M,否则将导致结果准确度下降。

STM32F4 将 ADC 的转换分为 2 个通道组:规则通道组和注入通道组。规则通道相当于你正常运行的程序,而注入通道呢,就相当于中断。在你程序正常执行的时候,中断是可以打断你的执行的。同这个类似,注入通道的转换可以打断规则通道的转换, 在注入通道被转换完成之后,规则通道才得以继续转换。

02. 硬件资源
用到的硬件资源有:
1) 指示灯 DS0
2) TFTLCD 模块
3) ADC
4) 杜邦线

03. 编程思路
①开启PA口时钟和ADC1时钟,设置PA1为模拟输入。

RCC_AHB1PeriphClockCmd (RCC_AHB1Periph_GPIOA, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

GPIO_Init();

② 复位ADC1,同时设置ADC1分频因子。

ADC_DeInit(ADC1);

③ 初始化ADC_CCR寄存器。

ADC_CommonInit();

④初始化ADC1参数,设置ADC1的工作模式以及规则序列的相关信息。

void ADC_Init(ADC_TypeDefADCx,ADC_InitTypeDef* ADC_InitStruct);*

⑤ 使能ADC。

​ ADC_Cmd(ADC1, ENABLE);

⑥配置规则通道参数:

ADC_RegularChannelConfig();

⑦开启软件转换:ADC_SoftwareStartConvCmd(ADC1);

⑧ 等待转换完成,读取ADC值。

ADC_GetConversionValue(ADC1);

04. 程序示例
adc.h

  1. #ifndef __ADC_H__
  2. #define __ADC_H__

  3. #include "sys.h"

  4. //ADC通道初始化
  5. void ADC1_Init(void);

  6. //获取某个通道的值
  7. u16 Get_Adc(u8 ch);

  8. //获取某个通道给定次数采样平均值
  9. u16 Get_Adc_Average(u8 ch, u8 times);

  10. #endif/*__ADC_H__*/
复制代码

adc.c

  1. #include "adc.h"
  2. #include "delay.h"


  3. //ADC通道初始化
  4. void ADC1_Init(void)
  5. {
  6.         GPIO_InitTypeDef gpio_InitTypeDef;
  7.         
  8.         ADC_InitTypeDef ADC_InitStruct;
  9.         
  10.         ADC_CommonInitTypeDef ADC_CommonInitStruct;
  11.         
  12.         //开启ADC1时钟
  13.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
  14.         
  15.         //开启GPIO时钟 PA5
  16.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
  17.         
  18.         
  19.         //GPIO初始化 初始化为模拟功能
  20.         gpio_InitTypeDef.GPIO_Pin = GPIO_Pin_5;
  21.         gpio_InitTypeDef.GPIO_Mode = GPIO_Mode_AN;
  22.         gpio_InitTypeDef.GPIO_PuPd = GPIO_PuPd_NOPULL;
  23.         GPIO_Init(GPIOA, &gpio_InitTypeDef);
  24.         
  25.         RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);          //ADC1复位
  26.         RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);        //复位结束        
  27.         
  28.         
  29.         //初始化ADC_CCR寄存器
  30.         ADC_CommonInitStruct.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
  31.         ADC_CommonInitStruct.ADC_Mode = ADC_Mode_Independent;
  32.         ADC_CommonInitStruct.ADC_Prescaler = ADC_Prescaler_Div4;
  33.         ADC_CommonInitStruct.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
  34.         ADC_CommonInit(&ADC_CommonInitStruct);
  35.         
  36.         //初始化ADC1
  37.         ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;
  38.         ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
  39.         ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
  40.         ADC_InitStruct.ADC_NbrOfConversion = 1;
  41.         ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b;
  42.         ADC_InitStruct.ADC_ScanConvMode = DISABLE;
  43.         ADC_Init(ADC1, &ADC_InitStruct);
  44.         
  45.         //使能ADC
  46.         ADC_Cmd(ADC1, ENABLE);
  47.         
  48. }

  49. //获取某个通道的值
  50. u16 Get_Adc(u8 ch)
  51. {

  52.         //设置ADC规则组通道 一个序列 采样时间
  53.         ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_480Cycles);
  54.         
  55.         //开启软件转换
  56.         ADC_SoftwareStartConv(ADC1);
  57.         
  58.         //等待转换结束
  59.         while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET)
  60.                 ;

  61.         //读取ADC的值
  62.         return  ADC_GetConversionValue(ADC1);
  63. }

  64. //获取某个通道给定次数采样平均值
  65. u16 Get_Adc_Average(u8 ch, u8 times)
  66. {
  67.         u32 tmp_val = 0;
  68.         
  69.         u8 i = 0;
  70.         
  71.         for (i = 0; i < times; i++)
  72.         {
  73.                 tmp_val += Get_Adc(ch);
  74.                 delay_ms(5);
  75.         }

  76.         return tmp_val / times;
  77. }
复制代码

main.c

  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "led.h"
  5. #include "beep.h"
  6. #include "key.h"
  7. #include "usmart.h"
  8. #include "lcd.h"
  9. #include "rtc.h"
  10. #include "rng.h"
  11. #include "key.h"
  12. #include "wkup.h"
  13. #include "adc.h"

  14. int main(void)
  15. {
  16.         u16 value = 0;
  17.         
  18.         float temp = 0;

  19.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
  20.         
  21.         delay_init(168);
  22.         
  23.         uart_init(115200);
  24.         
  25.         usmart_dev.init(84);

  26.         
  27.         LED_Init();
  28.         
  29.         
  30.         LCD_Init();

  31.         ADC1_Init();
  32.         
  33.                
  34.         POINT_COLOR = RED;
  35.         
  36.         LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");        
  37.         LCD_ShowString(30,70,200,16,16,"ADC TEST");        
  38.         LCD_ShowString(30,90,200,16,16,"ATOM@tom");
  39.         LCD_ShowString(30,110,200,16,16,"2020/09/10");         
  40.         
  41.         //设置字体为蓝色
  42.         POINT_COLOR = BLUE;
  43.         LCD_ShowString(30,130,200,16,16,"ADC1_CH5_VAL:");         
  44.         LCD_ShowString(30,150,200,16,16,"ADC1_CH5_VOL:0.000V");         
  45.                
  46.         while(1)
  47.         {
  48.                 value = Get_Adc_Average(ADC_Channel_5, 20);
  49.                
  50.                 //显示采样之后的原始值
  51.                 LCD_ShowxNum(134, 130, value, 4, 16, 0);
  52.                
  53.                 temp = (float)value * (3.3 / 4096);
  54.                 value = temp;
  55.                 LCD_ShowxNum(134, 150, value, 1, 16, 0);
  56.                
  57.                 //小数部分
  58.                 temp = temp - value;
  59.                 temp *= 1000;
  60.                 LCD_ShowxNum(150, 150, temp, 3, 16, 0x80);               
  61.                
  62.                 LED1 = !LED1;
  63.                
  64.                 delay_ms(250);
  65.         }
  66. }
复制代码




收藏 评论0 发布时间:2022-6-15 17:00

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版