2014年3月29日

CC2530基础实验(4) —— UART及温度传感器

UART是串口的一种异步通信方式(同步方式为SPI)。CC2530有UART0和UART1两个端口可用于串口通信,两个端口功能完全相同,可独立工作。

串口的初始化主要由以下几个部分组成:

  1. 选择通信模式、开启中断

    以USART0为例,要使用UART模式,需要设置U0CSR的第7位为1。而中断这里主要指USART0在接收数据时触发的中断。与USART0接收相关的中断有URX0IE(接收中断使能)、IT1、EA(总中断使能)。而数据手册中提到,IT1总是为1的,所以实际上只需设置URX0IE和EA即可。代码如下:

         IT1 = 1;       // 总是为1,可以省略
     URX0IE  = 1;       // 接收中断使能
         EA  = 1;       // 总中断使能
      UTX0IF = 0;       // UART0 TX中断标志位清0
    

    注意这里我没有配置U0CSR,这是因为手册中提到,当配置接收使能时(U0CSR的第6位)需要确保UART被已经完全配置好,所以我在初始化的最后一步同时配置这两位。

  2. 选择接线方式、配置相应管脚

    CC2530支持两种接线模式,一种在P0,另一种在P2。但我的开发板原理图上显示似乎只支持默认的P0上的接线。

    PERCFG &= ~0x01;   // U0使用第一种接线方式
     P0SEL |= 0x0C;    // P0.2 P0.3为外设
    

    把PERCFG的第0位置0即是第一种接线方式,这也是上电后的默认值。另外还需要把涉及到的相应管脚配置为外设。

  3. 设置波特率

    波特率跟系统时钟密切相关,其设置需要操作两个寄存器U0BAUD和U0GCR。数据手册上给出了使用32M晶振时这两个寄存器的取值,如果在其他时钟频率下设置波特率则需要根据其提供的公式自行推导。

    U0BAUD = baud_m;
     U0GCR = baud_e;
    
    U0CSR |= 0xC0;    // UART模式,允许接收
    
  4. 开启接收功能

    代码见上文。

接下来可以通过串口来发送、接收数据(通常是字符串)。数据的发送是逐字符发送的,即逐字符以“U0DBUF赋值——等待发送标志——重置发送标识”循环。

#include "string.h"
void UART0Send(char data[]){
  U0CSR &= ~0x40;
  uchar cnt;
  int len = strlen(data);
  for (cnt = 0; cnt < len; cnt++){
    U0DBUF = data[cnt];
    while(!UTX0IF);
    UTX0IF = 0;
  }
  U0CSR |= 0x40;
}

需要注意的是在发送开始之前记得关闭接收功能,在发送完毕后记得重新开启接收功能。这是由于数据的收发都共用同一个寄存器,故发送时必须保证当前发送序列对U0DBF的独占。


温度传感器的实验需要注意的有以下几点:

  1. 初始化时需要将ATEST和TR0两个寄存器置1
  2. ADCL中低2位是无效的

采集温度的代码如下:

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 位无效 
   value |= (((uint)ADCH) << 4);
   
   return (value-1367.5)/4.5 + 5;  //根据 AD 值,计算出实际的温度,芯片手册有错,温度系数应该是4.5 /℃
}

在实验中发现这个温度传感器的精度并不高,这个计算公式我也没有在CC2530的数据手册里找到,最后从网上抄了一段过来。而这个公式跟实际温度还是有5度左右的误差,于是我又在后面加了个5来修正。网上也有一种说法是这个温度传感器不是线性的,TI给的这个公式本来就不太合适。

没有评论:

发表评论