Zigbee之ADC片内温度传感器

实验片内温度传感器

代码网上找的,然后自己琢磨了下。

/***********系统时钟初始化*********************************/
void InitClock(void)
{   
    CLKCONCMD &= ~0x40;              //设置系统时钟源为 32MHZ晶振
    while(CLKCONSTA & 0x40);         //等待晶振稳定 
    CLKCONCMD &= ~0x47;              //设置系统主时钟频率为 32MHZ
}

在这里插入图片描述
在这里插入图片描述

/***************定时器初始化**********************/
void InitT3(void)
{
    T3CCTL0 = 0x44;        //0100 0100 T3CCTL0 (0xCC),CH0 中断使能,CH0 比较模式
    T3CC0 = 0xFA;          //T3CC0设置为250
    T3CTL |= 0x9A;         //启动T3计数器,计数时钟为16分频。使用MODULO模式
    IEN1 |= 0x08;     
    IEN0 |= 0x80;          //开总中断,开T3中断
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

/****************温度传感器初始化函数*******************/
void InitSensor(void)
{ 
   DISABLE_ALL_INTERRUPTS();     //关闭所有中断 
   InitClock();                  //设置系统主时钟为 32M 
   TR0=0x01;                     //设置为1来连接温度传感器到SOC_ADC
   ATEST=0x01;                   //使能温度传感
}   

在这里插入图片描述

在这里插入图片描述

/**************获取传感器温度值并返回***********************/
float GetTemperature(void)
{ 
   uint  value; 
   
   ADCCON3  = (0x3E);            //0011 1110 选择1.25V为参考电压;14位分辨率;对片内温度传感器采样
   ADCCON1 |= 0x30;              //0011 0000 选择ADC的启动模式为手动
   ADCCON1 |= 0x40;              //启动AD转化  
   while(!(ADCCON1 & 0x80));     //等待 AD 转换完成 
   value =  ADCL >> 4;           //ADCL 寄存器低 2 位无效,由于他只有12位有效,ADCL寄存器低4位无效。
   value |= (((uint)ADCH) << 4);
   
   return (value-1367.5)/4.5-5;  //根据 AD 值,计算出实际的温度,芯片手册有错,温度系数应该是4.5 /℃
                                 //进行温度校正,这里减去5℃(不同芯片根据具体情况校正)
}

ADCCON3
在这里插入图片描述
ADCCON1
在这里插入图片描述
完整代码

#include <ioCC2530.h>
#include <stdio.h>
#include <string.h>

typedef unsigned char uchar;
typedef unsigned int  uint;

#define DISABLE_ALL_INTERRUPTS() (IEN0 = IEN1 = IEN2 = 0x00)//关中断

/*************************延时*************************************/
void DelayMS(uint msec)
{ 
    uint i,j;
    
    for (i=0; i<msec; i++)
        for (j=0; j<1060; j++);
}

/***********系统时钟初始化*********************************/
void InitClock(void)
{   
    CLKCONCMD &= ~0x40;              //设置系统时钟源为 32MHZ晶振
    while(CLKCONSTA & 0x40);         //等待晶振稳定 
    CLKCONCMD &= ~0x47;              //设置系统主时钟频率为 32MHZ
}

/***************定时器初始化**********************/
void InitT3(void)
{
    T3CCTL0 = 0x44;        //T3CCTL0 (0xCC),CH0 中断使能,CH0 比较模式
    T3CC0 = 0xFA;          //T3CC0设置为250
    T3CTL |= 0x9A;         //启动T3计数器,计数时钟为16分频。使用MODULO模式
    IEN1 |= 0x08;     
    IEN0 |= 0x80;          //开总中断,开T3中断
}

/***********串口初始化***********************************************/
void InitUART(void)
{
    PERCFG = 0x00;                   //位置1 P0口
    P0SEL = 0x3C;                    //P0用作串口
    
    P2DIR &= ~0xC0;                  //P0优先作为UART0    
    U0CSR |= 0x80;                   //串口设置为UART方式
    U0GCR |= 11;				
    U0BAUD |= 216;                   //波特率设为115200
    
    UTX0IF = 0;                      //UART0 TX中断标志初始置位0
    U0CSR |= 0x40;                   //允许接收
    IEN0 |= 0x84;                    //开总中断,接收中断
}

/****************温度传感器初始化函数*******************/
void InitSensor(void)
{ 
   DISABLE_ALL_INTERRUPTS();     //关闭所有中断 
   InitClock();                  //设置系统主时钟为 32M 
   TR0=0x01;                     //设置为1来连接温度传感器到SOC_ADC
   ATEST=0x01;                   //使能温度传感
}   


/****************串口发送函数*******************************/
void UartSendString(char *Data, int len)
{
    uint i;
    
    for(i=0; i<len; i++)
    {
        U0DBUF = *Data++;
        while(UTX0IF == 0);
        UTX0IF = 0;
    }
   
    U0DBUF = 0x0A;                   //输出换行
    while(UTX0IF == 0);
    UTX0IF = 0;
}


/**************获取传感器温度值并返回***********************/
float GetTemperature(void)
{ 
   uint  value; 
   
   ADCCON3  = (0x3E);            //选择1.25V为参考电压;14位分辨率;对片内温度传感器采样
   ADCCON1 |= 0x30;              //选择ADC的启动模式为手动
   ADCCON1 |= 0x40;              //启动AD转化  
   while(!(ADCCON1 & 0x80));     //等待 AD 转换完成 
   value =  ADCL >> 4;           //ADCL 寄存器低 2 位无效,由于他只有12位有效,ADCL寄存器低4位无效。网络上很多代码这里都是右移两位,那是不对的
   value |= (((uint)ADCH) << 4);
   
   return (value-1367.5)/4.5-5;  //根据 AD 值,计算出实际的温度,芯片手册有错,温度系数应该是4.5 /℃
                                 //进行温度校正,这里减去5℃(不同芯片根据具体情况校正)
}

/****************************************************************************
* 程序入口函数
****************************************************************************/
void main(void) 
{   
    char i; 
    float fSum, AvgTemp;   
    char strTemp[6];
    
    InitUART();                           //初始化串口 
    InitSensor();                         //初始化 ADC 
    
    while(1) 
    {  
        fSum = 0;
        for (i=0; i<64; i++) 
        {    
            fSum += GetTemperature();     //取64次温度总和
        }
        AvgTemp = fSum/64;                //取64次温度平均数
       
        memset(strTemp, 0, 6);
        sprintf(strTemp,"%.02f", AvgTemp);//将浮点数转成字符串,保留2位小数位
        UartSendString(strTemp, 5);       //通过串口发给电脑显示芯片温度
        DelayMS(1000);                    //延时
    } 
}

在这里插入图片描述
这俩东西要根据你自己的串口来。我的zigbeeUSB数据线连接COM4,波特率代码里是115200.

ADC

cc2530中文手册里的。
在这里插入图片描述
12.2 ADC 操作
本节描述了 ADC 的一般安装和操作,并描述了 CPU 存取的 ADC 控制和状态寄存器的使用。
12.2.1 ADC 输入
端口 0 引脚的信号可以用作 ADC 输入。在下面的描述中,这些端口引脚指的是 AIN0-AIN7 引脚。输入引脚 AIN0-AIN7 是连接到 ADC 的。
可以把输入配置为单端或差分输入。在选择差分输入的情况下,差分输入包括输入对AIN0-1、AIN2-3、AIN4-5 和 AIN6-7。
注意负电压不适用于这些引脚,大于 VDD(未调节电压)的电压也不能。它们之间的差别是在差分模式下转换。它是在差分模式下转换的输入对之间的差。
除了输入引脚 AIN0-AIN7,片上温度传感器的输出也可以选择作为 ADC 的输入,用于温度测量。为此寄存器 TR0.ADCTM 和 ATEST.ATESTCTRL 必须分别按 要求设置。
还可以输入一个对应 AVDD5/3 的电压作为一个 ADC 输入。这个输入允许诸如需要在应用中实现一个电池监测器的功能。注意在这种情况下参考电压不能取决于电源电压,比如 AVDD5 电压不能用作一个参考电压。
单端电压输入 AIN0 到 AIN7 以通道号码 0 到 7 表示。通道号码 8 到 11 表示差分输入,由 AIN0–AIN1、AIN2–AIN3、AIN4–AIN5 和 AIN6–AIN7 组成。通道号码 12 到 15 表示 G N D(12)温度传感器(14),和 AVDD5/3
(15)。这些值在 ADCCON2.SCH 和 ADCCON3.SCH 域中使用。
12.2.2 ADC 转换序列
ADC 将执行一系列的转换,并把结果移动到存储器(通过 DMA),不需要任何 CPU 干预。
转换序列可以被 APCFG 寄存器影响,八位模拟输入来自 I/O 引脚,不必经过编程变为模拟输入。如果一个通道正常情况下应是序列的一部分,但是相应的模拟输入在 APCFG 中禁用,那么通道将被跳过。
当使用差分输入,处于差分对的两个引脚都必须在 APCFG 寄存器中设置为模拟输入引脚。
ADCCON2.SCH 寄存器位用于定义一个 ADC 转换序列,它来自 ADC 输入。
如果 ADCCON2.SCH 设置为一个小于 8 的值,转换序列包括一个转换,来自每个通道,从 0 往上,包括 ADCCON2.SCH 编程的通道号码。
当 ADCCON2.SCH 设置为一个在 8 和 12 之间的值,序列包括差分输入,从通道 8 开始,在已编程的通道结束。
对于 ADCCON2.SCH 大于或等于 12,序列仅包括所选的通道
12.2.3 单个 ADC 转换
除了这一转换序列,ADC 可以编程为从任何通道执行一个转换。这样一个转换通过写 ADCCON3 寄存器
触发。除非一个转换序列已经正在进行,转换立即开始,在这种情况下序列一完成单个转换就被执行。
12.2.4 ADC 运行模式
本节描述了运行模式和初始化转换。
ADC 有三种控制寄存器:ADCCON1, ADCCON2 和 ADCCON3。这些寄存器用于配置 ADC,并报告结果。
ADCCON1.EOC 位是一个状态位,当一个转换结束时,设置为高电平;当读取 ADCH 时,它就被清除。
ADCCON1.ST 位用于启动一个转换序列。当这个位设置为高电平,ADCCON1.STSEL 是 11,且当前没有转换正在运行时,就启动一个序列。当这个序列转换完成,这个位就被自动清除。
ADCCON1.STSEL 位选择哪个事件将启动一个新的转换序列。该选项可以选择为外部引脚 P2.0 上升沿或外部引脚事件,之前序列的结束事件,定时器 1 的通道 0 比较事件或 ADCCON1.ST 是 1。
ADCCON2 寄存器控制转换序列是如何执行的。
ADCCON2.SREF 用于选择参考电压。参考电压只能在没有转换运行的时候修改。
ADCCON2.SDIV 位选择抽取率(并因此也设置了分辨率和完成一个转换所需的时间,或样本率)。抽取率只能在没有转换运行的时候修改。转换序列的最后一个通道由 ADCCON2.SCH 位选择,如上所述。
ADCCON3 寄存器控制单个转换的通道号码、参考电压和抽取率。单个转换在寄存器 ADCCON3 写入后将立即发生,或如果一个转换序列正在进行,该序列结束之后立即发生。该寄存器位的编码和 ADCCON2 是完全一样的。
12.2.5 ADC 转换结果
数字转换结果以 2 的补码形式表示。对于单端配置,结果总是为正。这是因为结果是输入信号和地面之间的差值,它总是一个正符号数(Vconv=Vinp-Vinn,其中 Vinn=0V)。当输入幅度等于所选的电压参考 VREF时,达到最大值。对于差分配置,两个引脚对之间的差分被转换,这个差分可以是负符号数。对于抽取率是 512的一个数字转换结果的 12 位 MSB,当模拟输入 Vconv 等于 VREF 时,数字转换结果是 2047。当模拟输入等于-VREF 时,数字转换结果是-2048。 当 ADCCON1.EOC 设置为 1 时,数字转换结果是可以获得的,且结果放在 ADCH 和 ADCL 中。注意转换结果总是驻留在 ADCH 和 ADCL 寄存器组合的 MSB 段中。当读取 ADCCON2.SCH 位时,它们将指示转换在哪个通道上进行。ADCL 和 ADCH 中的结果一般适用于
之前的转换。如果转换序列已经结束,ADCCON2.SCH 的值大于最后一个通道号码,但是如果最后写入ADCCON2.SCH 的通道号码是 12 或更大,将读回同一个值。
12.2.6 ADC 参考电压
模拟数字转换的正参考电压可选择为一个内部生成的电压,AVDD5 引脚,适用于 AIN7 输入引脚的外部电压,或适用于 AIN6-AIN7 输入引脚的差分电压。转换结果的准确性取决于参考电压的稳定性和噪音属性。希望的电压有偏差会导致 ADC 增益误差,与希望电压和实际电压的比例成正比。参考电压的噪音必须低于 ADC 的量化噪音,以确保达到规定的 SNR。
12.2.7 ADC 转换时间
ADC 只能运行在 32 MHz XOSC 上,用户不能整除系统时钟。实际 ADC 采样的 4 MHz 的频率由固定的内部划分器产生。执行一个转换所需的时间取决于所选的抽取率。总的来说,转换时间由以下公式给定:
Tconv = (抽取率 + 16) x 0.25 μs。
12.2.8 ADC 中断
当通过写 ADCCON3 触发的一个单个转换完成时,ADC 将产生一个中断。当完成一个序列转换时,不产生一个中断。
12.2.9 ADC DMA 触发
每完成一个序列转换,ADC 将产生一个 DMA 触发。当完成一个单个转换,不产生 DMA 触发。对于 ADCCON2.SCH 中头 8 位可能的设置所定义的八个通道,每一个都有一个 DMA 触发。当通道中一个新的样本准备转换,DMA 触发是活动的。DMA 触发命名为表 8-1 中的 ADC_CHsd,其中 s 是单端通道,d 是差分通道。
另外,还有一个 DMA 触发 ADC_CHALL,当 ADC 转换序列的任何通道中有新的数据准备好时,它是活动的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值