CC2530实现ADC采集电池电压并通过串口发送

一、CC2530ADC模块

1. 可选取的抽取率,设置分辨率(7~12位)
2. 8个独立的输入通道,可接收单端或差分信号
3. 参考电压可选为内部单端、外部单端、外部差分或AVDD5
4. 单通道转换结束可产生中断请求
5. 序列转换结束可发出DMA触发
6. 可将片内温度传感器作为输入
7. 电池电压测量功能,可以选择AVDD5/3 的电压作为一个 ADC 输入

二、CC2530ADC寄存器

①ADCL、ADCH


        从图中可以看出,ADC的采样值由ADCH和ADCL共同组成,因此在读取数据的时候需要进行数据处理。

② ADCCON1

Bit7:EOC位,当ADC转换完成,该位赋值为1,读取ADCH时,它就被清除。
Bit6:ST位,当该位为1的时候开启ADC转换
Bit[5:4]:设置ADC触发的事件,设置为ST为1开启触发

③ ADCCON3

Bit[7:6]:设置ADC的参考电压引脚,本实验设置为AVDD5
Bit[5:4]:设置ADC的采样精度,本实验设置为12,实际上计算的时候为13
Bit[3:0] :设置ADC单个转换的通道,本实验设置为VDD/3

三、实验代码

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

typedef unsigned char uchar;
typedef unsigned int  uint;


//32MHZ晶振ms延时函数
void DelayMS(uint msec)
{ 
    uint i,j;
    
    for (i=0; i<msec; i++)
        for (j=0; j<1070; j++);
}

void InitAdc(void)
{
  ADCH = 0; //ADCH寄存器清0,清EOC标志
  ADCCON3 = 0xBF; //设置ADC参考电压为AVDD5引脚,ADC精度12位,ADC通道15为VDD/3
  ADCCON1 |= 0X70;  //设置ADC触发事件为.ST = 1,启动一次AD转换
}



//串口寄存器初始化
void InitUart(void)
{
  PERCFG = 0x00;       //外设控制寄存器 USART 0的IO位置:0为P0口位置1 
  P0SEL = 0x0c;        //P0_2,P0_3用作(外设功能)
  P2DIR &= ~0xC0;// 1100 0000 将外设设置为串口0优先
  U0UCR = 0x00; //禁止流控制 8位数据传输 禁止奇偶校验 1位停止位
  U0CSR |= 0x80;           //设置为UART模式
  
  U0GCR |= 11;	//设置数据LSB和波特率
  U0BAUD |= 216;           //波特率设为115200
  
  UTX0IF = 0;              //UART0 TX中断标志初始置位0
  U0CSR |= 0x40;           //允许接收 
  IEN0 |= 0x84;            //开总中断允许接收中断
}

//串口发送函数
//string:发送的字符串
//len:发送的数据长度
void UartSend_string(char *Data, int len)
{
  uint i;
  for(i = 0;i < len;i++) {
   U0DBUF = *Data++; 
   while(UTX0IF == 0);//等待发送完成
   UTX0IF = 0;  //发送中断标志位置0
  }
  
}

void main(void)
{	
    float num;  
    char strTemp[12]={0};
    unsigned short reading;

    CLKCONCMD &= ~0x40;                        //设置系统时钟源为32MHZ晶振
    while(CLKCONSTA & 0x40);                   //等待晶振稳定为32M
    CLKCONCMD &= ~0x47;                        //设置系统主时钟频率为32MHZ   
    InitUart();                                //调用串口初始化函数   
    InitAdc();  //ADCCON3是单次转换
    while(1)
    {
      char val = ADCCON1;
      if(val &= 0x80)
      {     
        reading = ADCL;
        reading |= ADCH << 8; 
        reading >>= 2;
        ADCCON1 |= 0x40; //开始下一转换
        
        num = (float)(reading)*3.3/8192; //有一位符号位,取 2^13;
        //定参考电压为 3.3V 14 位精确度
        
        sprintf(strTemp,"vol:%.02fV\r\n", num);//将浮点数转成字符串
        UartSend_string(strTemp,12); //串口送数
      }
      DelayMS(1000);
    }
}

        每间隔1000MS,将电池电压通过串口发送给上位机。

使用ZigBee协议和CC2530芯片以及定时器1来实现这个功能需要几个步骤: 1. **初始化硬件**: 首先,你需要配置CC2530的定时器1,将其设置为模式1,以便每过一定时间就触发中断。通常这涉及到设置计数器的初始值、分频因子和工作模式。 ```c // 定义定时器1的相关寄存器地址 volatile uint16_t Timer1Control = CC2530_TIMER1_CONTROL; volatile uint16_t Timer1Load = CC2530_TIMER1_LOAD; // 设置定时器1的工作模式和初始值 Timer1Control &= ~TIMER1_MODE; // 清除当前工作模式 Timer1Control |= TIMER1_MODE_1; // 设置为模式1 Timer1Load = 1000 - 1; // 1000 * f_cpu / timer1_freq,这里假设f_cpu是系统时钟频率 ``` 2. **ADC配置**: P0.2作为模拟输入,你需要配置CC2530ADC模块,让它指向P0.2引脚,选择AVDD5作为参考电压。 ```c // ADC模块配置 volatile uint16_t ADCControl = CC2530_ADC_CONTROL; ADCControl &= ~ADC_CHANNEL; // 清除当前通道 ADCControl |= ADC_CHANNEL_2; // 设置为P0.2 ADCControl |= ADC_REFSEL_AVDD5; // 使用AVDD5作为参考电压 // 开启ADC启动转换 ADCControl |= ADC_START Conversion; ``` 3. **定时器中断服务函数**: 当定时器1溢出时,会触发中断。在这个函数中读取ADC的结果,然后通过串口通信发送到PC。 ```c void IRAM_ATTR Timer1_IRQHandler() { uint16_t adcResult = readADC(); // 获取ADC的值 sendToPC(adcResult); // 通过Serial或其他通信方式发送到PC // 更新定时器1的计数值,继续计时 Timer1Load = 1000 - 1; // 重新加载计数器 } ``` 4. **串口通信**: 要在PC上显示结果,你需要在主循环中处理来自CC2530串口数据。可以使用标准的UART库来实现这一点。 ```c void serialSend(uint16_t value) { // 发送ADC值到串口 // 使用your_uart_library函数 your_uart_library(value); } void main() { enableTimer1Interrupts(); // ...其他初始化... while(1) { /* 等待串口接收操作 */ } } ``` 记得在开始之前确保所有相关的库和头文件都已经包含,以及串口ADC的驱动支持。此外,别忘了关闭中断处理完一次转换后再开启它,以避免不必要的干扰。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值