ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ARM裸机开发-ADC

ARM裸机开发-ADC 目录一.背景二.寄存器HC0HSR0CFGGCGS三.实现复用功能电气属性完整初始化校准函数读取传感器一.背景ADC是模拟到数字转换器Analog-to-Digital Converter的缩写。它是一种电子设备或模块2440内部拥有一个ADC外设。用于将连续变化的模拟信号转换为离散的数字信号以便数字系统如微处理器、微控制器等能够对其进行处理和分析。➢模拟信号一般是指连续变化的电压信号其数值在一定范围内变化。而数字信号是由一系列离散的数字表示只能取有限的值通常以二进制形式表示。➢ADC的工作原理是将模拟信号分割成一系列离散的取样并将每个取样值转换为相应的数字表示。这个过程涉及到两个主要步骤采样和量化。➢采样ADC将连续变化的模拟信号在一定时间间隔内进行取样。取样频率决定了每秒采集的样本数通常以赫兹Hz表示。采样过程通过保持并测量模拟信号在每个采样时间点的电压值来实现。➢量化采样得到的连续模拟信号经过量化转换为数字形式。量化是将每个采样值映射到一个离散的数字值的过程。这通常通过比较采样值与参考电压之间的差异并将其转换为数字表示。➢ADC量化的过程是相对于一个基准值的这个基准值称之为基准电压。一般采用逐次逼近法ADC会先拿采用电压Vadc跟基准电压Vref的1/2进行比较如果VadcVref则结果为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位。相机麦克风是ADC设备喇叭是DACADC最高频率限制20MHZ,ADACK为ADC内部时钟imx6ull专门为ADC配置的时钟默认20MHZ所以经过分频器选择一分频即可将运行速度拉满二.寄存器HC0AIEN:转换完成中断使能或禁止控制位转换完成会引发中断置0表示禁止采用轮询方式检测是否转换完成。ADCH:输入通道选择如下有通道0到9HS转换完成标记位在R0寄存器中存储R0CFGOVWREN:数据覆写使能位置0表示不覆盖上一次转换的结果置1则表示覆盖置0置1都可因为本次转换一次读一次所以无影响。AVGS:硬件平均滤波选择位选择在几次采样后进行滤波默认即可后续自己写一个滤波函数ADTRG:转换触发选择位清零软件触发ADC转换开始干活。REFSEL:选择基准电压VREFH-VREFL得到基准电压ADC_VREFH接了3.3V电压3P3)所以VREFL理论接地为0V电压。ADHSC:高速配置设置转换速度。ADSTS:采样周期00表示一次采样消耗2个时钟周期越久越精准ADLPC低功耗模式置0表示不在低功耗。ADIV:时钟分频位00表示输入时钟不分频。ADLSMP:长采样或者短采样默认即可。MODE:设置ADC分辨率设置最高12位ADICLK:选择输入时钟11为上述提及的专用时钟20MHZ。GCCAL:使用ADC之前校准将CAL置1ADCO:持续转换使能位0表示单次转换1表示持续转换本次采用单次转换。而要开启ADC转换要先切换一次通道比如从ADC1通道0切换到ADC1通道1开启转换。AVGE:硬件平均功能使能位清零表示硬件平均滤波失能因为要自己写滤波所以置零。ACFE设置中断阈值根据结果触发中断本次不用中断置0ACFGT:对中断比较结果的判断大于小于置0ACREN:开启ACFE位DMA:DMA位本次不用。对ADACK的使能配置置1表示时钟输出使能。GS0表示校准成功1失败失败清零三.实现复用功能// 配置引脚复用功能 IOMUXC_SetPinMux(IOMUXC_GPIO1_IO01_GPIO1_IO01, 0);电气属性PUE位配0为保持电压若置1则为拉可能改变传感器输入的电压PKE置1为保持功能使能// 配置电气属性 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));完整初始化void adc1_channel1_init(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);//置0表示禁止采用轮询方式检测是否转换完成。 ADC1-CFG 0; ADC1-CFG | (1 3) | (3 0); //23位MODE:设置ADC分辨率设置最高12位 //01位ADICLK:选择输入时钟11为上述提及的专用时钟20MHZ。 ADC1-GC 0; ADC1-GC | (1 0);//对ADACK的使能配置置1表示时钟输出使能。 // 校准 printf(adc1_calibration() ? calibration completed normally!\n : calibration completed failed!\n); }校准函数内部对电压校准校准之后产生误差下次调用会自动减去误差int adc1_calibration(void) { // 校准 ADC1-GC | (1 7); while ((ADC1-GC (1 7)) ! 0);//校准需要过一段时间校准完成后此位会自动清零所以卡住等校准成功 if ((ADC1-GS (1 1)) 0) //GSbit1位清零说明校准通过 { 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; //读取ADC转换完成后的数据 } float adc1_get_value(void) //转换为模拟信号 { return adc1_get_origin_value() / 4095.0 * 3.3; }
返回列表