18_ADC单通道

1、硬件

定义:ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量

 1.1独立的8位逐次逼近型ADC

  通道选择开关:选择输入通道

  DAC:数模转换器,输出最大最小值由Vref+,Vref-决定,也决定了ADC 的输入范围

  比较寄存器:选择的通道模拟量通过比较器与DAC输出的模拟量进行比较,直到数值相同为止(采用二分法进行逐次逼近)

  逐次比较寄存器:将比较值传回DAC使DAC继续输出值比较,将最终值传到锁存器中

  clock:提供ADC时钟

  start:发出开始触发信号

 

1.2STM32的ADC框图

  参考电压Vref+、Vref-由模拟电路电源VDDA、VSSA提供

  本实验选用的STM32F103C8T6能选用的ADC通道有10个

   转换的数据存储在ADC数据寄存器中,注入通道有4个数据寄存器,规则通道仅一个,在多通道的情况下需采用DMA进行数据转运,避免前面的数据被后边数据覆盖

  设置模拟看门狗可观察数据的异常情况,设置阈值高限与低限。超过范围就会发出警告

   ADCCLK来源于RCC,最大就只能14Mhz,采用6分频时为12Mhz

  状态标志位显示转换是否完成,可通过是否完成转换设置中断

  其余与独立ADC类似

1.3 ADC配置结构与顺序

  1、开启RCC时钟,包括ADC时钟,GPIO时钟,ADCCLK分频器时钟

  2、配置GPIO,将输入改为模拟输入

  3、多路开关控制,包括通道选择,转换模式选择等

  4、配置ADC转换器

  5、使能ADC1

  6、校准ADC1

  7、软件触发ADC1

  8、判断转换完毕后获取ADC1数值

 

2、接线图

通过调节电位器查看不断变化的电压值

 

3、程序

单通道模块程序

 1 #include "stm32f10x.h"
 2 
 3 
 4 void adc_init(void)
 5 {
 6     /*开启RCC时钟*/
 7     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//本实验使用PA0,开启GPIOA时钟
 8     RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//本实验使用ADC1,开启ADC1时钟
 9     RCC_ADCCLKConfig(RCC_PCLK2_Div6);//ADCCLK分频器采用6分频,频率为12Mhz
10     /*配置GPIO结构体*/
11     GPIO_InitTypeDef GPIO_InitStructure;
12     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;//选择模拟输入
13     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//选择PA0
14     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
15     GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO结构体
16     /*配置多路开关*/
17     ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);//选择ADC1的通道0,RANK在非扫描模式下无效,只取一通道,采样时间选择55
18     /*配置ADC转换器*/
19     ADC_InitTypeDef ADC_InitStructure;//定义一个ADC结构体
20     ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;//选择独立模式,本实验仅涉及1个ADC
21     ADC_InitStructure.ADC_ScanConvMode=DISABLE;//选择单通道模式
22     ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;//选择单模式还是连续模式,本实验选择单模式
23     ADC_InitStructure.ADC_ExternalTrigConv =ADC_ExternalTrigConv_None;//触发源选择软件触发
24     ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//选择右对齐
25     ADC_InitStructure.ADC_NbrOfChannel=1;//选择1通道
26     ADC_Init( ADC1, &ADC_InitStructure);
27     /*使能ADC1*/
28     ADC_Cmd(ADC1,ENABLE);
29     /*ADC校准*/
30     ADC_ResetCalibration(ADC1);
31     while( ADC_GetResetCalibrationStatus(ADC1)==SET);
32     ADC_StartCalibration( ADC1);
33     while(ADC_GetCalibrationStatus(ADC1)==SET);
34 }
35 
36 uint16_t get_adcvalue(void)
37 {
38     ADC_SoftwareStartConvCmd(ADC1,ENABLE);//软件触发ADC
39     while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET );//如果转换完毕,则可获取最终的结构,状态标志位在数据获取后自动置0
40     return ADC_GetConversionValue(ADC1);
41 
42 
43 }

 

posted @ 2023-12-06 15:55  菜腿慕  阅读(158)  评论(0)    收藏  举报