当前位置: 首页 > news >正文

《嵌入式硬件(十八):基于IMX6ULL的ADC操作》

一、ADC

        1.基本概念

        ADC是模拟到数字转换器(Analog-to-Digital Converter)的缩写。它是一种电子设备或模块,2440内部拥有一个ADC外设。用于将连续变化的模拟信号转换为离散的数字信号,以便数字系统(如微处理器、微控制器等)能够对其进行处理和分析。
模拟信号一般是指连续变化的电压信号,其数值在一定范围内变化。而数字信号是由一系列离散的数字表示,只能取有限的值,通常以二进制形式表示。

        2.工作原理


ADC的工作原理是将模拟信号分割成一系列离散的取样,并将每个取样值转换为相应的数字表示。这个过程涉及到两个主要步骤:采样和量化。
采样:ADC将连续变化的模拟信号在一定时间间隔内进行取样。取样频率决定了每秒采集的样本数,通常以赫兹(Hz)表示。采样过程通过保持并测量模拟信号在每个采样时间点的电压值来实现。
量化:采样得到的连续模拟信号经过量化转换为数字形式。量化是将每个采样值映射到一个离散的数字值的过程。这通常通过比较采样值与参考电压之间的差异,并将其转换为数字表示。


ADC量化的过程是相对于一个基准值的,这个基准值称之为基准电压。一般采用逐次逼近法的ADC会先拿采用电压Vadc跟基准电压Vref的1/2进行比较,如果Vadc>Vref,则结果为1,否则结果为0。之后继续拿Vadc和Vref的1/4或Vref的3/4继续比较。这个过程有点像二分法,每次比较都会使量化的结果逼近真实值。很明显,比较的次数决定了测量的精度,这个精度被称之为ADC的分辨率。比如一个比较了8次的ADC外设,它就称为8位ADC,其结果是0~255之间的一个数值,设该数值为n,那么实际电压就是Vref * (n/255)。如果把比较次数增加到10次,结果就是0~1023之间的一个数。常见的分辨率包括8位,10位,12位和16位。

        3.imx6ull里的ADC


I.MX6ULL内部具有两个ADC控制器。都是采用逐次逼近法设计的。每路ADC的分辨率可选,分别为8/10/12位。 I.MX6ULL内部ADC具有自动校准功能,因此能够保证更高的测量精度;最大转换速率为1MHz,即完成一次转换所需的时间最快只需要1us。 I.MX6ULL的ADC还具有硬件平均功能和比较功能,大大方便了软件设计。我们实验所使用的开发板将基准电压设置为3.3V。
每个ADC拥有10个通道,这里的通道就是指输入的电压信号是从哪个引脚输入进来的意思。10个引脚其实就是GPIO1_IO00~GPIO1_IO09这10个引脚。我们在配置引脚功能时只需将引脚配置为GPIO就行,电器配置时可以保持默认配置下使能Keeper即可。
I.MX6ULL的时钟源可以是igpclk、igpclk/2和ADACK,其中ADACK是I.MX6ULL内部提供的时钟源,只能提供给ADC外设使用,这样做的目的是保证系统处于低功耗状态时,ADC依旧能够运行。 ADACK的时钟默认为20MHz。我们接下来的操作就把时钟配置为ADACK。
I.MX6ULL的ADC使用还是很简单的,首先在初始化的时候配置好引脚,例如GPIO1_IO01这个引脚;之后配置ADCx_CFG和ADCx_GC寄存器。然后启动一次自动校准,系统校准完成后每次向ADCx_HC0寄存器中写入一次数据(其实就是切换到别的通道之后再切换回来)就会启动一次ADC转换。转换结束之后的数据就保存再ADCx_R0寄存器中。

二、原理

        1.HC0

        2.HS

        3.R0

        4.CFG(配置寄存器)

        5.GC

        6.GS

三、代码

        1.adc.c

#include "adc.h"
#include "MCIMX6Y2.h"
#include "fsl_iomuxc.h"void init_adc1_channle1(void)
{IOMUXC_SetPinMux(IOMUXC_GPIO1_IO01_GPIO1_IO01, 0);IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO01_GPIO1_IO01, IOMUXC_SW_PAD_CTL_PAD_PKE(1));//单独设置一位IOMUXC_SetPinConfig(IOMUXC_GPIO1_IO01_GPIO1_IO01, IOMUXC_SW_PAD_CTL_PAD_PUE(0));ADC1->HC[0] &= ~(1 << 7);//HC是数组ADC1->CFG = 0;ADC1->CFG |= (2 << 2) | (3 << 0);ADC1->GC = 0;ADC1->GC |= (1 << 0);printf(adc1_calibration() ? "Calibration completed normally." : "Calibration failed. ");//校准
}int adc1_calibration(void)
{ADC1->GC |= (1 << 7);while((ADC1->GC & (1 << 7)) != 0);if((ADC1->GS & (1 << 1)) == 0){return 1;}else{return 0;}
}unsigned short adc1_get_origin_value(void)
{ADC1->HC[0] = 0;ADC1->HC[0] = 1;while((ADC1->HS & (1 << 0)) == 0);return ADC1->R[0] & 0xFFF;//0000 0000 1111 1111 1111
}void swap(unsigned short *a, unsigned short *b)
{unsigned short t = *a;*a = *b;*b = t;
}void sort(unsigned short *a, int len)
{int i, j;for(i = 0;i < len - 1;++i){for(j = i + 1;j < len;++j){if(a[i] > a[j])//*(a + i){swap(a + i, a + j);}}}
}unsigned int sum_of_array(unsigned short *a, int len)
{unsigned int sum = 0;int i;for(i = 0;i < len;++i){sum += a[i];}return sum;
}float adc1_get_value(void)
{unsigned short a[100];int i;for(i = 0;i < 100;++i){a[i] = adc1_get_origin_value();}sort(a, sizeof(a) / sizeof(a[0]));return sum_of_array(a + 10, 80) / 80 / 4095.0 * 3.3;
}

        2.adc.h

#ifndef _ADC_H_
#define _ADC_H_extern void init_adc1_channle1(void);
extern int adc1_calibration(void);
extern unsigned short adc1_get_origin_value(void);
extern float adc1_get_value(void);#endif

        3.main.c

#include "string.h"
#include "led.h"
#include "beep.h"
#include "MCIMX6Y2.h"
#include "key.h"
#include "interrupt.h"
#include "clock.h"
#include "epit.h"
#include "gpt.h"
#include "delay.h"
#include "uart.h"
#include "stdio.h"
#include "i2c.h"
#include "lm75.h"
#include "adc.h"int main(void)
{init_clock();system_interrupt_init();init_led();init_beep();// init_key();
//    init_epit1();init_gpt1();init_uart1(); init_i2c1();init_adc1_channle1();while(1){float f;f = adc1_get_value();int k = f * 1000;int m = k / 1000;int n = k % 1000;printf("%d.%d\n", m, n);}return 0;
}
http://www.dtcms.com/a/544665.html

相关文章:

  • 注册网站发财的富豪北京公司如何做网站
  • 仓颉语言异常捕获机制深度解析
  • 基于SAP.NET Core Web APP(MVC)的医疗记录管理系统完整开发指南
  • 咖啡网站建设设计规划书wordpress修改首页网址导航
  • C#WPF UI路由事件:事件冒泡与隧道机制
  • 神经网络时序预测融合宏观变量的ETF动态止盈系统设计与实现
  • 分布式Session会话实现方案
  • Java创建【线程池】的方法
  • 相机直播,HDMI线怎么选择
  • 做外贸哪些国外网站可以推广上海中学地址
  • HFSS微带线仿真
  • 推荐常州微信网站建设网站友链怎么做
  • 多模态的大模型文本分类模型代码(二)——模型初步运行
  • 强化特权用户监控,守护Active Directory核心安全
  • Kafka Consumer 消费流程详解
  • 安全守护者:防爆外壳在气体传感器领域的关键应用
  • 【JavaEE初阶】网络经典面试题小小结
  • 以太网多参量传感器:构筑工业安全与环境稳定的“数据堡垒”
  • pinia-storeToRefs方法
  • 基于用户的协同过滤算法理解
  • jsp书城网站开发中国建设银行重庆网站首页
  • 郑州网站建设公司排名湖南省城乡住房建设厅网站
  • 蓝牙钥匙 第4次 蓝牙协议栈深度剖析:从物理层到应用层的完整架构解析
  • 口腔健康系统|口腔医疗|基于java和小程序的口腔健康系统小程序设计与实现(源码+数据库+文档)
  • FANUC发那科焊接机器人薄板焊接节气
  • 如何加强网站信息管理建设个人网站设计步骤
  • 调用API历史和未来气象数据获取
  • 机器人从设计到仿真到落地
  • 战略合作 | 深信科创携手北极雄芯、灵猴机器人共推国产智能机器人规模化落地
  • Rust 闭包的定义与捕获:从理论到实践的深度探索