欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

第二部分 基础篇-第7章 CC2530温度串口显示(片内ADC)

程序员文章站 2022-04-01 22:04:23
...

1 理论分析

1.1 CC2530 的 ADC 介绍

CC2530 的 ADC 支持多达 14 位的模拟数字转换,具有多达 12 位的 ENOB(有效数字位)。它包括一个模拟多路转换器,具有多达 8 个各自可配置的通道;以及一个参考电压发生器。转换结果通过 DMA 写入存储器。还具有若干运行模式。

第二部分 基础篇-第7章 CC2530温度串口显示(片内ADC)

图1 ADC方框图

ADC 的主要特性如下:
 可选的抽取率,这也设置了分辨率(7 到 12 位)8 个独立的输入通道,可接受单端或差分信号
 参考电压可选为内部单端、外部单端、外部差分或 AVDD5
 产生中断请求
 转换结束时的 DMA 触发
 温度传感器输入
 电池测量功能
第二部分 基础篇-第7章 CC2530温度串口显示(片内ADC)

图2 ADC 操作

图2是 CC2530ADC 的操作图,这里面就是讲解 ADC 是怎么操作的,待会我们的实验就按照这个图来开展。

1.2流程图

下面是本实验的流程图,大家可以结合这个图来学习编写程序

第二部分 基础篇-第7章 CC2530温度串口显示(片内ADC)

图.3 流程图

2实验详解

2.1实验目的

1)、通过实验掌握CC2530 芯片串口配置与使用
2)、学会使用 CC2530 片内温度传感器。

2.2实验设备

硬件:PC 机一台 ZB2530(底板、核心板、仿真器、USB 线) 一套
软件:2000/XP/win7 系统,IAR 8.20 集成开发环境、串口助手

2.3相关电路图

第二部分 基础篇-第7章 CC2530温度串口显示(片内ADC)

图4 FT232

第二部分 基础篇-第7章 CC2530温度串口显示(片内ADC)

图5 USB

2.4实验分析

本实验需要用到IO口串口、中断及ADC等寄存器,在前面已经对IO口、串口、中断等寄存器详细分析了,在此只给出ADC相关寄存器。相关寄存器ADCON1、 ADCON2、ADCON1、TR0、ATEST如下表所示.

表1 ADC控制1

第二部分 基础篇-第7章 CC2530温度串口显示(片内ADC)第二部分 基础篇-第7章 CC2530温度串口显示(片内ADC)

表2 ADC控制2

第二部分 基础篇-第7章 CC2530温度串口显示(片内ADC)第二部分 基础篇-第7章 CC2530温度串口显示(片内ADC)第二部分 基础篇-第7章 CC2530温度串口显示(片内ADC)

表3 ADC控制3

ADCCON3 (0xB6)–ADC控制3
第二部分 基础篇-第7章 CC2530温度串口显示(片内ADC)第二部分 基础篇-第7章 CC2530温度串口显示(片内ADC)

表4测试寄存器0

第二部分 基础篇-第7章 CC2530温度串口显示(片内ADC)

表5 模拟测试控制

第二部分 基础篇-第7章 CC2530温度串口显示(片内ADC)

2.5参考代码(部分代码)

/**Includes*********************************************************************/
#include <iocc2530.h>
#include <stdio.h>
#include <string.h>

/**宏定义***********************************************************************/
#define uchar unsigned char
#define uint unsigned int
#define int16 short 
#define uint16 unsigned short 

/**函数声明*********************************************************************/
void initclock(void);
void inituart0(void);
void uarttx_send_string(char *data,int len);
void Delay(uint xms);
uint gettemperature(void);

/**全局变量*********************************************************************/
int16 avgtemp;


/**
  * @brief     主函数
  * @param     None
  * @retval    None
  */
void main(void)
{
  char i;
  char tempvalue[30];

  initclock();//初始化时钟  
  inituart0();//初始化串口
  IEN0=IEN1=IEN2=0X00;//关闭所有中断
  ATEST=0X01;//开启温度传感器
  TR0=0X01;//将温度传感器与ADC连接起来

  while(1)
  {
    avgtemp=0;
    for(i=0;i<64;i++)
    {
      avgtemp +=gettemperature();//取得温度数,加上原平均值
      if(i>0) avgtemp>>=1;//除以2,取得平均值
    }

    memset(tempvalue, 0, 30);
    sprintf(tempvalue, "AD Data= %dC", (int)avgtemp);
    uarttx_send_string(tempvalue,strlen(tempvalue));
    //uarttx_send_string("\n",1);
    Delay(3000);
  }
}

/**
  * @brief     初始化时钟
  * @param     None
  * @retval    None
  */
void initclock(void)
{
  CLKCONCMD &=0XBF;//系统时钟源选择32MHZ XOSC
  CLKCONCMD &=0XF8;//系统时钟频率为32MHZ

  CLKCONCMD |=0X28;
  CLKCONCMD &=0XEF;//定时时钟频率为1MHZ
  while(CLKCONSTA & 0X40);//等待时钟稳定
}

/**
  * @brief     初始化串口0函数
  * @param     None
  * @retval    None
  */
void inituart0(void)
{
  PERCFG = 0x00;                 //位置1 P0口
  P0SEL = 0x3c;              //P0用作串口

  P2DIR &= ~0XC0;                       //P0优先作为UART0    
  U0CSR |= 0x80;                    //串口设置为UART方式
  U0GCR |= 11;              
  U0BAUD |= 216;               //波特率设为115200

  UTX0IF = 1;                          //UART0 TX中断标志初始置位1  
  U0CSR |= 0X40;               //允许接收
  IEN0 |= 0x84;                //开总中断,接收中断
}


/**
  * @brief     串口发送字符串函数
  * @param     date  数据‘
               len   长度
  * @retval    None
  */
void uarttx_send_string(char *data,int len)
{
  int j;
  for(j=0;j<len;j++)
  {
    U0DBUF=*data++;
    while(UTX0IF==0);
    UTX0IF=0;
  }
  U0DBUF=0X0A;//换行
  while(UTX0IF==0);
  UTX0IF=0;  
}

/**
  * @brief     延时函数
  * @param     xms   延时大小
  * @retval    None
  */
void Delay(uint xms)
{
   uint i,j;
    for(i=xms;i>0;i--)
     for(j=587;j>0;j--);   
}

/**
  * @brief     读取温度传感器AD值函数
  * @param     None
  * @retval    None
  */
uint gettemperature(void)
{
  uint i;
  uint16 adcvalue;
  uint16 value;

  adcvalue=0;
  for(i=0;i<4;i++)
  {
    ADCCON3 |=0X0E;//单通道AD转换源为温度传感器
    ADCCON3 &=0X3F;//单通道AD转换参考电压为1.25内部电压
    ADCCON3 |=0X30;//单通道AD转换分辨率为512DEC,12有效
    ADCCON1 |=0X30;//ADC启动方式选择为ADCCON1.ST=1事件
    ADCCON1 |=0X40;//ADC启动转换

    while(!ADCCON1&0X80);//等待AD转换完成
    value =  ADCL >> 2; //ADCL寄存器低2位无效
    value |=(((uint16)ADCH)<<6);//连接ADCH和ADCL,并赋值给value
    adcvalue +=value;//adcvalue被赋值为4次AD值之和
  }
  value=adcvalue>>2;//累加除以4,得到平均值
  //return (((value) >> 4) - 315)/10;     //根据AD值,计算出实际的温度
  return (uint)(((value>>2)-1367.5)/4.5-5);

}   

【参考代码-1-1】
注意:上述参考代码值列出部分,要看整个代码请查看元工程。另外,可以参考该部分的参考代码,上述代码是在参考代码的基础上完善的,参考代码比较简单,建议先从参考代码开始学习,如果你有OLED屏,插在开发板上就可显示温度,不用串口显示,另外OLED会在后续的教程中讲到。

2.6实验现象

打开串口,进行如下设置,会看到接收区温度自动更新。

第二部分 基础篇-第7章 CC2530温度串口显示(片内ADC)

图6实验现象

小贴士:

头文件的使用
在本例程中,我们写了“Uart.h”“initUART_Timer.h”,需要引用该头文件。
方法一:
在 option 里设置路径,找到例程文件夹,打开 include 文件夹,复制路径,粘贴到下面这个位置。

第二部分 基础篇-第7章 CC2530温度串口显示(片内ADC)

图7

方法二:
将”initUART_Timer.h”,放到工程目录下即可。

本章参考代码

点击进入

相关标签: CC2530 ADC