我的DS18B20测试程序

我的DS18B20测试程序
//--------------------------------------------------//
// 硬件:ATmega16 7.3728MHz晶振 //
//描述:使用AVR单片机,LCD1602显示,从MAXIM单线温度 //
//传感器DS18B20的温度数值(PD7接18B20DQ,需4。7K上拉//
//电阻,LCD接口使用PA7---PA2) //
// //
// BY: 柠檬7294 2006.10.21 //
//--------------------------------------------------//
#include
#include

#define uchar unsigned char
#define uint unsigned int
//LCD1602口线定义
#define LCD_EN_PORT PORTA //以下2个要设为同一个口
#define LCD_EN_DDR DDRA
#define LCD_RS_PORT PORTA //以下2个要设为同一个口
#define LCD_RS_DDR DDRA
#define LCD_DATA_PORT PORTA //以下3个要设为同一个口
#define LCD_DATA_DDR DDRA //一定要用高4位
#define LCD_DATA_PIN PINA
#define LCD_RS (1<#define LCD_EN (1<#define LCD_DATA ((1<
/********************************************************************************
数据类型的定义
********************************************************************************/
#define BYTE unsigned char
#define WORD unsigned int
/********************************************************************************
位变量操作宏定义
********************************************************************************/
#define BIT_SET(a,b) a|=BIT(b)
#define BIT_CLR(a,b) a&=~BIT(b)
#define BIT_INV(a,b) a^=BIT(b)
#define BIT_STATUS(a,b) a&BIT(b)
/********************************************************************************
DS18B20操作定义
********************************************************************************/
#define CLR_DS18B20 BIT_CLR(PORTD,PD7) //数据线强制拉低
#define SET_DS18B20 BIT_SET(PORTD,PD7) //数据线强制拉高,上拉
#define HLD_DS18B20 BIT_SET(DDRD,PD7) //Mega16控制总线
#define RLS_DS18B20 BIT_CLR(DDRD,PD7) //释放总线
#define STU_DS18B20 BIT_STATUS(PIND,PD7) //数据线的状态
volatile unsigned char alarm_fleg=0;
volatile signed long Tempareture,Tempareture_top=450000,Tempareture_low=280000;
volatile unsigned int KEY,key_fleg;
const unsigned c

har tab[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

//端口初始化
void port_init(void)
{
PORTA = 0x00;
DDRA = 0xFC;
PORTB = 0x00;
DDRB = 0x02;
PORTC = 0xFF;
DDRC = 0x00;
PORTD = 0x00;
DDRD = 0x00;
}

void get_key(void)
{
static char key_old,hold;
uchar temp;
temp=PINC;
if(temp!=0xFF)
key_old=temp;
delay_nms(30);
temp=PINC;
if(temp==key_old)
{
switch(temp)
{
//case 0b11111111:{KEY=1;key_fleg=1;}break;
case 0b11011111:{KEY=2;key_fleg=1;}break;
case 0b11101111:{KEY=3;key_fleg=1;}break;
case 0b11111110:{KEY=4;key_fleg=1;}break;
case 0b11111011:{KEY=5;key_fleg=1;}break;
case 0b11111101:{KEY=6;key_fleg=1;}break;
case 0b11110111:{KEY=7;key_fleg=1;}break;
default:break;
}
}
while(PINC==key_old&&hold++<10)
{
delay_nms(20);
}
hold=0;
}
/*-------------液晶驱动----------------*/
void LCD_init(void) //液晶初始化
{
LCD_DATA_DDR|=LCD_DATA; //数据口方向为输出
LCD_EN_DDR|=LCD_EN; //设置EN方向为输出
LCD_RS_DDR|=LCD_RS; //设置RS方向为输出
LCD_write_command(0x28);
LCD_en_write();
delay_nus(20);
LCD_write_command(0x28); //4位显示
LCD_write_command(0x0C); //显示开
LCD_write_command(0x01); //清屏
delay_nms(2);
}

void LCD_en_write(void) //液晶使能
{
CLI();
LCD_EN_PORT|=LCD_EN;
delay_nus(2);
LCD_EN_PORT&=~LCD_EN;
SEI();
}

void LCD_write_command(unsigned char command) //写指令
{
CLI();
delay_nus(20);
LCD_RS_PORT&=~LCD_RS; //RS=0
LCD_DATA_PORT&=0X0f; //清高四位
LCD_DATA_PORT|=command&0xf0; //写高四位
LCD_en_write();
command=command<<4; //低四位移到高四位
LCD_DATA_PORT&=0x0f; //清高四位
LCD_DATA_PORT|=command&0xf0; //写低四位
LCD_en_write();
SEI();
}


void LCD_write_data(unsigned char data) //写数据
{
CLI();
delay_nus(20);
LCD_RS_PORT|=LCD_RS; //RS=1
LCD_DATA_PORT&=0X0f; //清高四位
LCD_DATA_PORT|=data&0xf0; //写高四位
LCD_en_write();
data=data<<4; //低四位移到高四位
LCD_DATA_PORT&=0X0f; //清高四位
LCD_DATA_PORT|=data&0xf0; //写低四位
LCD_en_write();
SEI();
}


void LCD_set_xy( unsigned char x, unsigned char y ) //写地址函数
{
unsigned char address;
CLI();
if (y == 0) address = 0x80+x;
else
address = 0xc0+x;
LCD_write_command( address);
SEI();
}

void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s) //列x=0~15,行y=0,1
{
LCD_set_xy( X, Y ); //写地址
while (*s) /

/ 写显示字符
{
LCD_write_data( *s );
s ++;
}
}

void LCD_write_char(unsigned char X,unsigned char Y,unsigned char data) //列x=0~15,行y=0,1
{
LCD_set_xy( X, Y ); //写地址
LCD_write_data( data);

}


/*-----------------------------------------------------------------------
延时函数
系统时钟:8M

/**********************************************************************
functionName: void delayUs(BYTE temp)
description :延时函数 晶振频率:7.3728MHZ
delayUs(1); //2.71us
delayUs(2); //3.53us
delayUs(4); //5.15us
delayUs(8); //8.41us
delayUs(16); //14.92us
delayUs(32); //27.94us
delayUs(64); //53.98us
delayUs(128); //106.07us
delayUs(255); //209.42us
delayUs(18); //16.55us
delayUs(34); //29.57us
delayUs(35); //30.38us
delayUs(100); //83.28
_NOP(); //0.14us
**********************************************************************/
void delayUs(BYTE temp)
{
while(temp--);
}

/**********************************************************************
functionName: BYTE resetDS18B20(void)
description :DS18B20初始化
**********************************************************************/
BYTE resetDS18B20(void)
{
BYTE errTime=0;
RLS_DS18B20; //释放总线
_NOP();
HLD_DS18B20; //Maga16控制总线
CLR_DS18B20; //强制拉低
delayUs(255); //209.42us
delayUs(255); //209.42us
delayUs(255); //83.28us
//以上的三个延时大于480us
RLS_DS18B20; //释放总线,总线自动上拉
_NOP();
while(STU_DS18B20)
{
delayUs(4); //5.15us
errTime++;
if(errTime>20)
return(0x00); //如果等带大于约 5.15us*20就返回0x00,报告复位失败(实际上只要等待15-60us)
}
errTime=0;
while(!(STU_DS18B20))
{
delayUs(4); //5.15us
errTime++;
if(errTime>50)
return(0x00); //如果等带大于约 5.15us*50就返回0x00,报告复位失败(实际上只要等待60-240us)
}
return(0xff);
}


/**********************************************************************
functionName: BYTE readByteDS18B20(void)
description :读DS18B20一个字节
**********************************************************************/
BYTE readByteDS18B20(void)
{
BYTE i;
BYTE retVal=0;

RLS_DS18B20; //释放总线
for(i=8;i>0;i--)
{
retVal>>=1;
HLD_DS18B20; //Maga16控制总线
CLR_DS18B20; //强制拉低
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
NOP(); //延时大于1us
RLS_DS18B20; //释放总线,DS18B20会将总线强制拉低
delayUs(16); //14.92us
if(STU_DS18B20)
retVal|=0x80;
delayUs(16); //14.92us
delayUs(16); //14.92us
//RLS_DS18B20; //释放总线
delayUs(35); //30.38us
}
delayUs(1); //2.71us(大于1us就行了)
return(retVal);
}


/**********************************************************************
functionName: BYTE readByteDS18B20(void)
description :写DS18B20一个字节
**********************************************************************/
void writeByteDS18B20(BYTE wb)
{
BYTE i;
BYTE temp;
RLS_DS18B20; //释放总线
for(i=0;i<8;i++)
{
HLD_DS18B20; //Maga16控制总线
CLR_DS18B20; //强制拉低
delayUs(16); //14.92us
temp=wb>>i;
temp&=0x01;
if(temp)
RLS_DS18B20; //释放总线
else
CLR_DS18B20; //强制拉低
delayUs(16); //14.92us
delayUs(35); //30.38us
RLS_DS18B20; //释放总线
delayUs(1); //2.71us(大于1us就行了)
}
}

/**********************************************************************
functionName: unsigned int readTempDS18B20(void)
description :读DS18B20温度
**********************************************************************/
unsigned int readTempDS18B20(void)
{
BYTE tempL,tempH;
WORD x;
while(resetDS18B20()==0);
writeByteDS18B20(0xcc); //跳过ROM
writeByteDS18B20(0x44); //启动温度转换
delayUs(1);
while(resetDS18B20()==0);
writeByteDS18B20(0xcc); //跳过ROM
writeByteDS18B20(0xbe); //读数据
tempL=readByteDS18B20();
tempH=readByteDS18B20();
x=(tempH<<8)|tempL;
return(x);
}



void display_hex(unsigned char x,unsigned char y,unsigned int number)
{
unsigned char t

emp[4];
temp[0]=(char)((number&0xf000)>>12);
temp[1]=(char)((number&0x0f00)>>8);
temp[2]=(char)((number&0xf0)>>4);
temp[3]=(char)(number&0x0f);
LCD_write_string(x,y,"0x");
LCD_write_char(x+2 ,y,tab[temp[0]]);
LCD_write_char(x+3 ,y,tab[temp[1]]);
LCD_write_char(x+4 ,y,tab[temp[2]]);
LCD_write_char(x+5 ,y,tab[temp[3]]);
}
void display_TEMP(unsigned char x,unsigned char y,signed long number)
{
unsigned char temp[7];unsigned long temp1=0;
temp[0]=(char)(number/100000);
temp1=(number%100000);
temp[1]=(char)(temp1/10000);
temp1=(temp1%10000);
temp[2]=(char)(temp1/1000);
temp1=(temp1%1000);
temp[3]=(char)(temp1/100);
temp1=(temp1%100);
temp[4]=(char)(temp1/10);
temp1=(temp1%10);
//temp[5]=(char)(temp1/10);
//temp1=(temp1%10);
temp[5]=(char)(temp1);
temp1=0;
//if(Tempareture<0)
//LCD_write_char(x-1 ,y,'-');
LCD_write_char(x ,y,tab[temp[0]]);
LCD_write_char(x+1 ,y,tab[temp[1]]);
LCD_write_char(x+2 ,y,'.');
LCD_write_char(x+3 ,y,tab[temp[2]]);
//LCD_write_char(x+4 ,y,tab[temp[3]]);
//LCD_write_char(x+5 ,y,tab[temp[4]]);
//LCD_write_char(x+6 ,y,tab[temp[5]]);
//LCD_write_char(x+7 ,y,tab[temp[6]]);
LCD_write_char(x+4,y,0xDF);
LCD_write_char(x+5,y,'C');
}

void alarm(void)
{
if(alarm_fleg)
PORTB|= (1<else
PORTB&=~(1<}


void main(void)
{
signed long temp=0;
LCD_init();
delay_nms(50);
LCD_write_string(2,0,"DS18B20 test!");
delay_nms(500);
while(1)
{
resetDS18B20();
temp=readTempDS18B20();
delay_nms(500);
Tempareture=temp*625;
display_hex(1,1,temp);
display_TEMP(9,1,Tempareture);
if(Tempareture>=Tempareture_top||Tempareture>=Tempareture_low)
alarm_fleg=1;else alarm_fleg=0;
alarm();
}
}

相关文档
最新文档