当前位置:   article > 正文

STM32学习笔记(江协科技)-----ADC模数转换

江协科技

目录

ADC简介:

原理框图:

ADC0809内部结构图:

总体框图:

​编辑


 

 

ADC简介:

可以将引脚上连续变化的模拟电压转化为内存存储的数字变化量,建立模拟到数字的桥梁。

是一种逐次逼近型模拟数字转换器有12位,1微秒的转换时间

12位:最大值:1111 1111 1111,即:2^13 - 1 = 4096-1=4095

        所以转换结果的范围为:0~4095。

1微秒:即周期为1微秒,对应(最大)频率为:1/1μs = 1MHZ。

输入电压范围:0~3.3v。

它有多达18个通道,可测量16个外部和2个内部信号源。

各通道的A/D转换可以单次、连续、扫描或间断模式执行。

ADC的结果可以左对齐或右对齐方式存储在16位数据寄存器中。

因为转换结果是12位的,而寄存器是16位的,所以必然有4个位为0.

(通常使用右对齐)。eg:0000 1101 1001

原理框图:

ADC0809内部结构图:

408e9efe29804a0bac1242b137a86339.png

总体框图:

cff40a27dc9a4ac9aaa0246ee1168f88.png

691d25c65c6b41129849d4284c6b85ba.png

输入通道:

d40f182efa534e779c7110c542ac332f.png

转换模式:

单次转换,非扫描模式。

d38c629b646845b2a69eed88a61d5e94.png

连续转换,非扫描模式。

9774324c2bf94c34868af38aca948b18.png

单次转换,扫描模式。

2783a0d5e29949e0a43073702d63dd3f.png

连续转换,扫描模式。

b14143c0307b409883680a34489e86e5.png

代码:

ADC.c

  1. #include "stm32f10x.h" // Device header
  2. /**
  3. * 函 数:AD初始化
  4. * 参 数:无
  5. * 返 回 值:无
  6. */
  7. void AD_Init(void)
  8. {
  9. /*开启时钟*/
  10. RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //开启ADC1的时钟
  11. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟
  12. /*设置ADC时钟*/
  13. RCC_ADCCLKConfig(RCC_PCLK2_Div6); //选择时钟6分频,ADCCLK = 72MHz / 6 = 12MHz
  14. /*GPIO初始化*/
  15. GPIO_InitTypeDef GPIO_InitStructure;
  16. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  17. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
  18. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  19. GPIO_Init(GPIOA, &GPIO_InitStructure); //将PA0、PA1、PA2和PA3引脚初始化为模拟输入
  20. /*不在此处配置规则组序列,而是在每次AD转换前配置,这样可以灵活更改AD转换的通道*/
  21. /*ADC初始化*/
  22. ADC_InitTypeDef ADC_InitStructure; //定义结构体变量
  23. ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //模式,选择独立模式,即单独使用ADC1
  24. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据对齐,选择右对齐
  25. ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //外部触发,使用软件触发,不需要外部触发
  26. ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //连续转换,失能,每转换一次规则组序列后停止
  27. ADC_InitStructure.ADC_ScanConvMode = DISABLE; //扫描模式,失能,只转换规则组的序列1这一个位置
  28. ADC_InitStructure.ADC_NbrOfChannel = 1; //通道数,为1,仅在扫描模式下,才需要指定大于1的数,在非扫描模式下,只能是1
  29. ADC_Init(ADC1, &ADC_InitStructure); //将结构体变量交给ADC_Init,配置ADC1
  30. /*ADC使能*/
  31. ADC_Cmd(ADC1, ENABLE); //使能ADC1,ADC开始运行
  32. /*ADC校准*/
  33. ADC_ResetCalibration(ADC1); //固定流程,内部有电路会自动执行校准
  34. while (ADC_GetResetCalibrationStatus(ADC1) == SET);
  35. ADC_StartCalibration(ADC1);
  36. while (ADC_GetCalibrationStatus(ADC1) == SET);
  37. }
  38. /**
  39. * 函 数:获取AD转换的值
  40. * 参 数:ADC_Channel 指定AD转换的通道,范围:ADC_Channel_x,其中x可以是0/1/2/3
  41. * 返 回 值:AD转换的值,范围:0~4095
  42. */
  43. uint16_t AD_GetValue(uint8_t ADC_Channel)
  44. {
  45. ADC_RegularChannelConfig(ADC1, ADC_Channel, 1, ADC_SampleTime_55Cycles5); //在每次转换前,根据函数形参灵活更改规则组的通道1
  46. ADC_SoftwareStartConvCmd(ADC1, ENABLE); //软件触发AD转换一次
  47. while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); //等待EOC标志位,即等待AD转换结束
  48. return ADC_GetConversionValue(ADC1); //读数据寄存器,得到AD转换的结果
  49. }

ADC.h

  1. #ifndef __AD_H
  2. #define __AD_H
  3. void AD_Init(void);
  4. uint16_t AD_GetValue(uint8_t ADC_Channel);
  5. #endif

main.c

  1. #include "stm32f10x.h" // Device header
  2. #include "Delay.h"
  3. #include "OLED.h"
  4. #include "AD.h"
  5. uint16_t AD0, AD1, AD2, AD3; //定义AD值变量
  6. int main(void)
  7. {
  8. /*模块初始化*/
  9. OLED_Init(); //OLED初始化
  10. AD_Init(); //AD初始化
  11. /*显示静态字符串*/
  12. OLED_ShowString(1, 1, "AD0:");
  13. OLED_ShowString(2, 1, "AD1:");
  14. OLED_ShowString(3, 1, "AD2:");
  15. OLED_ShowString(4, 1, "AD3:");
  16. while (1)
  17. {
  18. AD0 = AD_GetValue(ADC_Channel_0); //单次启动ADC,转换通道0
  19. AD1 = AD_GetValue(ADC_Channel_1); //单次启动ADC,转换通道1
  20. AD2 = AD_GetValue(ADC_Channel_2); //单次启动ADC,转换通道2
  21. AD3 = AD_GetValue(ADC_Channel_3); //单次启动ADC,转换通道3
  22. OLED_ShowNum(1, 5, AD0, 4); //显示通道0的转换结果AD0
  23. OLED_ShowNum(2, 5, AD1, 4); //显示通道1的转换结果AD1
  24. OLED_ShowNum(3, 5, AD2, 4); //显示通道2的转换结果AD2
  25. OLED_ShowNum(4, 5, AD3, 4); //显示通道3的转换结果AD3
  26. Delay_ms(100); //延时100ms,手动增加一些转换的间隔时间
  27. }
  28. }

 

 

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/935844
推荐阅读
相关标签
  

闽ICP备14008679号