#include
#include
#include
#include
unsigned char data_H, data_L,wendu;
unsigned int data_T;
void main(void)
{
LCD_init(); //lcd初始化
lcd_cls(); //清屏,光標回位
while(1)
{
monobus_init(); //單總線復(fù)位
write_monobus(0xCC); //跳過ID碼匹配,適用于一個DS18B20
//可以使用8條語句代替上面的那條語句依次寫入8個ID碼,這樣就是ID碼匹配了
//如果不知道18B20的ID碼,可以在總線上接入單個18B20
//然后參考下面的讀取語句,依次讀取18B20的8個ID碼
//記得使用CRC8校驗一下是否正確
write_monobus(0x44); //啟動溫度轉(zhuǎn)換
delay_ms(500); //等待轉(zhuǎn)換
monobus_init(); //單總線復(fù)位
write_monobus(0xCC); //跳過ID碼匹配
write_monobus(0xBE); //通知DS18B20,準備讀數(shù)據(jù)
data_L=read_monobus(); //讀取第一個數(shù)據(jù)(溫度低字節(jié))
data_H=read_monobus(); //讀取第二個數(shù)據(jù)(溫度高字節(jié))
//可以繼續(xù)讀取第三個到第九個RAM數(shù)據(jù)
lcd_cls();
data_T=data_H*256+data_L; //合并后得到原始溫度數(shù)據(jù)
if(data_H>15) data_T=(~data_T+1)/16; else data_T/=16; //計算實際溫度
wendu=data_T;
lcd_gotoxy(16,3);
lcd_putsf("T = ",4); //顯示字符串,字符串是保存在Flash的
if(data_H>15) lcd_putchar('-');
lcd_put(wendu); //顯示溫度
lcd_putchar(' '); //空一個字符
lcd_write(2); //顯示C前面上標的一個點
lcd_write(0); //空一小格
lcd_putchar('C');
delay_ms(250);
}
}
/*
如果溫度為正,則T的最高位的4位都為0,否則為1
負溫度的計算:原始數(shù)據(jù)取反、加1、再乘以 0.0625
正溫度的計算:原始數(shù)據(jù)乘以 0.0625
CVAVR自帶了18B20的庫,如果大家不喜歡上面我寫的函數(shù),也可以使用自帶的
*/
//**********************************************************************************
//**********************************************************************************
//monobus.h文件,用于操作DS18B20/DS2401等單總線器件
//假設(shè)軟件設(shè)計要求的時鐘頻率是4MHz
//實際上硬件工作在2-8MHz下也很正常,就是說,下面代碼的延時取值是很合適的
//CVAVR本身自帶單總線的庫1wire.h,如果大家不喜歡下面的代碼也可以使用它自帶的函數(shù)(請看幫助文檔)
#define monobus_1 DDRC.0=0 //設(shè)置單片機IO為輸入,由于總線存在上拉電阻,所以此時電平是1
#define monobus_0 DDRC.0=1 //設(shè)置 單片機 IO為輸出,配合默認的 PORTC.0=0 則輸出0電平
#define monobus_inPINC.0 //檢測總線(從機)的電平狀態(tài)
void monobus_init(void) //復(fù)位,不檢測從機設(shè)備是否存在(只要沒有虛焊就肯定存在的)
{
monobus_0;
delay_us(480);
monobus_1;
delay_us(480);
}
void write_monobus(unsigned char data) //向單總線的從機寫入數(shù)據(jù)(先寫低位再寫高位,與SPI相反)
{
unsigned char n=1;
while(n)
{
monobus_0;
delay_us(2); //拉低總線1-3us,通知從機準備收發(fā)數(shù)據(jù)
if(data&n) monobus_1; else monobus_0; //向總線寫數(shù)據(jù)的某一位(1或者0)
delay_us(75); //等待90us,保證從機有足夠的時間進行采樣(24-210us)
monobus_1; //釋放總線
delay_us(2); //釋放總線時間要大于1us
n<<=1;
}
}
unsigned char read_monobus(void) //讀單總線的從機數(shù)據(jù)(先傳輸?shù)臀缓髠鬏敻呶?與SPI相反)
{
unsigned char data_18b20=0;
unsigned char n=1;
while(n)
{
monobus_0;
delay_us(2); //拉低總線1-3us,通知從機準備收發(fā)數(shù)據(jù)
monobus_1; //釋放總線
delay_us(5); //從機在1-25us內(nèi)會向總線輸出數(shù)據(jù)的某一位(1或者0)
if(monobus_in) data_18b20+=n; //讀取總線數(shù)據(jù)
delay_us(55); //等待從機釋放總線
n<<=1;
}
return data_18b20;
}
//**********************************************************************************
//**********************************************************************************
/*************************************************************
使用者只需把這個nokia3310.h的文件復(fù)制到工程目錄即可
使用nokia3310庫函數(shù)時,請先定義3310與MCU的連接
本例子3310LCD與 單片機 的連接如下
RESET PB1
D/C PB2
SDIN PB3
SCLK PB5
SCE GND
英文字庫,5*8點陣,每一個字符占用5個字節(jié),共94個可顯示字符數(shù)據(jù)**/
#define RESET PORTB.1 //RESET=0時,LCD復(fù)位
#define DC PORTB.2 //DC=0_指令,DC=1_數(shù)據(jù)
#define SDIN PORTB.3
#define SCLK PORTB.5