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

#ifndef _RESISTER_ADC
#define _RESISTER_ADC

#include "gd32f10x.h"
#include "systick.h"

void resister_adc_init(void);
void gpio_config(void);
void adc_config(void);

uint16_t read_adc0_data(uint8_t adc_channel); // 读取ADC0转换的结果
float get_photo_r(void);    //获取光敏电阻的阻值
float get_var_r(void);      //获取可调电阻的阻值

#endif

  resister_adc.c

#include "resister_adc.h"

// 是与电阻相连的adc外设及其channel的初始化
void resister_adc_init(void){
	gpio_config();
	adc_config();
}

/* 初始化IO口为模拟输入模式 */
void gpio_config(){
	  rcu_periph_clock_enable(RCU_GPIOA);   // 1.使能rcu时钟
    gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_4 |GPIO_PIN_5);  //2.初始化gpio输入模式
}

/* 初始化adc0 */
void adc_config(){
	rcu_periph_clock_enable(RCU_ADC0);            // 使能时钟
	rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV8);  // 配置ADC的时钟
	
	/* 配置ADC0的参数 */
	adc_mode_config(ADC_MODE_FREE);            // 自由模式 各个ADC独立
	
	adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);        
	adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, DISABLE); //关闭连续模式
	
	adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);      //对齐方式
	adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 1);   // 转换数量1 不同采集切换通道
	
	adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE); // 触发方式,软件触发
	adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);  // 使能外部触发
	
	/* 使能ADC0 */
	adc_enable(ADC0);
	delay_1ms(2);     //等待稳定
	
	/* 自校准 */
	adc_calibration_enable(ADC0);
}

// 读取ADC0转换的结果
uint16_t read_adc0_data(uint8_t adc_channel){
	/*配置adc0的通道*/
	adc_regular_channel_config(ADC0, 0, adc_channel, ADC_SAMPLETIME_1POINT5);
	
	/*触发adc0的转换*/
	adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);
	
	/*等待EOC置位,即ADC0转换完成*/
	while(!adc_flag_get(ADC0, ADC_FLAG_EOC));
	/*清零EOC*/
	adc_flag_clear(ADC0, ADC_FLAG_EOC);
	
	/*读常规通道数据寄存器值并返回*/
	return adc_regular_data_read(ADC0);
}

/*获取光敏电阻的阻值, 
* return:光敏电阻阻值,单位是千欧
*/
float get_photo_r(void){
	uint16_t adc_value = 0;
	uint8_t i;
	for(i=0; i<8; i++){
    	adc_value += read_adc0_data(ADC_CHANNEL_5);
	}
	
	adc_value = adc_value / 8;
	
	float v_photo_res = adc_value * 3.3f / 4096.0f;  //得到模数转换的结果对应的电压值 基准电压3.3v  4096 = 2的12次方
	float result = (v_photo_res * 10) / (3 - v_photo_res);
	return result; 
}

/*获取可调电阻的阻值, 
* return:可调电阻阻值,单位是千欧
*/
float get_var_r(void){      
	uint16_t adc_value = 0;
	uint8_t i;
	for(i=0; i<8; i++){
    	adc_value += read_adc0_data(ADC_CHANNEL_4);
	}
	
	adc_value = adc_value / 8;
	
	float v_var_res = adc_value * 3.3f / 4096.0f;  //得到模数转换的结果对应的电压值
	float result = (v_var_res * 10) / (5 - v_var_res);
	return result; 
}

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值