第二部分 基础篇-第7章 CC2530温度串口显示(片内ADC)
程序员文章站
2022-04-01 22:04:23
...
1 理论分析
1.1 CC2530 的 ADC 介绍
CC2530 的 ADC 支持多达 14 位的模拟数字转换,具有多达 12 位的 ENOB(有效数字位)。它包括一个模拟多路转换器,具有多达 8 个各自可配置的通道;以及一个参考电压发生器。转换结果通过 DMA 写入存储器。还具有若干运行模式。
ADC 的主要特性如下:
可选的抽取率,这也设置了分辨率(7 到 12 位)8 个独立的输入通道,可接受单端或差分信号
参考电压可选为内部单端、外部单端、外部差分或 AVDD5
产生中断请求
转换结束时的 DMA 触发
温度传感器输入
电池测量功能
图2是 CC2530ADC 的操作图,这里面就是讲解 ADC 是怎么操作的,待会我们的实验就按照这个图来开展。
1.2流程图
下面是本实验的流程图,大家可以结合这个图来学习编写程序
2实验详解
2.1实验目的
1)、通过实验掌握CC2530 芯片串口配置与使用
2)、学会使用 CC2530 片内温度传感器。
2.2实验设备
硬件:PC 机一台 ZB2530(底板、核心板、仿真器、USB 线) 一套
软件:2000/XP/win7 系统,IAR 8.20 集成开发环境、串口助手
2.3相关电路图
2.4实验分析
本实验需要用到IO口串口、中断及ADC等寄存器,在前面已经对IO口、串口、中断等寄存器详细分析了,在此只给出ADC相关寄存器。相关寄存器ADCON1、 ADCON2、ADCON1、TR0、ATEST如下表所示.
ADCCON3 (0xB6)–ADC控制3
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实验现象
打开串口,进行如下设置,会看到接收区温度自动更新。
小贴士:
头文件的使用
在本例程中,我们写了“Uart.h”“initUART_Timer.h”,需要引用该头文件。
方法一:
在 option 里设置路径,找到例程文件夹,打开 include 文件夹,复制路径,粘贴到下面这个位置。
方法二:
将”initUART_Timer.h”,放到工程目录下即可。