|
- /********************************************
- 讀取DS18B20溫度,通過LCD1602顯示出來
- 第一行: 實時溫度值
- 第二行: 最大值和最小值
- ********************************************/
- /*頭文件*/
- #include <reg52.h>
- #include <intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
- #define AddWr 0x90 //寫數據地址
- #define AddRd 0x91 //讀數據地址
- 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; //數碼管的位選信號
- void delay1 (void)//關閉數碼管延時程序
- {
- 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; //發送起始條件的數據信號
- _Nop();
- SCL=1;
- _Nop(); //起始條件建立時間大于4.7us,延時
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- SDA=0; //發送起始信號
- _Nop(); //起始條件鎖定時間大于4μ
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- SCL=0; //鉗住I2C總線,準備發送或接收數據
- _Nop();
- _Nop();
- }
- /*------------------------------------------------
- 結束總線
- ------------------------------------------------*/
- void Stop_I2c()
- {
- SDA=0; //發送結束條件的數據信號
- _Nop(); //發送結束條件的時鐘信號
- SCL=1; //結束條件建立時間大于4μ
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- SDA=1; //發送I2C總線結束信號
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- }
- /*----------------------------------------------------------------
- 字節數據傳送函數
- 函數原型: void SendByte(unsigned char c);
- 功能: 將數據c發送出去,可以是地址,也可以是數據,發完后等待應答,并對
- 此狀態位進行操作.(不應答或非應答都使ack=0 假)
- 發送數據正常,ack=1; ack=0表示被控器無應答或損壞。
- ------------------------------------------------------------------*/
- void SendByte(unsigned char c)
- {
- unsigned char BitCnt;
- for(BitCnt=0;BitCnt<8;BitCnt++) //要傳送的數據長度為8位
- {
- if((c<<BitCnt)&0x80)SDA=1; //判斷發送位
- else SDA=0;
- _Nop();
- SCL=1; //置時鐘線為高,通知被控器開始接收數據位
- _Nop();
- _Nop(); //保證時鐘高電平周期大于4μ
- _Nop();
- _Nop();
- _Nop();
- SCL=0;
- }
- _Nop();
- _Nop();
- SDA=1; //8位發送完后釋放數據線,準備接收應答位
- _Nop();
- _Nop();
- SCL=1;
- _Nop();
- _Nop();
- _Nop();
- if(SDA==1)ack=0;
- else ack=1; //判斷是否接收到應答信號
- SCL=0;
- _Nop();
- _Nop();
- }
- /*----------------------------------------------------------------
- 字節數據傳送函數
- 函數原型: unsigned char RcvByte();
- 功能: 用來接收從器件傳來的數據,并判斷總線錯誤(不發應答信號),
- 發完后請用應答函數。
- ------------------------------------------------------------------*/
- unsigned char RcvByte()
- {
- unsigned char retc;
- unsigned char BitCnt;
- retc=0;
- SDA=1; //置數據線為輸入方式
- for(BitCnt=0;BitCnt<8;BitCnt++)
- {
- _Nop();
- SCL=0; //置時鐘線為低,準備接收數據位
- _Nop();
- _Nop(); //時鐘低電平周期大于4.7us
- _Nop();
- _Nop();
- _Nop();
- SCL=1; //置時鐘線為高使數據線上數據有效
- _Nop();
- _Nop();
- retc=retc<<1;
- if(SDA==1)retc=retc+1; //讀數據位,接收的數據位放入retc中
- _Nop();
- _Nop();
- }
- SCL=0;
- _Nop();
- _Nop();
- return(retc);
- }
- /*----------------------------------------------------------------
- 應答子函數
- 原型: void Ack_I2c(void);
- ----------------------------------------------------------------*/
- /*void Ack_I2c(void)
- {
- SDA=0;
- _Nop();
- _Nop();
- _Nop();
- SCL=1;
- _Nop();
- _Nop(); //時鐘低電平周期大于4μ
- _Nop();
- _Nop();
- _Nop();
- SCL=0; //清時鐘線,鉗住I2C總線以便繼續接收
- _Nop();
- _Nop();
- }*/
- /*----------------------------------------------------------------
- 非應答子函數
- 原型: void NoAck_I2c(void);
- ----------------------------------------------------------------*/
- void NoAck_I2c(void)
- {
- SDA=1;
- _Nop();
- _Nop();
- _Nop();
- SCL=1;
- _Nop();
- _Nop(); //時鐘低電平周期大于4μ
- _Nop();
- _Nop();
- _Nop();
- SCL=0; //清時鐘線,鉗住I2C總線以便繼續接收
- _Nop();
- _Nop();
- }
- /////////////////////////////////////
- //////////////以下是LCD1602驅動程序////////////////
- 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驅動程序////////////////
- //////////////////以下是DS18B20驅動程序////////////////
- //////////////////以上是DS18B20驅動程序////////////////
- /*定義數字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;//關掉數碼管的位選信號。阻止數碼管受到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);//值取差值,用于顯示光強越小,數值越小
- 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轉值程序
- 輸入參數 Chl 表示需要轉換的通道,范圍從0-3
- 返回值范圍0-255
- ------------------------------------------------*/
- unsigned char ReadADC(unsigned char Chl)
- {
- unsigned char Val;
- Start_I2c(); //啟動總線
- SendByte(AddWr); //發送器件地址
- if(ack==0)return(0);
- SendByte(0x40|Chl); //發送器件子地址
- if(ack==0)return(0);
- Start_I2c();
- SendByte(AddWr+1);
- if(ack==0)return(0);
- Val=RcvByte();
- NoAck_I2c(); //發送非應位
- Stop_I2c(); //結束總線
- return(Val);
- }
復制代碼 |
-
-
51開發板使用手冊.pdf
2017-7-6 08:49 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
12.32 MB, 下載次數: 64, 下載積分: 黑幣 -5
(51開發板)
|