• GD32F103 ADC


    1. 模拟量于数字量。

    模拟量:反应真实世界中的物理量(比如温度,压力,长度)模拟量通常是通过电压,电流等信号来表示。

    数字量:通常是0和1来表示某个物理量的变化。

     2. ADC(模拟量转成信号量)

    1. 分为并联比较,逐次逼近,计数型,双积分型。

    1.并联比较型

    Vin 大于 Vr 输出1 ,Vin 小于 Vr 输出0. 而Vin可以设置0~8v。每个比较器的Vr通过分压算出来。就可以控制比较器的输出。

    上图是输出8位怎么输出三位呢。

    利用D触发的当控制端 = 1 ,数据输入等于数据输出。

    利用D触发的当控制端 = 0,保持数据输出不变。

    如下电路就只输出三位的组合。

     2. 逐次逼近型

    一次一次接近所需的值。如下未知砝码的重量。先用权重大的。慢慢加砝码。直到两边平衡。

    VIN相当于待测量的值.于VDAC去比较。如果大于或者小于就去调整逐次逼近电路。

    直到VIN = VDAC。B1,B2.....Bn的值就是模数的转换结果。

    3. ADC的计数参数

    3. DAC(数字量转成模拟量)

    1. DAC的技术参数

    4. ADC的框图 

    GD32的框图

    STM32的框图

    分为规则通道与注入通道。并且规则通道最多可以16个。注入通道最多4个。规则通道只有一个数据寄存器。而注入每个都有单独的数据寄存器。当EOC标志位1。说明ADC转换完成。并且可以触发中断。要想成功转换还必须设置ADC的触发源。比如:软件触发。

      

     1. ADC的通道与序列

    2. ADC上电 

     3. ADC时钟

     4. ADC的运行模式

    分为单次运行,连续运行,扫描运行,间断运行。

    1. 单次模式

    单次转换模式:在这种模式下,ADC 仅进行一次转换。一旦转换完成,ADC 将停止工作。这是最基本的模式,适用于只需要一次转换的应用。

    2. 连续模式

    连续转换模式:在这种模式下,ADC 连续不断地进行转换。每次转换完成后,ADC 会自动启动下一次转换。这种模式适用于需要连续监测的应用,例如连续采集传感器数据。

     3. 扫描模式

    扫描模式:在这种模式下,ADC 会按照预设的顺序对多个通道进行转换。每次转换完成后,ADC 会继续进行下一次转换,直到完成所有通道的转换。这种模式适用于需要定期监测多个通道的应用。

    4. 间断模式 

    间断运行模式:这种模式下,ADC 会在预定的时间间隔内进行转换。在转换完成后,ADC 会停止工作,直到下一次预定的时间到达。这种模式适用于需要定期进行转换,但转换频率较低的应用。

     5. ADC函数的介绍

    1.  adc_mode_config

    2.  adc_special_function_config 

    3. adc_data_alignment_config 

    4. adc_channel_length_config

    5. adc_external_trigger_source_config

     

    6. adc_external_trigger_config

    7. adc_enable

    8. adc_calibration_enable 

    9. adc_regular_channel_config

    10. adc_software_trigger_enable

    11. adc_flag_get

    12. adc_flag_clear

    13. adc_regular_data_read

    14. adc_interrupt_flag_get

    15. adc_interrupt_flag_clear

    16. adc_interrupt_enable

    6. ADC的dome

    光敏电阻与可调电阻的P7的3,1引脚。获取PA4,PA5的电压。根据分压求出光敏电阻与可调电阻

    的电阻值。

     resister_adc.h

    1. #ifndef _RESISTER_ADC
    2. #define _RESISTER_ADC
    3. #include "gd32f10x.h"
    4. #include "systick.h"
    5. void resister_adc_init(void);
    6. void gpio_config(void);
    7. void adc_config(void);
    8. uint16_t read_adc0_data(uint8_t adc_channel); // 读取ADC0转换的结果
    9. float get_photo_r(void); //获取光敏电阻的阻值
    10. float get_var_r(void); //获取可调电阻的阻值
    11. #endif

      resister_adc.c

    1. #include "resister_adc.h"
    2. // 是与电阻相连的adc外设及其channel的初始化
    3. void resister_adc_init(void){
    4. gpio_config();
    5. adc_config();
    6. }
    7. /* 初始化IO口为模拟输入模式 */
    8. void gpio_config(){
    9. rcu_periph_clock_enable(RCU_GPIOA); // 1.使能rcu时钟
    10. gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_4 |GPIO_PIN_5); //2.初始化gpio输入模式
    11. }
    12. /* 初始化adc0 */
    13. void adc_config(){
    14. rcu_periph_clock_enable(RCU_ADC0); // 使能时钟
    15. rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV8); // 配置ADC的时钟
    16. /* 配置ADC0的参数 */
    17. adc_mode_config(ADC_MODE_FREE); // 自由模式 各个ADC独立
    18. adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);
    19. adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, DISABLE); //关闭连续模式
    20. adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT); //对齐方式
    21. adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 1); // 转换数量1 不同采集切换通道
    22. adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE); // 触发方式,软件触发
    23. adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE); // 使能外部触发
    24. /* 使能ADC0 */
    25. adc_enable(ADC0);
    26. delay_1ms(2); //等待稳定
    27. /* 自校准 */
    28. adc_calibration_enable(ADC0);
    29. }
    30. // 读取ADC0转换的结果
    31. uint16_t read_adc0_data(uint8_t adc_channel){
    32. /*配置adc0的通道*/
    33. adc_regular_channel_config(ADC0, 0, adc_channel, ADC_SAMPLETIME_1POINT5);
    34. /*触发adc0的转换*/
    35. adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);
    36. /*等待EOC置位,即ADC0转换完成*/
    37. while(!adc_flag_get(ADC0, ADC_FLAG_EOC));
    38. /*清零EOC*/
    39. adc_flag_clear(ADC0, ADC_FLAG_EOC);
    40. /*读常规通道数据寄存器值并返回*/
    41. return adc_regular_data_read(ADC0);
    42. }
    43. /*获取光敏电阻的阻值,
    44. * return:光敏电阻阻值,单位是千欧
    45. */
    46. float get_photo_r(void){
    47. uint16_t adc_value = 0;
    48. uint8_t i;
    49. for(i=0; i<8; i++){
    50. adc_value += read_adc0_data(ADC_CHANNEL_5);
    51. }
    52. adc_value = adc_value / 8;
    53. float v_photo_res = adc_value * 3.3f / 4096.0f; //得到模数转换的结果对应的电压值 基准电压3.3v 4096 = 2的12次方
    54. float result = (v_photo_res * 10) / (3 - v_photo_res);
    55. return result;
    56. }
    57. /*获取可调电阻的阻值,
    58. * return:可调电阻阻值,单位是千欧
    59. */
    60. float get_var_r(void){
    61. uint16_t adc_value = 0;
    62. uint8_t i;
    63. for(i=0; i<8; i++){
    64. adc_value += read_adc0_data(ADC_CHANNEL_4);
    65. }
    66. adc_value = adc_value / 8;
    67. float v_var_res = adc_value * 3.3f / 4096.0f; //得到模数转换的结果对应的电压值
    68. float result = (v_var_res * 10) / (5 - v_var_res);
    69. return result;
    70. }

  • 相关阅读:
    谷歌验证码无法显示问题
    循环语句中var与let声明循环变量的区别
    java中@Qualifier注解的作用?
    【Redis】链表和字典
    docker的使用
    Airtext连接chrome谷歌浏览器报错
    论文解读(PairNorm)《PairNorm: Tackling Oversmoothing in GNNs》
    共享店铺系统如何设计?具体如何做?
    C语言 数据结构 顺序表的 插入与删除
    数据降维——因子分析
  • 原文地址:https://blog.csdn.net/qq_41328470/article/details/133828486