|
- /********************************************
- 讀取DS18B20溫度,通過LCD1602顯示出來
- 第一行: 實時溫度值
- 第二行: 最大值和最小值
- ********************************************/
- /*頭文件*/
- #include <reg52.h>
- #include <intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
- #define AddWr 0x90 //寫數(shù)據(jù)地址
- #define AddRd 0x91 //讀數(shù)據(jù)地址
- unsigned char ReadADC(unsigned char Chl);
- bit ack; //應答標志位
- sbit SDA=P2^0;
- sbit SCL=P2^1;
- sbit lcd_rs_port = P3^5; /*定義LCD控制端口*/
- sbit lcd_rw_port = P3^6;
- sbit lcd_en_port = P3^4;
- #define lcd_data_port P0
- ////////////////////////////////////////
- sbit WELA=P2^7; //數(shù)碼管的位選信號
- void delay1 (void)//關(guān)閉數(shù)碼管延時程序
- {
- int k;
- for (k=0; k<1000; k++);
- }
- void _Nop(void)//I2C延時程序
- {
- int k;
- for (k=0; k<10; k++);
- }
- //////////////////////////////////////
- /*------------------------------------------------
- 啟動總線
- ------------------------------------------------*/
- void Start_I2c()
- {
- SDA=1; //發(fā)送起始條件的數(shù)據(jù)信號
- _Nop();
- SCL=1;
- _Nop(); //起始條件建立時間大于4.7us,延時
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- SDA=0; //發(fā)送起始信號
- _Nop(); //起始條件鎖定時間大于4μ
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- SCL=0; //鉗住I2C總線,準備發(fā)送或接收數(shù)據(jù)
- _Nop();
- _Nop();
- }
- /*------------------------------------------------
- 結(jié)束總線
- ------------------------------------------------*/
- void Stop_I2c()
- {
- SDA=0; //發(fā)送結(jié)束條件的數(shù)據(jù)信號
- _Nop(); //發(fā)送結(jié)束條件的時鐘信號
- SCL=1; //結(jié)束條件建立時間大于4μ
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- SDA=1; //發(fā)送I2C總線結(jié)束信號
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- }
- /*----------------------------------------------------------------
- 字節(jié)數(shù)據(jù)傳送函數(shù)
- 函數(shù)原型: void SendByte(unsigned char c);
- 功能: 將數(shù)據(jù)c發(fā)送出去,可以是地址,也可以是數(shù)據(jù),發(fā)完后等待應答,并對
- 此狀態(tài)位進行操作.(不應答或非應答都使ack=0 假)
- 發(fā)送數(shù)據(jù)正常,ack=1; ack=0表示被控器無應答或損壞。
- ------------------------------------------------------------------*/
- void SendByte(unsigned char c)
- {
- unsigned char BitCnt;
- for(BitCnt=0;BitCnt<8;BitCnt++) //要傳送的數(shù)據(jù)長度為8位
- {
- if((c<<BitCnt)&0x80)SDA=1; //判斷發(fā)送位
- else SDA=0;
- _Nop();
- SCL=1; //置時鐘線為高,通知被控器開始接收數(shù)據(jù)位
- _Nop();
- _Nop(); //保證時鐘高電平周期大于4μ
- _Nop();
- _Nop();
- _Nop();
- SCL=0;
- }
- _Nop();
- _Nop();
- SDA=1; //8位發(fā)送完后釋放數(shù)據(jù)線,準備接收應答位
- _Nop();
- _Nop();
- SCL=1;
- _Nop();
- _Nop();
- _Nop();
- if(SDA==1)ack=0;
- else ack=1; //判斷是否接收到應答信號
- SCL=0;
- _Nop();
- _Nop();
- }
- /*----------------------------------------------------------------
- 字節(jié)數(shù)據(jù)傳送函數(shù)
- 函數(shù)原型: unsigned char RcvByte();
- 功能: 用來接收從器件傳來的數(shù)據(jù),并判斷總線錯誤(不發(fā)應答信號),
- 發(fā)完后請用應答函數(shù)。
- ------------------------------------------------------------------*/
- unsigned char RcvByte()
- {
- unsigned char retc;
- unsigned char BitCnt;
- retc=0;
- SDA=1; //置數(shù)據(jù)線為輸入方式
- for(BitCnt=0;BitCnt<8;BitCnt++)
- {
- _Nop();
- SCL=0; //置時鐘線為低,準備接收數(shù)據(jù)位
- _Nop();
- _Nop(); //時鐘低電平周期大于4.7us
- _Nop();
- _Nop();
- _Nop();
- SCL=1; //置時鐘線為高使數(shù)據(jù)線上數(shù)據(jù)有效
- _Nop();
- _Nop();
- retc=retc<<1;
- if(SDA==1)retc=retc+1; //讀數(shù)據(jù)位,接收的數(shù)據(jù)位放入retc中
- _Nop();
- _Nop();
- }
- SCL=0;
- _Nop();
- _Nop();
- return(retc);
- }
- /*----------------------------------------------------------------
- 應答子函數(shù)
- 原型: void Ack_I2c(void);
- ----------------------------------------------------------------*/
- /*void Ack_I2c(void)
- {
- SDA=0;
- _Nop();
- _Nop();
- _Nop();
- SCL=1;
- _Nop();
- _Nop(); //時鐘低電平周期大于4μ
- _Nop();
- _Nop();
- _Nop();
- SCL=0; //清時鐘線,鉗住I2C總線以便繼續(xù)接收
- _Nop();
- _Nop();
- }*/
- /*----------------------------------------------------------------
- 非應答子函數(shù)
- 原型: void NoAck_I2c(void);
- ----------------------------------------------------------------*/
- void NoAck_I2c(void)
- {
- SDA=1;
- _Nop();
- _Nop();
- _Nop();
- SCL=1;
- _Nop();
- _Nop(); //時鐘低電平周期大于4μ
- _Nop();
- _Nop();
- _Nop();
- SCL=0; //清時鐘線,鉗住I2C總線以便繼續(xù)接收
- _Nop();
- _Nop();
- }
- /////////////////////////////////////
- //////////////以下是LCD1602驅(qū)動程序////////////////
- void lcd_delay(uchar ms) /*LCD1602 延時*/
- {
- uchar j;
- while(ms--){
- for(j=0;j<250;j++)
- {;}
- }
- }
- void lcd_busy_wait() /*LCD1602 忙等待*/
- {
- lcd_rs_port = 0;
- lcd_rw_port = 1;
- lcd_en_port = 1;
- lcd_data_port = 0xff;
- while (lcd_data_port&0x80);
- lcd_en_port = 0;
- }
- void lcd_command_write(uchar command) /*LCD1602 命令字寫入*/
- {
- lcd_busy_wait();
- lcd_rs_port = 0;
- lcd_rw_port = 0;
- lcd_en_port = 0;
- lcd_data_port = command;
- lcd_en_port = 1;
- lcd_en_port = 0;
- }
- void lcd_system_reset() /*LCD1602 初始化*/
- {
- lcd_delay(20);
- lcd_command_write(0x38);
- lcd_delay(100);
- lcd_command_write(0x38);
- lcd_delay(50);
- lcd_command_write(0x38);
- lcd_delay(10);
- lcd_command_write(0x08);
- lcd_command_write(0x01);
- lcd_command_write(0x06);
- lcd_command_write(0x0c);
- }
- void lcd_char_write(uchar x_pos,y_pos,lcd_dat) /*LCD1602 字符寫入*/
- {
- x_pos &= 0x0f; /* X位置范圍 0~15 */
- y_pos &= 0x01; /* Y位置范圍 0~ 1 */
- if(y_pos==1) x_pos += 0x40;
- x_pos += 0x80;
- lcd_command_write(x_pos);
- lcd_busy_wait();
- lcd_rs_port = 1;
- lcd_rw_port = 0;
- lcd_en_port = 0;
- lcd_data_port = lcd_dat;
- lcd_en_port = 1;
- lcd_en_port = 0;
- }
- void lcd_bad_check() /*LCD1602 壞點檢查*/
- {
- char i,j;
- for(i=0;i<2;i++){
- for(j=0;j<16;j++) {
- lcd_char_write(j,i,0xff);
- }
- }
- lcd_delay(200);
- lcd_delay(200);
- lcd_delay(200);
- lcd_delay(100);
- lcd_delay(200);
- lcd_command_write(0x01); /* clear lcd disp */
- }
- //////////////////以上是LCD1602驅(qū)動程序////////////////
- //////////////////以下是DS18B20驅(qū)動程序////////////////
- //////////////////以上是DS18B20驅(qū)動程序////////////////
- /*定義數(shù)字ascii編碼*/
- unsigned char mun_char_table[]={"0123456789abcdef"};
- unsigned char temp_table[] ={"light: "};
- /*1MS為單位的延時程序*/
- void delay_1ms(uchar x)
- {
- uchar j;
- while(x--){
- for(j=0;j<125;j++)
- {;}
- }
- }
- main()
- {
-
- unsigned int i=0;
-
- lcd_system_reset(); /*LCD1602 初始化*/
- ////////////////////////////////////////////////////////////////
- P0=0X00;//關(guān)掉數(shù)碼管的位選信號。阻止數(shù)碼管受到P0口信號的影響。
- delay1();
- WELA=1;
- delay1();
- WELA=0;
- ////////////////////////////////////////////////////////////////
- lcd_bad_check(); /*LCD1602 壞點檢查*/
- for (i=0;i<9;i++) lcd_char_write(i,0,temp_table[i]);
- while(1){
- i=255-ReadADC(1);//值取差值,用于顯示光強越小,數(shù)值越小
- lcd_char_write(7,0,mun_char_table[i/100]); /*把溫度顯示出來*/
- lcd_char_write(8,0,mun_char_table[i%100/10]);
- lcd_char_write(9,0,mun_char_table[i%10]);
- delay_1ms(100);
- }
- }
- /*------------------------------------------------
- 讀AD轉(zhuǎn)值程序
- 輸入?yún)?shù) Chl 表示需要轉(zhuǎn)換的通道,范圍從0-3
- 返回值范圍0-255
- ------------------------------------------------*/
- unsigned char ReadADC(unsigned char Chl)
- {
- unsigned char Val;
- Start_I2c(); //啟動總線
- SendByte(AddWr); //發(fā)送器件地址
- if(ack==0)return(0);
- SendByte(0x40|Chl); //發(fā)送器件子地址
- if(ack==0)return(0);
- Start_I2c();
- SendByte(AddWr+1);
- if(ack==0)return(0);
- Val=RcvByte();
- NoAck_I2c(); //發(fā)送非應位
- Stop_I2c(); //結(jié)束總線
- return(Val);
- }
復制代碼 |
-
-
51開發(fā)板使用手冊.pdf
2017-7-6 08:49 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
12.32 MB, 下載次數(shù): 64, 下載積分: 黑幣 -5
(51開發(fā)板)
|