zoukankan      html  css  js  c++  java
  • RIOT 技术笔记-06 RIOT操作系统中 CC2538的ADC使用

    ADC简介

    ADC的作用:采集传感器的数据,测量输入电压,检查电池电量剩余,监测温湿度等。



           RIOT操作系统,没有提供ADC的应用函数。因此我们需要自己移植,当然,需要自己移植的也是很少的,大部分都有的。我是从cc2530中移植过来的。adc采集的时间是微妙级的,大概100us就可以采集一次了。时间非常短。

            太详细的我就仔细说了,相信,只要花心思,看代码加上cc2538的数据手册也是可以理解的。。一定要去看看数据手册,看了数据手册就知道了我为什么代码里要那样写了。。。。
    下面是cc2538adc.c文件

        #include <stdio.h>
        #include "cc2538.h"    
        #include "cc2538adc.h"    
         
         
        void Adc_GPIO_Init(void)//这里可以自己修改端口
        {    
            gpio_software_control(GPIO_PA4);    
            gpio_dir_input(GPIO_PA4);
            IOC_PXX_OVER[GPIO_PA4] = IOC_OVERRIDE_ANA;
        }
         
        void Adc_Init_2538(uint8_t channel)
        {        
            Adc_GPIO_Init();
            //配置寄存器SOC_ADC_ADCCON1
            //0x03,也就是0000 0011最后两位是需要被保留的,不能动,因此一或过去就置1了
            SOC_ADC_ADCCON1 |= 0x03;                //0x03   0000 0011
            SOC_ADC_ADCCON1 |= ADC_STSEL_ST ;         //0x30   0011 0000    模式
            SOC_ADC_ADCCON1 |= ADC_RAND_NORM ;        
         
        /*
        //连续转换才需要    ,因为单次转换,这里目前不需要                        
            SOC_ADC_ADCCON2 |= ADC_REF_AVDD;        //参考电压的设定                                    低6第7位
            SOC_ADC_ADCCON2 |= ADC_DEC_10Bit;        //精度的设定,                                        第4第5位
            SOC_ADC_ADCCON2 |= ADC_CHN_GND;            //通道的选择,这里默认adc那么外部应交电源电压        低4位
        */    
         
        //刚开始转换,前一次转换不出东西的,这里多转换几次,跳过这个bug,,因此下面多转换了几次             
              for(uint8_t i=0;i<10;i++)
              {
                  SOC_ADC_ADCCON3 |= ADC_REF_V;  
                  SOC_ADC_ADCCON3 |= ADC_DEC_12Bit;  
                  SOC_ADC_ADCCON3 |= channel;      
                while ((SOC_ADC_ADCCON1 & ADC_EOC) != ADC_EOC);
                
                SOC_ADC_ADCCON3 |= ADC_REF_V;  
                  SOC_ADC_ADCCON3 |= ADC_DEC_12Bit;  
                  SOC_ADC_ADCCON3 |= channel;
                while ((SOC_ADC_ADCCON1 & ADC_EOC) != ADC_EOC);
              }
              
        }
         
        uint16_t Adc_Read(uint8_t channel)
        {
            uint16_t      result         = 0;
            uint16_t      reading     = 0;
              
              for(uint8_t j=0;j<5;j++)    //一次采集5次求平均值,这里可以自己修改
              {
                  SOC_ADC_ADCCON3 |= ADC_REF_V;                    //选择参考电压
                SOC_ADC_ADCCON3 |= ADC_DEC_12Bit;                //选择采集位数
                SOC_ADC_ADCCON3 |= channel;                        //选择通道    
                SOC_ADC_ADCCON1 |= 0x30;                        //st = 0011,设置事件
                SOC_ADC_ADCCON1 |= 0x40;                        //st = 0100,开始转换            
                while ((SOC_ADC_ADCCON1 & ADC_EOC) != ADC_EOC); //等待转换结束
                
                
                  reading  = SOC_ADC_ADCL;                //SOC_ADC_ADCL,SOC_ADC_ADCH这两个寄存器只能读不能写
                  reading |= SOC_ADC_ADCH << 8;
                  reading  = reading >> 3;                //因为最后两位是没用的,数据手册有说明
                  if(j!=0)                                //舍掉第一位                        
                  {
                      result  += reading;
                  }
                  
              }
            result = result/4;                            //上面测试了5次,舍掉了第一次,还有4次,求平均值
            return ((uint16_t)result);
        }
         
         
         


    下面是cc2538adc.h文件

        #ifndef __CC2538ADC_H
        #define __CC2538ADC_H
         
        #include "cpu_conf.h"
         
         
        #define ADC_EOC         0x80    /* 结束转换 */
        #define ADC_START       0x40    /* 开始转换,未结束*/
         
         
        //这是ADCCON1的设定&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
         
        //这是最高位,基本默认为0,因此就不动了                                                                第7位
        #define ADC_ECO_Y       0x80    /*转换完毕之后清除结果 */
        #define ADC_ECO_N       0x00    /*转换完毕之后不清除结果 */
         
        //这是第6位,基本默认为0,因此就不动了                                                                第6位
        #define ADC_ST_0        0x00
        #define ADC_ST_1        0x40
         
        //寄存器STSEL,的位,具体看数据手册,在寄存器的                                                        第4和第5位,
        #define ADC_STSEL_EXT   0x00    /* Not implemented */
        #define ADC_STSEL_FULL  0x10    /* Full Speed, No Trigger */
        #define ADC_STSEL_T1C0  0x20    /* Timer1, Channel 0 Compare Event Trigger */
        #define ADC_STSEL_ST    0x30    /* ADCCON1.ST =1 Trigger */
         
        //随机数控制器的设定
        #define ADC_RAND_NORM   0x00    /* Normal Operation */
        #define ADC_RAND_LFSR   0x04    /* Clock LFSR */
        #define ADC_RAND_SEED   0x08    /* Seed Modulator */
        #define ADC_RAND_STOP   0x0c    /* Stop Random Generator */
        #define ADC_RAND_BITS   0x0c    /* Bits [3:2] */
         
        //这是ADCCON2的设定&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
        #define ADC_DEC_7Bit    0x00    /* Decimate by 64 :  7 -bit resolution */
        #define ADC_DEC_9Bit     0x10    /* Decimate by 128 : 9 -bit resolution */
        #define ADC_DEC_10Bit    0x20    /* Decimate by 256 : 10-bit resolution */
        #define ADC_DEC_12Bit     0x30    /* Decimate by 512 : 12-bit resolution */
         
        #define ADC_CHN_AIN0    0x00    /* AIN0 */
        #define ADC_CHN_AIN1    0x01    /* AIN1 */
        #define ADC_CHN_AIN2    0x02    /* AIN2 */
        #define ADC_CHN_AIN3    0x03    /* AIN3 */
        #define ADC_CHN_AIN4    0x04    /* AIN4 */
        #define ADC_CHN_AIN5    0x05    /* AIN5 */
        #define ADC_CHN_AIN6    0x06    /* AIN6 */
        #define ADC_CHN_AIN7    0x07    /* AIN7 */
        #define ADC_CHN_A0A1    0x08    /* AIN0,AIN1 */
        #define ADC_CHN_A2A3    0x09    /* AIN2,AIN3 */
        #define ADC_CHN_A4A5    0x0a    /* AIN4,AIN5 */
        #define ADC_CHN_A6A7    0x0b    /* AIN6,AIN7 */
        #define ADC_CHN_GND     0x0c    /* GND */
        #define ADC_CHN_VREF    0x0d    /* Positive voltage reference */
        #define ADC_CHN_TEMP    0x0e    /* Temperature sensor */
        #define ADC_CHN_VDD3    0x0f    /* VDD/3 */
         
        /* Channels */
        #define ADC_CHANNEL_0     0x00
        #define ADC_CHANNEL_1     0x01
        #define ADC_CHANNEL_2     0x02
        #define ADC_CHANNEL_3      0x03
        #define ADC_CHANNEL_4     0x04
        #define ADC_CHANNEL_5      0x05
        #define ADC_CHANNEL_6      0x06
        #define ADC_CHANNEL_7      0x07
         
         
        /* 参考电压的设定 */
        #define ADC_REF_125V    0x00    /* Internal Reference (1.25V-CC2430)(1.15V-CC2530) */
        #define ADC_REF_AIN7    0x40    /* AIN7 Refersence */
        #define ADC_REF_AVDD    0x80    /* AVDD_SOC Pin Reference,根据专门的那个电压输入端 */
        #define ADC_REF_DIFF    0xc0    /* AIN7,AIN6 Differential Reference */
         
        #define ADC_REF_V        ADC_REF_AVDD
         
        void Adc_Init_2538(uint8_t channel);
        uint16_t Adc_Read(uint8_t channel);
         
        #endif
         


    ————————————————
    版权声明:本文为CSDN博主「莫九玉」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/mx1252111/java/article/details/53494035

  • 相关阅读:
    Python基础(14)_python模块之configparser模块、suprocess
    Python基础(13)_python模块之re模块(正则表达式)
    Python基础(12)_python模块之sys模块、logging模块、序列化json模块、pickle模块、shelve模块
    Python基础(11)_python模块之time模块、rando模块、hashlib、os模块
    Python基础(10)_内置函数、匿名函数、递归
    python中内建函数isinstance的用法
    Python基础(9)_生成器(yield表达式形式)、面向过程编程
    Python基础(8)_迭代器、生成器、列表解析
    Python基础(7)_闭包函数、装饰器
    Python基础(6)_函数
  • 原文地址:https://www.cnblogs.com/caobw/p/13228334.html
Copyright © 2011-2022 走看看