?? 18b20.c
字號(hào):
/***********************************************
**** DS18B20溫度采集,LCD1602B顯示 ***
**** MCU : Atmeag16 ***
**** 作者: XueTwins ***
**** 時(shí)間 20007.02.17 ***
注:DS18B20的數(shù)據(jù)口接PA0
***********************************************/
#include <iom16v.h>
#include <macros.h>
/*******************************************************************************
定義MCU與LCD的接口
接線:EN-PD3、RS-PD2、DATA-PD4,5,6,7
*******************************************************************************/
#define LCD_EN_PORT PORTD //PD3使能LCD
#define LCD_RS_PORT PORTD //PD2
#define LCD_DATA_PORT PORTD
#define LCD_EN 0x08 //PD3 out
#define LCD_RS 0x02 //PD2 out
#define LCD_DATA 0xF0 //PD4,5,6,7
/*******************************************************************************
函數(shù)原型聲明
*******************************************************************************/
void LCD_init(void);//LCD初始化
void LCD_en_write(void);//LCD寫(xiě)
void LCD_set_xy(unsigned char x,unsigned char y);//寫(xiě)X,Y地址
void LCD_write_string(unsigned char x,unsigned char y,unsigned char *string);
void LCD_write_char(unsigned command,unsigned data);
void LCD_write_data_variable(unsigned char x,unsigned char y,
unsigned char Z,unsigned long S);
/*******************************************************************************
延時(shí)函數(shù)
系統(tǒng)時(shí)鐘:8M
*******************************************************************************/
void delay_1us(void) //1us延時(shí)函數(shù)
{
asm("nop");
asm("nop");
asm("nop");
asm("nop");
}
void delay_nus(unsigned int n) //N us延時(shí)函數(shù)
{
unsigned int i=0;
for (i=0;i<n;i++)
delay_1us();
}
void delay_1ms(void) //1ms延時(shí)函數(shù)
{
unsigned int i;
for (i=0;i<1142;i++);
}
void delay(unsigned int n) //N ms延時(shí)函數(shù)
{
unsigned int i=0;
for (i=0;i<n;i++)
delay_1ms();
}
/*******************************************************************************
上面聲明各函數(shù)的實(shí)現(xiàn)
*******************************************************************************/
void LCD_init(void)
{
LCD_write_char(0x28,0);
LCD_en_write();
delay(15);//延時(shí)15ms
LCD_write_char(0x28,0);//四位數(shù)據(jù)接口,二行顯示,5*7點(diǎn)陣字符
LCD_write_char(0x0C,0);//顯示開(kāi)
LCD_write_char(0x01,0);//清屏
delay(2);
LCD_write_char(0x06,0);//顯示光標(biāo)移動(dòng)設(shè)置
}
void LCD_en_write(void)//液晶使能
{
LCD_EN_PORT|=LCD_EN;
delay(1);
LCD_EN_PORT&=~LCD_EN;
}
/*******************************************************************************
寫(xiě)數(shù)據(jù)
*******************************************************************************/
void LCD_write_char(unsigned command,unsigned data)
{
unsigned command_temp,data_temp;
command_temp=command;
data_temp=data;
delay(16);
if(command==0)
{
LCD_RS_PORT|=LCD_RS; //RS=1
LCD_DATA_PORT&=0X0f;
LCD_DATA_PORT|=data_temp&0xf0; //寫(xiě)高四位
LCD_en_write();
data_temp=data_temp<<4;
LCD_DATA_PORT&=0X0f;
LCD_DATA_PORT|=data_temp&0xf0; //寫(xiě)低四位
LCD_en_write();
}
else
{
LCD_RS_PORT&=~LCD_RS; //RS=0
LCD_DATA_PORT&=0X0f;
LCD_DATA_PORT|=command_temp&0xf0; //寫(xiě)高四位
LCD_en_write();
command_temp=command_temp<<4;
LCD_DATA_PORT&=0x0f;
LCD_DATA_PORT|=command_temp&0xf0; //寫(xiě)低四位
LCD_en_write();
}
}
/*******************************************************************************
寫(xiě)地址
//設(shè)置LCD顯示的起始位置,顯示字符串的位置,X:0-15,Y:0-1
// LCD第一行顯示寄存器地址:0X80-0X8F
// LCD第一行顯示寄存器地址:0XC0-0XCF
*******************************************************************************/
void LCD_set_xy(unsigned char x,unsigned char y)
{
unsigned char address;
if(y==0)
address=0x80 + x;
else //即y==1
address=0xC0 + x;
LCD_write_char(address,0);
}
/*******************************************************************************
英文字符串顯示函數(shù)
*******************************************************************************/
void LCD_write_string(unsigned char x,unsigned char y,unsigned char *string)
{
LCD_set_xy(x,y);//寫(xiě)地址
while (*string) // 寫(xiě)顯示字符
{
LCD_write_char(0,*string);
string ++;
}
}
/*******************************************************************************
顯示數(shù)字變量函數(shù)
Z為S變量共幾位數(shù) //最大變量顯示為99999;
*******************************************************************************/
void LCD_write_data_variable(unsigned char x,unsigned char y,
unsigned char Z,unsigned long S)
{
unsigned char k;
unsigned char p[6]="0";
unsigned char i=0;
LCD_set_xy( x, y );
for(i=0;i<Z;i++)
{
p[i]=S%10;
S=S/10;
}
while(!(p[i]))
{
if(i==0)
{
LCD_write_char( 0, 0x30 );
i--;
}
else
{
i--;
LCD_write_char( 0, 0x80 );
}
}
for(;i<255;i--)
{
LCD_write_char( 0, p[i]+0x30 );
}
}
///////////////////////數(shù)字溫度傳感器////////////////////////////////////
////////////////////////DS18B20//////////////////////////////////////////
#define DS18B20_PORT PORTA
#define DS18B20_DDR DDRA
#define DS18B20_PIN PINA
#define DS18B2_IO BIT(0)//0x01
/*******************************************************************************
函數(shù)原型聲明
*******************************************************************************/
unsigned char DS18B20_reset(void); // 復(fù)位程序
unsigned char DS18B20_read(void); //從單總線讀1字節(jié)
void DS18B20_write(unsigned char CMD); //向單總線寫(xiě)1字節(jié)
long count;
/*******************************************************************************
復(fù)位程序
檢查DS18B20是否存在:不存在返回1,存在返回0
*******************************************************************************/
unsigned char DS18B20_reset(void)
{
unsigned char online;
DS18B20_DDR |= DS18B2_IO; //PORTA.0輸出
DS18B20_PORT &=~DS18B2_IO; //PORTA&=0xFE;//輸出低電平
delay_nus(500); //480us~960us
DS18B20_PORT |=DS18B2_IO; //輸出高電平
DS18B20_DDR &=~DS18B2_IO; //PORTA.0輸入
delay_nus(45); //16-60us等待響應(yīng)
online=DS18B20_PORT & DS18B2_IO;//響應(yīng)信號(hào),讀出online的值
delay_nus(100); //60-240us
return (online);
}
/*******************************************************************************
從DS18B20讀1字節(jié)數(shù)據(jù)(從單總線讀1字節(jié))
*******************************************************************************/
unsigned char DS18B20_read(void)
{
unsigned char i,temp;
unsigned char byte=0;//byte=0x00;
for(i=0;i<8;i++)
{
DS18B20_DDR|=DS18B2_IO; //PORTA.0輸出
DS18B20_PORT&=~DS18B2_IO; //PORTA&=0xFE;//輸出低電平,產(chǎn)生讀起始信號(hào)
delay_nus(3); //延時(shí)1us~15us
DS18B20_PORT|=DS18B2_IO; //輸出高電平
DS18B20_DDR&=~DS18B2_IO; //PORTA.0輸入,接收數(shù)據(jù)
delay_nus(10); //要在15us內(nèi)完成讀數(shù)
temp=(DS18B20_PIN & DS18B2_IO);//讀數(shù)據(jù),從低位開(kāi)始
if(temp!=0x00)
byte|=0x80;
if(i<7)
byte=byte>>1;
delay_nus(100); //60~120us
DS18B20_DDR|=DS18B2_IO; //PORTA.0輸出
delay_nus(5);
}
return byte;
}
/*******************************************************************************
寫(xiě)ROM或存儲(chǔ)器命令到DS18B20(向單總線寫(xiě)1字節(jié))
*******************************************************************************/
void DS18B20_write(unsigned char CMD)
{
unsigned char i,value;
DS18B20_DDR|=DS18B2_IO; //PORTA.0輸出
for(i=0;i<8;i++)
{
value=CMD&DS18B2_IO;
if(value==0x01)
{
delay_nus(1); //延時(shí)>1us
DS18B20_PORT&=~DS18B2_IO; //產(chǎn)生寫(xiě)起始信號(hào)
delay_nus(10); //延時(shí)1us~15us
DS18B20_PORT|=DS18B2_IO; //數(shù)據(jù)線電平拉高
delay_nus(100); //延時(shí)60us~120us
}
else
{
delay_nus(1); //延時(shí)>1us
DS18B20_PORT&=~DS18B2_IO; //產(chǎn)生寫(xiě)起始信號(hào)
delay_nus(100); //18B20采樣要60us到120us
DS18B20_PORT|=DS18B2_IO; //數(shù)據(jù)線電平拉高
delay_nus(10);
}
CMD=CMD>>1; //右移一位
}
}
/*******************************************************************************
主函數(shù)
*******************************************************************************/
void main(void)
{
unsigned char i,temh,teml;
unsigned char errortrue;
DDRD|=LCD_EN | LCD_RS | LCD_DATA;//EN方向,RS方向,數(shù)據(jù)口方向?yàn)檩敵?
LCD_EN_PORT &= ~LCD_EN; //EN=0
LCD_init(); //液晶初始化
delay_nus(2000);
OSCCAL=0X9d; //系統(tǒng)時(shí)鐘校準(zhǔn),不同的芯片和不同的頻率,
WDR(); //看門狗計(jì)數(shù)清零
WDTCR=0x0F;
for(;;)
{
LCD_write_char(0x01,0);//清屏
errortrue=DS18B20_reset(); //復(fù)位18b20
if(errortrue==0x01)
{
LCD_write_string(0,1,"wrong"); //初始化失敗
}
else
{
LCD_write_string(0,0,"Temperature:");//初始化成功
}
DS18B20_write(0xcc); // 發(fā)出轉(zhuǎn)換命令
DS18B20_write(0x44); //啟動(dòng)18B20溫度開(kāi)始轉(zhuǎn)換
delay_nus(400); //每次轉(zhuǎn)換需要延時(shí)200ms以上
DS18B20_reset();
WDR();
DS18B20_write(0xcc); //發(fā)出讀命令 ,搜索ROM
DS18B20_write(0xbe); //讀閃存器,讀CRC冗余校驗(yàn)
teml=DS18B20_read(); //讀低字節(jié)數(shù)據(jù)
temh=DS18B20_read(); //讀高字節(jié)數(shù)據(jù)
count=(temh*256+teml)*6.25; //計(jì)算具體溫度
WDR();
LCD_write_data_variable(0,1,2,count);
LCD_write_string(14,1,"`C");
delay(300);
}
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -