下面把整个工程的代码共享出来。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