NORDIC nRF24LE1 学习笔记 Day04 ADC

在已经搞定最基础的GPIO和串口后,就要开始学习更具体一些的功能了

关于NORDIC nRF24LE1的ADC的简介
其包含一个14通道的通用ADC(与封装相关),ADC内置1.2V的内置参考电压,也可以以外部才考电压或者VDD作为参考电压。可以在软件控制下单步工作,也可以设置采样速率进行连续采样装换。
特征
6,8,10,12位分辨率
多达14个输入通道
单端或差分输入
内部参考电压,外部参考电压,或VDD
单步模式转换时间小于3微秒
持续模式可设置为2,4,8或16Kbps采样速率
低电流消耗,2Kbps速率下仅0.1毫安

这次我使用的例程是来自NORDIC的SDK包中的例程,这个例程中使用的是NORDIC提供的简单的类似库的操作。


#include "nrf24le1.h"
#include "hal_adc.h"

void main()
{
  // Set P1 as output
  P1DIR = 0;

  // Configure ADC
  hal_adc_set_input_channel(HAL_ADC_INP_AIN0);
  hal_adc_set_reference(HAL_ADC_REF_VDD);
  hal_adc_set_input_mode(HAL_ADC_SINGLE);
  hal_adc_set_conversion_mode(HAL_ADC_CONTINOUS);
  hal_adc_set_sampling_rate(HAL_ADC_2KSPS);
  hal_adc_set_resolution(HAL_ADC_RES_8BIT);
  hal_adc_set_data_just(HAL_ADC_JUST_RIGHT);

  // Enable MISC interrupts to enable ADC interrupt
  MISC = 1;
  // Enable global interrupts
  EA = 1;
  // Start ADC conversion
  hal_adc_start();

  for(;;){}
}

// ADC (MISC) interrupt
ADC_ISR()
{
  // Write sample value to P0
  P1 = hal_adc_read_LSB();
}

#include 
#include 

#include "nrf24le1.h"
#include "nordic_common.h"
#include "hal_adc.h"


void hal_adc_set_input_channel(hal_adc_input_channel_t chsel)
{ // Update "chsel" bits
  ADCCON1 = ((ADCCON1 & 0xC3) | (((uint8_t)(chsel) << 2) & ~0xC3));
}


void hal_adc_set_reference(hal_adc_reference_t refsel)
{ // Update "refsel" bits
  ADCCON1 = ((ADCCON1 & 0xFC) | (((uint8_t)(refsel)) & ~0xFC));
}


void hal_adc_set_input_mode(hal_adc_input_mode_t input_mode)
{ // Update "diffm" bits
  ADCCON2 = ((ADCCON2 & 0x3F) | ((uint8_t)(input_mode) << 6));
}


void hal_adc_set_conversion_mode(hal_adc_conversion_mode_t conv_mode)
{ // Update "cont" bit
  ADCCON2 = ((ADCCON2 & 0xDF) | (((uint8_t)(conv_mode) << 5) & ~0xDF));
}


void hal_adc_set_sampling_rate(hal_adc_sampling_rate_t rate)
{ // Update "rate" bits
  ADCCON2 = ((ADCCON2 & 0xE3) | (((uint8_t)(rate) << 2) & ~0xE3));
}


void hal_adc_set_power_down_delay(hal_adc_power_down_delay_t pdd)
{ // Update "rate" bits
  ADCCON2 = ((ADCCON2 & 0xE3) | (((uint8_t)(pdd) << 2) & ~0xE3));
}


void hal_adc_set_acq_window(hal_adc_acq_window_t tacq)
{ // Update "tacq" bits
  ADCCON2 = ((ADCCON2 & 0xFC) | (((uint8_t)(tacq)) & ~0xFC));
}


void hal_adc_set_resolution(hal_adc_resolution_t res)
{ // Update "resol" bits
  ADCCON3 = ((ADCCON3 & 0x3F) | ((uint8_t)(res) << 6));
}


void hal_adc_set_data_just(hal_adc_data_just_t just)
{ // Update "rljust" bit
  ADCCON3 = ((ADCCON3 & 0xDF) | (((uint8_t)(just) << 5) & ~0xDF));
}


void hal_adc_start(void)
{
  uint8_t cnt = ADC_STARTUP_CNT;             // Get the counter value
  ADCCON1 = ADCCON1 | BIT_7;                 // Set "pwrup" bit

  while(cnt--){}                         // Wait for busy bit to stabilize
}


uint8_t hal_adc_read_LSB(void)
{
  return ADCDATL;                            // Return value stored in ADCDATL
}

uint8_t hal_adc_read_MSB(void)
{
  return ADCDATH;                            // Return value stored in ADCDATH
}

bool hal_adc_busy(void)
{
  return ((ADCCON1 & BIT_6));            // Return status of "busy" bit
}

hal_adc_overflow_t hal_adc_get_overflow_status(void)
{
  return (hal_adc_overflow_t)((ADCCON3 & (BIT_3 | BIT_4)) >> 3);
}
                                      // Return status bits from ADCCON3

ADCCON1 寄存器(地址 : 0xD3 复位值 : 0x00)

名称 类型 描述
7 pwrup 读写 0 : ADC掉电
1 :ADC上电并配置所选择的引脚作为模拟输入
6 busy 只读 0 :没有在转换
1 : 正在转换
5:2 chsel 读写 0000 : AIN0
0001 :AIN1
···
···
1101AIN13
1110:1/3 VDD
1111:2/3 VDD
1:0 refsel 读写 00 : 内部1.2V参考电压
01 : VDD
10 : AIN3输入的外部参考电压
11 : AIN9输入的外部参考电压

ADCCIN2 寄存器(地址 : 0xD2 复位值 : 0x00)

名称 类型 描述
7:6 diffm 读写 00 : 单端输入
01 : 差分输入,AIN2反相输入
10 : 差分输入,AIN6反相输入
11 : 未使用
5 cont 读写 0 : 单步转换模式
1 : 持续转换模式
4:2 rate 读写 持续模式转换速率
000 : 2Kbps
001 : 4Kbps
010 : 8Kbps
011 : 16Kbps
1xx : 未使用
单步模式下掉电延时
000 : 0微秒
001 : 6微秒
010 : 24微秒
011 : 无穷大(清pwrup进入掉电)
1xx : 未使用
1:0 tacq 读写 输入持续采样时间
00 : 0.75微秒
01 : 3微秒
10 : 12微秒
11 : 36微秒

ADCCON3 寄存器(地址 : 0xD1 复位值 : 0x00)

名称 类型 描述
7:6 resol 读写 分辨率:
00 : 6位
01 : 8位
10 : 10位
11 : 12位
5 rljust 只读 选择ADCDATH/ADCDATL中的数据对齐方式
0 : 左对齐
1 : 右对齐
4 uflow 只读 转换结果全为0
3 oflow 只读 转换结果全为1
2 range 只读 uflow与oflow的逻辑或
1:0 - - 未使用

ADCDATH 寄存器 (地址 : 0xD4 复位值 : 0x00)

名称 类型 描述
7:0 - 只读 ADCDATA MSB

ADCDATL 寄存器

名称 类型 描述
7:0 - 只读 ADCDATA LSB
rljust resol ADCDATH[7:0] ADCDATL[7:0]
0 00 ADCDATA[5:0] 0
0 01 ADCDATA[7:0] 0
0 10 ADCDATA[9:0] 0
0 11 ADCDATA[11:0] 0
1 00 0 ADCDATA[5:0]
1 01 0 ADCDATA[7:0]
1 10 0 ADCDATA[9:0]
1 11 0 ADCDATA[11:0]

最重要的一步就是将寄存器内的数据转换成浮点型

由于分辨率是8位所以最大值为255,单端输入的范围是0V到参考电压,所以255就是参考电压的值
由此得到V = V*330/256;

常用的几种类型的ADC基本原理及特点
AD转换器的分类
下面简要介绍常用的几种类型的基本原理及特点:积分型、逐次逼近型、并行比较型/串并行型、Σ-Δ调制型、电容阵列逐次比较型及压频变换型。
1)积分型(如TLC7135)
积分型AD工作原理是将输入电压转换成时间(脉冲宽度信号)或频率(脉冲频率),然后由定时器/计数器获得数字值。其优点是用简单电路就能获得高分辨率,但缺点是由于转换精度依赖于积分时间,因此转换速率极低。初期的单片AD转换器大多采用积分型,现在逐次比较型已逐步成为主流。
2)逐次比较型(如TLC0831)
逐次比较型AD由一个比较器和DA转换器通过逐次比较逻辑构成,从MSB开始,顺序地对每一位将输入电压与内置DA转换器输出进行比较,经n次比较而输出数字值。其电路规模属于中等。其优点是速度较高、功耗低,在低分辩率(<12位)时价格便宜,但高精度(>12位)时价格很高。
3)并行比较型/串并行比较型(如TLC5510)
并行比较型AD采用多个比较器,仅作一次比较而实行转换,又称FLash(快速)型。由于转换速率极高,n位的转换需要2n-1个比较器,因此电路规模也极大,价格也高,只适用于视频AD转换器等速度特别高的领域。
串并行比较型AD结构上介于并行型和逐次比较型之间,最典型的是由2个n/2位的并行型AD转换器配合DA转换器组成,用两次比较实行转换,所以称为Half flash(半快速)型。还有分成三步或多步实现AD转换的叫做分级(Multistep/Subrangling)型AD,而从转换时序角度又可称为流水线(Pipelined)型AD,现代的分级型AD中还加入了对多次转换结果作数字运算而修正特性等功能。这类AD速度比逐次比较型高,电路规模比并行型小。
4)Σ-Δ(Sigma?/FONT>delta)调制型(如AD7705)
Σ-Δ型AD由积分器、比较器、1位DA转换器和数字滤波器等组成。原理上近似于积分型,将输入电压转换成时间(脉冲宽度)信号,用数字滤波器处理后得到数字值。电路的数字部分基本上容易单片化,因此容易做到高分辨率。主要用于音频和测量。
5)电容阵列逐次比较型
电容阵列逐次比较型AD在内置DA转换器中采用电容矩阵方式,也可称为电荷再分配型。一般的电阻阵列DA转换器中多数电阻的值必须一致,在单芯片上生成高精度的电阻并不容易。如果用电容阵列取代电阻阵列,可以用低廉成本制成高精度单片AD转换器。最近的逐次比较型AD转换器大多为电容阵列式的。
6)压频变换型(如AD650)
压频变换型(Voltage-Frequency Converter)是通过间接转换方式实现模数转换的。其原理是首先将输入的模拟信号转换成频率,然后用计数器将频率转换成数字量。从理论上讲这种AD的分辨率几乎可以无限增加,只要采样的时间能够满足输出频率分辨率要求的累积脉冲个数的宽度。其优点是分辩率高、功耗低、价格低,但是需要外部计数电路共同完成AD转换

你可能感兴趣的:(学习笔记,nRF24LE1)