物联网|AD转换之VDD检测|外设I/O|ADC电压读取|Read_Vddvalue函数|ADC的计算方法|分段取值|物联网之蓝牙4.0 BLE基础-学习笔记(10)

AD转换之VDD检测

外设I/O

本节描述了数字IO引脚是如何配置为外设IO的。对于可以通过数字输入/输出引脚和外部系统接口的每个外设单元,如何配置外设IO的描述给定在以下小节中。
在这里插入图片描述
对于USART和定时器IO,在一个数字TO引脚上选择外设IO功能,需要设置对应的 PxSEL位为1。注意,该外部单元具有两个可以选择的位置对应它们的TO 引脚,参见表7-1。如果有关于TO映射的冲突设置,可以在这些之间设置优先级(使用P2SEL.PRIP1和 P2DIR PRIPO位)。所有不会导致冲突的组合都可以使用。
注意即使没有使用,外设一般也会出现在选定的位置,使用引脚的其他外设必须给予较高的优先级。例外情况是流量控制禁用时UART模式下USART的RTS和CTS 引脚,以及SPI主模式下USART配置的SSN引脚。
还要注意不管PxINP的设置,有输入引脚的外设单元是从引脚接收输入,这可能会影响外设单元的状态。例如如果RX引脚在用作一个UART 引脚之前,可能已经有活动,UART 在使用之前必须被清除。
例子:使用P0_0胶,并设置成为输出模式。

常量定义

#define HAL_ADC_REF_125V 0x00
#define HAL_ADC_DEC064 0x00
#define HAL_ADC_CHN_VDD3 0x0f
#define HAL_ADC_CHN_AIN0 0xf0

ADC

ADC支持高达12位ENOB的14位模数转换。它包括一个模拟多路复用器,多达8个独立配置通道和一个参考电压发生器。转换结果可以通过DMA写入内存。有几种操作模式可供选择。
ADC支持高达14位的模数转换,具有高达12位的ENOB(有效位数)。它包括一个模拟多路复用器,最多可配置8个通道和一个参考电压发生器。转换结果可以通过DMA写入内存。有几种操作模式可用。
ADC的主要特点如下:
可选择的抽取率,也设置有效分辨率(7至12位)。
8个单独的输入通道,
单端或差分
参考电压可选为内部、外部单端、
外部差分或avdd5中断请求生成
转换结束时DMA触发温度传感器输入
·电池测量能力

ADC电压读取

在这里插入图片描述

ADC interrupt flag. Set to 1 when ADC interrupt occurs and cleared when CPu vectors to the interrupt service routine.
ADC中断标志当ADC中断发生时,将其设置为1,并在中断服务例程的CPU VISTION中清除。
0: Interrupt not pending
0:中断未挂起
1 : Interrupt pending
1:中断等待

ADCCON3 (0xB6) – ADC Control 3设置

Read_Vddvalue函数

在这里插入图片描述

unsigned int Read_Vddvalue(void)
{
  unsigned int value;
  unsigned char tmpADCCON3 = ADCCON3;
  ADCIF = 0;
  ADCCON3 =(HAL_ADC_REF_125V|HAL_ADC_DEC064|HAL_ADC_CHN_AIN0);
  while(!ADCIF);//中断等待,直到转换结束(1 : Interrupt pending)
  value = ADCL >> 2; //低2位,Not used. Always read as 0,右移2位,将低位清除。取7:2 有效位是ADC[5:0]
  value |= ((unsigned int )ADCH)<<6; //ADCH取7:0,有效位是ADC[13:6],故左移6位,再与低位或操作,共14位
  ADCCON3 = tmpADCCON3;
  return (value);
}

函数分析

ADCCON3 =(HAL_ADC_REF125V|HAL_ADC_DEC064|HAL_ADC_CHN_AIN0);
或操作,仅设置对应位,不改变其他位,故设置为:内部参考电压,7 bits ENOB,0000: AIN0端口,
Selects reference voltage used for the extra conversion
选择用于额外转换的基准电压。
00:Internal reference
Sets the decimation rate used for the extra conversion.The decimation rate also determines theresolution and time required to complete the conversion.
设置用于额外转换的抽取速率。抽取速率还决定完成转换所需的时间和时间。
00:64 decimation rate (7 bits ENOB)
00:64抽取率(7位EnOB)
Single channel select. Selects the channel number of the single conversion that is triggered bywriting to ADCCON3.The bits are automatically cleared when the single conversion has finished.0000:AINO
单通道选择选择写入ADCCON 3触发的单个转换的信道号。当单个转换完成时,将自动清除位数。在这里插入图片描述

ADC的计算方法

vddvalue = (VddCount25)>>8;
VddCount为实测值,给定基准值为1.25V(CC2530 应该是1.15V,CC2430是1.25V)。
计算方法:VddCount
基准电压(这里是1.25)/(2^采样位数),读取时放大10倍,故有:vddvalue = (VddCount1.25210)/2^72=(VddCount*25)>>8;
一个具有8位分辨率的模拟数字转换器可以将模拟信号编码成256个不同的离散值(因为2^8= 256),从0到255(即无符号整数)或从-128到127(即带符号整数),假设参考电压,输入的模拟电压是1.25v,那我们得到的数字值是多少呢?
将5V分成256,同时1.25v是5V的1/4,则输出数字值为256/4=64。

分段取值

在这里插入图片描述
根据不同的采样位数,采用vdd*基准电压(这里是1.25)/(2^采样位数)进行计算。

扫描二维码关注公众号,回复: 15749007 查看本文章
while(1)
        {
          if (cmd == 'A')
          {
            cmd = 0;
            VddCount = Read_Vddvalue();
            vddvalue = (VddCount*25)>>8; //计算方法:vdd*基准电压(这里是1.25)/(2^采样位数)
            buf[0] = vddvalue/10+'0'; //取整数部分
            buf[1] = '.';
            buf[2] = vddvalue%10 + '0'; //取小数部分
            UartSendString(buf,5);
          }
        }

选择其他通道

Sequence channel select. Selects the end of the sequence.A sequence can either be from AINOto AlIN7(SCH≤7) or from the differential input AINO-AlN1 to AIN6-AIN7(8 ≤ SCH≤ 11).Forother settings, only one conversions is performed.
顺序通道选择。选择序列的结尾。序列可以是从AINOTO AlIN 7(SCH≤7)或从差分输入AIN-AlN1到AIN6-AIN 7(8≤Sch≤11)。对于其他设置,只执行一次转换。
When read, these bits indicate the channel number on which a conversion is ongoing.
读取时,这些位指示正在进行转换的信道号。
在这里插入图片描述

完整例程

#include "ioCC2530.h"
#define HAL_ADC_REF_125V 0x00
#define HAL_ADC_DEC064 0x00
#define HAL_ADC_CHN_VDD3 0x0f
#define HAL_ADC_CHN_AIN0 0xf0
unsigned char cmd;
unsigned int Read_Vddvalue(void) 
{
  unsigned int value;
  unsigned char tmpADCCON3 = ADCCON3;
  ADCIF = 0;
  ADCCON3 =(HAL_ADC_REF_125V|HAL_ADC_DEC064|HAL_ADC_CHN_AIN0);
  while(!ADCIF);//中断等待,直到转换结束(1 : Interrupt pending)
  value = ADCL >> 2; //低2位,Not used. Always read as 0,右移2位,将低位清除。取7:2 有效位是ADC[5:0]
  value |= ((unsigned int )ADCH)<<6; //ADCH取7:0,有效位是ADC[13:6],故左移6位,再与低位或操作,共14位
  ADCCON3 = tmpADCCON3;
  return (value);
}

#pragma vector = URX0_VECTOR
__interrupt void UART0_ISR(void)
{
  URX0IF = 0; //清中断标志
  cmd = U0DBUF;
}

void UartSendString(char *Data,int len)
{
  int i;
  
  for(i = 0;i<len;i++)
  {
    U0DBUF = *Data++;
    while(UTX0IF == 0);
    UTX0IF = 0;
  }
}

/****************************************************************
串口(UART0)初始化函数:				
****************************************************************/
void InitUart(unsigned long int baudrate)
{
  
    CLKCONCMD &= ~0x40;                           //0: 32 MHz XOSC 与操作,仅设置0位,其他位为1,与后保持不变,设置系统时钟源为32MHZ晶振
    while(CLKCONSTA & 0x40);                      //等待晶振稳定
    CLKCONCMD &= ~0x47;                           // ~0x47=1011 1000,2:0 CLKSPD 001 R/W Clock speed. Cannot be higher than system clock setting given by the OSC bit
                                                  //setting. Indicates current system-clock frequency 000: 32 MHz,设置系统主时钟频率为32MHZ
    PERCFG = 0x00;			          //位外设控制寄存器USART 0的IO位置;0为P0口位置;
    P0SEL = 0x0c;				  //P0用作串口,P0.7 to P0.0 function select
                                                  //0: General-purpose I/O  1: Peripheral function
                                                  //0x0c=0000 1100,P0_2,P0_3用作串口,外设功能
    P2DIR &= ~0XC0;                               //0XC0=1100 0000,~0XC0=0011 1111,与操作,设置0位,P0优先作为UART0  
                                           //Port 0 peripheral priority control. These bits determine the order of priority in the case
                                        //when PERCFG assigns several peripherals to the same pins.
                                        //Detailed priority list:
                                        //00:
                                        //1st priority: USART 0
                                        //2nd priority: USART 1
                                        //3rd priority: Timer 1
   U0CSR |= 0X40;			  //允许接收
   switch(baudrate)
   {
   case 115200:
              U0GCR = 11;				
              U0BAUD = 216;				  //波特率设为115200
              break;
   case 9600:
              U0GCR = 8;				
              U0BAUD = 59;				  //波特率设为9600
              break;
   default:
              U0GCR = 8;				
              U0BAUD = 59;				  //默认波特率设为9600
              break;
   }
   UTX0IF = 0;
   U0CSR |= 0x40;                          //允许接收
   IEN0 |= 0x84;			 //开总中断,允许接收中断
}


/****************************************************************
主函数	
****************************************************************/
void main(void)
{	
        unsigned int vddvalue;
        unsigned int VddCount;
        char buf[5] = "0.0V";
        InitUart(115200);                                    //初始化串口
        while(1)
        {
          if (cmd == 'A')
          {
            cmd = 0;
            VddCount = Read_Vddvalue();
            vddvalue = (VddCount*25)>>8; //计算方法:vdd*基准电压(这里是1.25)/(2^采样位数)
            buf[0] = vddvalue/10+'0'; //取整数部分
            buf[1] = '.';
            buf[2] = vddvalue%10 + '0'; //取小数部分
            UartSendString(buf,5);
          }
        }
}

猜你喜欢

转载自blog.csdn.net/Medlar_CN/article/details/130750571