//DS18b20的C语言驱动程序,三位数码管显示,读取当前环境温度,精度达0.1度,温度范围0-99度
//DS18B20 详细引脚功能描述1、GND 地信号;2、DQ数据输入出引脚。开漏单总线接口引脚。当被用在寄生电源下
//也可以向器件提供电源;3、VDD可选择的VDD 引脚。当工作于寄生电源时,此引脚必须接地。
//DS18B20 的使用方法。DS18B20 采用的是1-Wire 总线协议方式
//即在一根数据线实现数据的双向传输
//编译环境 AVR Studio 4.13/AVR GCC
//系统时钟7.3728MHz,设置熔丝位为外部高频石英晶体振荡,启动时间4.1ms
//***********************************************************************
// 包含文件
//***********************************************************************
#include
#include
#define F_CPU 7372800 // 单片机 主频为7.3728MHz,用于延时子程序
#include
#include
#include
#include //中断信号头文件
//***********************************************************************
// 定义变量区
// CH451各个功能命令值,根据需要写入
//***********************************************************************
#define CH451_RESET 0x0201 //复位
#define CH451_LEFT MOV 0x0300 //设置移动方式-作移
#define CH451_LEFTCYC 0x0301 //设置移动方式-左循
#define CH451_RIGHT MOV 0x0302 //设置移动方式-右移
#define CH451_RIGHTCYC 0x0303 //设置移动方式-右循
#define CH451_SYSOFF 0x0400 //关显示、键盘、看门狗
#define CH451_SYSON1 0x0401 //开显示
#define CH451_SYSON2 0x0403 //开显示、键盘
#define CH451_SYSON3 0x0407 //开显示、键盘、看门狗功能
#define CH451_DSP 0x0500 //设置默认显示方式
#define CH451_BCD 0x0580 //设置BCD译码方式
#define CH451_TWINKLE 0x0600 //设置闪烁控制
#define CH451_DIG0 0x0800 //数码管位0显示
#define CH451_DIG1 0x0900 //数码管位1显示
#define CH451_DIG2 0x0a00 //数码管位2显示
#define CH451_DIG3 0x0b00 //数码管位3显示
#define CH451_DIG4 0x0c00 //数码管位4显示
#define CH451_DIG5 0x0d00 //数码管位5显示
#define CH451_DIG6 0x0e00 //数码管位6显示
#define CH451_DIG7 0x0f00 //数码管位7显示
#define LED0 0x0000 //数码管位0显示的数据
#define led1 0x0000 //数码管位0显示的数据;0x0010为不亮
#define led2 0x0000 //数码管位0显示的数据
#define led3 0x0010 //数码管位0显示的数据
#define led4 0x0010 //数码管位0显示的数据
#define led5 0x0010 //数码管位0显示的数据
#define led6 0x0010 //数码管位0显示的数据
#define led7 0x0010 //数码管位0显示的数据
#define dclk0 PORTD &= ~(1 <#define dclk1 PORTD |= (1 <#define din0 PORTD &= ~(1 <#define din1 PORTD |= (1 <#define load0 PORTD &= ~(1 <#define load1 PORTD |= (1 <
#define DQ_IN DDRC &= ~(1 <#define DQ_OUT DDRC |= (1 <#define DQ_CLR PORTC &= ~(1 <电平
#define DQ_SET PORTC |= (1 <#define DQ_R PINC & (1 <
#define delay_us(x) _delay_us(x) //AVR GCC延时函数 x(us)
#define delay_ms(x) _delay_ms(x) //AVR GCC延时函数 x(ms)
#define uchar unsigned char
#define uint unsigned int
uint value;
uint temp,A1,A2,A3; //定义的变量,显示数据处理
uchar flag1;
uchar table[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,
0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,
0x0e,0x0f}; //数码管的BCD码
//*************************************************************************
// 初始化子程序
//*************************************************************************
void system_init()
{
SFIOR=(1<<2)|SFIOR; //PUD=1;关闭上拉电阻
PORTD=0x70;
DDRD=0x70;
}
void ch451_init()
{
din0; //先低后高,选择4线输入
din1;
}
//*************************************************************************
// 输出命令子程序
// 定义一无符号整型变量存储12字节的命令字
//************************************************************************
void ch451_write(unsigned int command)
{
unsigned char i;
load0; //命令开始
for(i=0;i<12;i++)
{ //送入12位数据,低位在前
if(command&1)
{
din1;
}
else
din0;
dclk0;
dclk1; //上升沿有效
command>>=1;
}
load1; //加载数据
}
//*************************************************************************
// 显示函数
//*************************************************************************
void display(uint b_d,uint s_d,uint g_d)
{
ch451_init();
ch451_write(CH451_SYSOFF); //关显示、键盘、看门狗
ch451_write(CH451_SYSON1); //开显示
ch451_write(CH451_BCD); //设置BCD译码方式
ch451_write(CH451_TWINKLE); //设置闪烁控制
ch451_write(CH451_DIG0|table[b_d]); //显示百位数据
ch451_write(CH451_DIG1|table[s_d]|0x80); //显示十位数据
ch451_write(CH451_DIG2|table[g_d]); //显示个位数据
ch451_write(CH451_DIG3|led3); //其他数码管不显示,熄灭状态
ch451_write(CH451_DIG4|led4);
ch451_write(CH451_DIG5|led5);
ch451_write(CH451_DIG6|led6);
ch451_write(CH451_DIG7|led7);
}
//*************************************************************************
// DS18B20初始化
//*************************************************************************
unsigned char ds1820_reset(void) //初始化和复位
{
unsigned char i;
DQ_OUT;
DQ_CLR;
delay_us(500); //延时500uS(480-960)
DQ_SET;
DQ_IN;
delay_us(80); //延时80uS
i = DQ_R;
delay_us(500); //延时500uS(保持>480uS)
if (i)
{
return 0x00;
}
else
{
return 0x01;
}
}
//*************************************************************************
// DS18B20读一个字节函数
//*************************************************************************
unsigned char ds1820_read_byte(void)
{
unsigned char i;
unsigned char value = 0;
for (i = 8; i != 0; i--)
{
value >>= 1;
DQ_OUT;
DQ_CLR;
delay_us(4); //*延时4uS
DQ_SET;
DQ_IN;
delay_us(10); //*延时10uS
if (DQ_R)
{
value|=0x80;
}
delay_us(60); //*延时60uS
}
return(value);
}
//*************************************************************************
// 向18B20写一个字节函数
//*************************************************************************
/*DS18B20字节写入函数*/
void ds1820_write_byte(unsigned char value)
{
unsigned char i;
for (i = 8; i != 0; i--)
{
DQ_OUT;
DQ_CLR;
delay_us(4); //延时4uS
if (value & 0x01)
{
DQ_SET;
}
delay_us(80); //延时80uS
DQ_SET; //位结束
value >>= 1;
}
}
//*************************************************************************
// 发送温度转换命令
//*************************************************************************
/*启动ds1820转换*/
void ds1820_start(void) {
ds1820_reset();
ds1820_write_byte(0xCC); //勿略地址
ds1820_write_byte(0x44); //启动转换
}
//*************************************************************************
// DS8B20读取温度信息
//*************************************************************************
unsigned int ds1820_read_temp(void)
{
unsigned int i;
unsigned char buf[9];
ds1820_reset();
ds1820_write_byte(0xCC); //勿略地址
ds1820_write_byte(0xBE); //读取温度
for (i = 0; i {
buf[i] = ds1820_read_byte();
}
i = buf[1];
i <<= 8;
i |= buf[0];
value=i;
value=value*0.625; //不是乘以0.0625的原因是为了把小数点后一位数据也转化为可以显示的数据
//比如温度本身为27.5度,为了在后续的数据处理程序中得到BCD码,我们先放大到275
//然后在显示的时候确定小数点的位置即可,就能显示出27.5度了
//value=value*10;
return i;
}
//*************************************************************************
// 温度数据处理函数
//*************************************************************************
void data_do(uint d)
{
uint A2t;
A1=d/100; //分出百,十,和个位
A2t=d%100;
A2=A2t/10;
A3=A2t%10;
}
//*************************************************************************
// 主程序
//*************************************************************************
void main(void)
{
DDRC = 0x00;
PORTC = 0xFF;
system_init(); //系统初始化
delay_ms(250);
ds1820_reset(); //复位D18B20
while (1)
{
ds1820_start(); //启动一次转换
delay_ms(300); //等待转换结束
ds1820_read_temp(); //读取温度数值
data_do(value); //处理数据,得到要显示的值
display(A1,A2,A3); //显示温度值
delay_ms(1000); //延时1S
}
}
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』