7、RIOT操作系统中 CC2538采集ds18b20源码共享

        下面把整个工程的代码共享出来。ds18b20的采集不是我写的,是我的一个同事写的。   adc的是我写的。把下面的源码,分别复制下来,放到文件中,给文件命名好。放在riot操作系统下面,然后再终端中进去这个文件夹中 输入 make 就可以编译了。。如果不会编译,不会使用ubuntu终端的,可以看看前面的帖子




cc2538adc.c

#include <stdio.h>
#include "cc2538.h"    
#include "cc2538adc.h"    

void Adc_Init_2538(uint8_t channel)
{        
    //配置寄存器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_125V;  
        SOC_ADC_ADCCON3 |= ADC_DEC_12Bit;  
        SOC_ADC_ADCCON3 |= channel;      
        while ((SOC_ADC_ADCCON1 & ADC_EOC) != ADC_EOC); 
        
        SOC_ADC_ADCCON3  |= ADC_REF_125V;  
        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<3;j++)                            //一次采集3次求平均值
    {
        SOC_ADC_ADCCON3 |= ADC_REF_125V;                //选择参考电压
        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/2;                            //上面测试了3次,舍掉了第一次,还有2次,求平均值
    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 */

void Adc_Init_2538(uint8_t channel);
uint16_t Adc_Read(uint8_t channel);

#endif 


ds18b20.c 

#include "ds18b20.h"
#include "periph/gpio.h"

void delay_us(uint16_t delay)
{
    uint16_t i,j;  
    for (i = 0; i < delay; i++) 
    {
        for(j = 0; j < 3; j++)
        {
        	__asm__("nop");
        }       
    }
}

//复位DS18B20
void DS18B20_Rst(void)	   
{
	gpio_software_control(GPIO_PA6);
	gpio_dir_output(GPIO_PA6); 		//设置PA6为输出
    gpio_clear(GPIO_PA6); 			//拉低DQ
    delay_us(750);    				//拉低750us
    gpio_set(GPIO_PA6); 			//拉高DQ 
	delay_us(15);    				//15us
}
//等待DS18B20的响应
//返回1:未检测到DS18B20的存在
//返回0:存在
uint8_t DS18B20_Check(void) 	   
{   
	uint8_t retry=0;
	//设置PA6为输入
	gpio_software_control(GPIO_PA6);	
	gpio_dir_input(GPIO_PA6);
	IOC_PXX_OVER[GPIO_PA6] = IOC_OVERRIDE_PUE;	
				
    while (gpio_read(GPIO_PA6)&&retry<200)
	{
		retry++;
		delay_us(1);
	};	 
	if(retry>=200)return 1;
	else retry=0;
    while (!gpio_read(GPIO_PA6)&&retry<240)
	{
		retry++;
		delay_us(1);
	};
	if(retry>=240)return 1;	    
	return 0;
}
//从DS18B20读取一个位
//返回值:1/0
uint8_t DS18B20_Read_Bit(void) 			 // read one bit
{
    uint8_t data;
	gpio_dir_output(GPIO_PA6); 				//SET PA0 OUTPUT
    gpio_clear(GPIO_PA6);
	delay_us(2);
    gpio_set(GPIO_PA6); 
	gpio_dir_input(GPIO_PA6);				//SET PA0 INPUT
	IOC_PXX_OVER[GPIO_PA6] = IOC_OVERRIDE_PUE;
	delay_us(12);
	if(gpio_read(GPIO_PA6))data=1;
    else data=0;	 
    delay_us(50);           
    return data;
}
//从DS18B20读取一个字节
//返回值:读到的数值
uint8_t DS18B20_Read_Byte(void)    		// read one byte
{        
    uint8_t i,j,dat;
    dat=0;
	for (i=1;i<=8;i++) 
	{
        j=DS18B20_Read_Bit();
        dat=(j<<7)|(dat>>1);
    }						    
    return dat;
}
//写一个字节到DS18B20
//dat:要写入的数据
void DS18B20_Write_Byte(uint8_t dat)     
 {             
    uint8_t j;
    uint8_t testb;
	gpio_dir_output(GPIO_PA6); 				//SET PA0 OUTPUT;
    for (j=1;j<=8;j++) 
	{
        testb=dat&0x01;
        dat=dat>>1;
        if (testb) 
        {
            gpio_clear(GPIO_PA6); 	// Write 1
            delay_us(2);                            
            gpio_set(GPIO_PA6);
            delay_us(60);             
        }
        else 
        {
            gpio_clear(GPIO_PA6); 		// Write 0
            delay_us(60);             
            gpio_set(GPIO_PA6);
            delay_us(2);                          
        }
    }
}
//开始温度转换
void DS18B20_Start(void)			// ds1820 start convert
{   						               
    DS18B20_Rst();	   
	DS18B20_Check();	 
    DS18B20_Write_Byte(0xcc);		// skip rom
    DS18B20_Write_Byte(0x44);		// convert
} 
//初始化DS18B20的IO口 DQ 同时检测DS的存在
//返回1:不存在
//返回0:存在    	 
uint8_t DS18B20_Init(void)
{
	gpio_software_control(GPIO_PA6);	
	gpio_dir_input(GPIO_PA6);

	DS18B20_Rst();

	return DS18B20_Check();
}  
//从ds18b20得到温度值
//精度:0.1C
//返回值:温度值(-550~1250) 
int ds18b20_get_temp(void)
{
    uint8_t temp;
    uint8_t TL,TH;
	int tem;
    DS18B20_Start ();                    // ds1820 start convert
    DS18B20_Rst();
    DS18B20_Check();	 
    DS18B20_Write_Byte(0xcc);			// skip rom
    DS18B20_Write_Byte(0xbe);			// convert	    
    TL=DS18B20_Read_Byte(); 			// LSB   
    TH=DS18B20_Read_Byte(); 			// MSB  
	    	  
    if(TH>7)
    {
        TH=~TH;
        TL=~TL; 
        temp=0;							//温度为负 
    }else temp=1;						//温度为正  	  
    tem=TH; 							//获得高八位
    tem<<=8;    
    tem+=TL;							//获得低八位
    tem=(float)tem*0.625;				//转换    
	if(temp)return tem; 				//返回温度值
	else return -tem;    
} 
 


ds18b20.h

#ifndef __DS18B20_H
#define	__DS18B20_H

#include "cpu_conf.h"

uint8_t DS18B20_Init(void);
int ds18b20_get_temp(void);

#endif 



#include <stdio.h>
#include "cc2538.h"		
#include "cpu_conf.h"			
#include "periph/gpio.h"
#include "ds18b20.h"
#include "cc2538adc.h"	

void delay_ms(uint16_t delay)
{
    uint16_t i,j;  
    for (i = 0; i < delay; i++) 
    {
        for(j = 0; j < 1600; j++)
        {
        	__asm__("nop");
        }       
    }
}

int main(void)
{	
    int      temp    = 1;
    uint16_t AD_data = 0;
    uint16_t result  = 0;

    Adc_Init_2538(ADC_CHN_VDD3);//gpio的配置,adccon1,2,3寄存器的配置,等
    cpu_init();
	
    while(DS18B20_Init())
    {
        delay_ms(50);
    }
    puts("DS18B20 OK");
	
    while(1)
    {
        AD_data = Adc_Read(ADC_CHN_VDD3);     //ADC内部电压的采集。采用内部参考电压。具体看cc2538adc.c
        result = AD_data*138*3/4095-24;
		temp = ds18b20_get_temp();
		
		printf("AD_data = %d\n", AD_data );
        printf("ADC = %dV\n", result);        
        printf("temperature = %d\r\n\r\n", temp);

        delay_ms(3000);
    }	
} 


makefile

# name of your application
APPLICATION = DS18B20-adc

# If no BOARD is found in the environment, use this default:
BOARD ?= cc2538dk

# This has to be the absolute path to the RIOT base directory:
RIOTBASE ?= $(CURDIR)/../..

# Comment this out to disable code in RIOT that does safety checking
# which is not needed in a production environment but helps in the
# development process:
CFLAGS += -DDEVELHELP

# Change this to 0 show compiler invocation lines by default:
QUIET ?= 1

include $(RIOTBASE)/Makefile.include













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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值