6、RIOT操作系统中 CC2538的ADC使用

RIOT操作系统中 CC2538的ADC使用

       很久没有更新博客了,我也是一直在学习riot。我想说riot确实是一款很好用的操作系统。等接触到线程之后,接触到RPL组网之后,就会发现这个操作系统的强大。。。。话不多说,下面介绍一下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 


然后在main函数中的调用就行啦。部分代码在下面,可以参考使用。。。其他的自己去完善了,写这些博客有点累,就不详细讲了


int main()  
{
	Adc_Init_2538(ADC_CHANNEL_4);//gpio的配置,adccon1,2,3寄存器的配置,等  
	while(1)
	{
		AD_data = Adc_Read(ADC_CHANNEL_4);  
		printf("AD_data = %d\n", AD_data );  
		result = AD_data*305/4095;         //这里自己调整一下,  
		printf("ADC = %dV\n", result);	
	}
}

                                                                                     莫九玉

                                                                 2016.12.6   22:33




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值