這時我做的關于1602顯示其 的相關實驗。可以通過單片機讀取相關的溫度以及序碼。
一個是關于溫度顯示的源代碼,一個是可以切換的實驗結果。
單片機源程序如下:
- /**********************BST-V51實驗開發板例程************************
- * 平臺:BST-V51 + Keil U3 + STC89C52
- * 名稱:18B20實時溫度計1602顯示
- * 晶振:11.0592MHZ
- * 說明:免費開源,不提供源代碼分析.
- ******************************************************************/
- #include <reg52.H>
- #include <intrins.H>
- #include <math.H>
- #define uchar unsigned char
- #define uint unsigned int
- #define GPIO_KEY P3 //獨立鍵盤用P1口
- sbit dula = P2^6;
- sbit wela = P2^7;
- sbit RW = P1^1;
- sbit RS = P1^0;
- sbit LCD2 = P1^2;
- sbit LCDEN = P2^5;
- sbit DQ = P2^2; //定義DS18B20端口DQ
- sbit BEEP=P2^3 ; //蜂鳴器驅動線
- bit presence ;
- sbit K1 = P3^4;
- sbit K2 = P3^5;
- sbit K3 = P3^6;
- sbit K4 = P3^7;
- uchar code cdis1[ ] = {" DS18B20 OK "};
- uchar code cdis2[ ] = {" "};
- uchar code cdis3[ ] = {" DS18B20 ERR0R "};
- uchar code cdis4[ ] = {" PLEASE CHECK "};
- uchar code cdis5[ ] = {" xianzaiwendu: "};
- unsigned char data display[2] = {0x00,0x00};
-
- unsigned char data RomCode[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
- unsigned char Temp;
- unsigned char crc;
- void beep();
- #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
- /*******************************************************************/
- /* */
- /*us級延時函數 */
- /* */
- /*******************************************************************/
- void Delay(unsigned int num)
- {
- while( --num );
- }
-
- void delayUs()
- {
- _nop_();
- }
- void delayMs(uint a)
- {
- uint i, j;
- for(i = a; i > 0; i--)
- for(j = 100; j > 0; j--);
- }
- /******************************************************************/
- /* */
- /*檢查LCD忙狀態 */
- /*lcd_busy為1時,忙,等待。lcd-busy為0時,閑,可寫指令與數據。 */
- /* */
- /******************************************************************/
- bit lcd_busy()
- {
- bit result;
- RS = 0;
- // LCD1 = 1;
- LCDEN = 1;
- delayNOP();
- result = (bit)(P0&0x80);
- LCDEN = 0;
- return(result);
- }
-
- void writeComm(uchar comm)
- {
- RS = 0;
- P0 = comm;
- LCDEN = 1;
- delayUs();
- LCDEN = 0;
- delayMs(1);
- }
- //寫數據:RS=1, RW=0;
- void writeData(uchar dat)
- {
- RS = 1;
- P0 = dat;
- LCDEN = 1;
- delayUs();
- LCDEN = 0;
- delayMs(1);
- }
- /*******************************************************************/
- /* */
- /* LCD初始化設定 */
- /* */
- /*******************************************************************/
- void lcd_init()
- {
- RW = 0;
- delayMs(15);
- writeComm(0x01); //清除LCD的顯示內容
-
- writeComm(0x38); //16*2顯示,5*7點陣,8位數據
- delayMs(5);
- writeComm(0x38);
- delayMs(5);
- writeComm(0x38);
- delayMs(5);
- writeComm(0x0c); //顯示開,關光標
- delayMs(5);
- writeComm(0x06); //移動光標
- delayMs(5);
- writeComm(0x01); //清除LCD的顯示內容
- delayMs(5);
- }
-
- void init()
- {
- RW = 0;
- dula = wela = 0;
- writeComm(0x38);
- writeComm(0x0c);
- writeComm(0x06);
- writeComm(0x01);
- }
- Init_DS18B20(void)
- {
- DQ = 1; //DQ復位
- Delay(8); //稍做延時
- DQ = 0; //將DQ拉低
- Delay(90); //精確延時 大于 480us
- DQ = 1; //拉高總線
- Delay(8);
- presence = DQ; //讀取存在信號
- Delay(100);
- DQ = 1;
-
- return(presence); //返回信號,0=presence,1= no presence
- }
- void writeString(uchar * str, uchar length)
- {
- uchar i;
- for(i = 0; i < length; i++)
- {
- writeData(str[i]);
- }
- }
-
- /*******************************************************************/
- /* */
- /* 設定顯示位置 */
- /* */
- /*******************************************************************/
- void lcd_pos(uchar pos)
- {
- writeComm(pos | 0x80); //數據指針=80+地址變量
- }
- /**//*****************************DS18B20*******************************/
- void dsInit()
- {
-
- unsigned int i;
- DQ = 0;
- i = 100;
- while(i>0) i--;
- DQ = 1;
- i = 4;
- while(i>0) i--;
- }
-
- void dsWait()
- {
- unsigned int i;
- while(DQ);
- while(~DQ);
- i = 4;
- while(i > 0) i--;
- }
- bit readBit()
- {
- unsigned int i;
- bit b;
- DQ = 0;
- i++;
- DQ = 1;
- i++; i++;
- b = DQ;
- i = 8;
- while(i>0) i--;
- return b;
- }
- unsigned char readByte()
- {
- unsigned int i;
- unsigned char j, dat;
- dat = 0;
- for(i=0; i<8; i++)
- {
- j = readBit();
-
- dat = (j << 7) | (dat >> 1);
- }
- return dat;
- }
- void writebit(char bitval) {
- DQ = 0; // 將DQ 拉低開始寫時間隙
- if(bitval==1) DQ =1; // 如果寫1,DQ 返回高電平
- Delay(5); // 在時間隙內保持電平值,
- DQ = 1; // Delay函數每次循環延時16μs,因此delay(5) = 104μs
- }
- void writeByte(unsigned char dat)
- {
- unsigned int i;
- unsigned char j;
- bit b;
- for(j = 0; j < 8; j++)
- {
- b = dat & 0x01;
- dat >>= 1;
-
- if(b)
- {
- DQ = 0; i++; i++;
- DQ = 1;
- i = 8; while(i>0) i--;
- }
- else
- {
- DQ = 0;
- i = 8; while(i>0) i--;
- DQ = 1;
- i++; i++;
- }
- }
- }
- void sendChangeCmd()
- {
- dsInit();
- dsWait();
- delayMs(1);
- writeByte(0xcc);
- writeByte(0x44);
- }
- void sendReadCmd()
- {
- dsInit();
- dsWait();
- delayMs(1);
- writeByte(0xcc);
- writeByte(0xbe);
- }
- int getTmpValue()
- {
- unsigned int tmpvalue;
- int value;
- float t;
- unsigned char low, high;
- sendReadCmd();
-
- low = readByte();
- high = readByte();
-
- tmpvalue = high;
- tmpvalue <<= 8;
- tmpvalue |= low;
- value = tmpvalue;
-
- \
- t = value * 0.0625;
- \
- value = t * 100 + (value > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0減0.5
- return value;
- }
- void dis(int v)
- {
- unsigned char count;
- unsigned char datas[] = {0, 0, 0, 0, 0};
- unsigned int tmp = abs(v);
- datas[0] = tmp / 10000;
- datas[1] = tmp % 10000 / 1000;
- datas[2] = tmp % 1000 / 100;
- datas[3] = tmp % 100 / 10;
- datas[4] = tmp % 10;
- writeComm(0xc0+3);
- if(v < 0)
- {
- writeString("- ", 2);
- }
- else
- {
- writeString("+ ", 2);
- }
- if(datas[0] != 0)
- {
- writeData('0'+datas[0]);
- }
- for(count = 1; count != 5; count++)
- {
- writeData('0'+datas[count]);
- if(count == 2)
- {
- writeData('.');
- }
- }
- }
- /**//*****************************XULEIMA*******************************/
- void beep()
- {
- unsigned char y;
- for (y=0;y<100;y++)
- {
- Delay(60);
- BEEP=!BEEP; //BEEP取反
- }
- BEEP=1; //關閉蜂鳴器
- Delay(40000);
- }
- /*******************************************************************/
- /* */
- /* 讀取64位序列碼 */
- /* */
- /*******************************************************************/
- Read_RomCord(void)
- {
- unsigned char j;
- Init_DS18B20();
-
- writeByte(0x33); // 讀序列碼的操作
- for (j = 0; j < 8; j++)
- {
- RomCode[j] = readByte() ;
- }
- }
- /*******************************************************************/
- /* */
- /*DS18B20的CRC8校驗程序 */
- /* */
- /*******************************************************************/
- uchar CRC8()
- {
- uchar i,x; uchar crcbuff;
-
- crc=0;
- for(x = 0; x <8; x++)
- {
- crcbuff=RomCode[x];
- for(i = 0; i < 8; i++)
- {
- if(((crc ^ crcbuff)&0x01)==0)
- crc >>= 1;
- else {
- crc ^= 0x18; //CRC=X8+X5+X4+1
- crc >>= 1;
- crc |= 0x80;
- }
- crcbuff >>= 1;
- }
- }
- return crc;
- }
- /*******************************************************************/
- /* */
- /* 數據轉換與顯示 */
- /* */
- /*******************************************************************/
- Disp_RomCode()
- {
- uchar j;
- uchar H_num=0x40; //LCD第二行初始位置
- for(j=0;j<8;j++)
- {
- Temp = RomCode[j];
- display[0]=((Temp&0xf0)>>4);
- if(display[0]>9)
- { display[0]=display[0]+0x37;}
- else{display[0]=display[0]+0x30;}
- lcd_pos(H_num);
- writeData(display[0]); //高位數顯示
- H_num++;
- display[1]=(Temp&0x0f);
- if(display[1]>9)
- {display[1]=display[1]+0x37;}
- else {display[1]=display[1]+0x30;}
- lcd_pos(H_num);
- writeData(display[1]); //低位數顯示
- H_num++;
- }
- }
- /*******************************************************************/
- /* */
- /* DS18B20 OK 顯示菜單 */
- /* */
- /*******************************************************************/
- void Ok_Menu ()
- {
- uchar m;
- lcd_init(); //初始化LCD
-
- lcd_pos(0); //設置顯示位置為第一行的第1個字符
- m = 0;
- while(cdis1[m] != '\0')
- { //顯示字符
- writeData(cdis1[m]);
- m++;
- }
- lcd_pos(0x40); //設置顯示位置為第二行第1個字符
- m = 0;
- while(cdis2[m] != '\0')
- {
- writeData(cdis2[m]); //顯示字符
- m++;
- }
- }
- /*******************************************************************/
- /* */
- /* DS18B20 ERROR 顯示菜單 */
- /* */
- /*******************************************************************/
- void Error_Menu ()
- {
- uchar m;
- lcd_init(); //初始化LCD
-
- lcd_pos(0); //設置顯示位置為第一行的第1個字符
- m = 0;
- while(cdis3[m] != '\0')
- { //顯示字符
- writeData(cdis3[m]);
- m++;
- }
- lcd_pos(0x40); //設置顯示位置為第二行第1個字符
- m = 0;
- while(cdis4[m] != '\0')
- {
- writeData(cdis4[m]); //顯示字符
- m++;
- }
- }
- /**//*****************************DS18B20*******************************/
- void display64()
- {
- P0 = 0xff;
- P2 = 0xff;
- //while(1)
- //{
- Ok_Menu ();
- Read_RomCord(); //讀取64位序列碼
- CRC8(); //CRC效驗
- if(crc==0) //CRC效驗正確
- {
- Disp_RomCode(); //顯示64位序列碼
- }
-
- //}
- }
- void main()
- {
- int max;
-
- while(1)
- {
- if(K4==0)
- {
- delayMs(10);
- if(K4==0)
- {
- writeComm(0x01);
- display64();
-
- }
- }
- if(K1==0)
- {
- delayMs(10);
- if(K1==0)
- {
- writeComm(0x01);
- while(K4!=0)
-
- {
- init();
- writeString(cdis5, 16);
- delayMs(1000); //溫度轉換時間需要750ms以上
- writeComm(0xc0);
- dis(getTmpValue());
- if(max>2800)
- {
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
實驗.rar
(112.22 KB, 下載次數: 7)
2017-10-24 14:21 上傳
點擊文件名下載附件
|