【原創+整理】基於紅外通信的溫度監測仿真

【原創+整理】基於紅外通信的溫度監測仿真+用到的知識整理

一、總線

1、總線概述
計算機系統是以微處理器爲核心的,各器件要與微處理器相連,且必須協調工作,所以在微處理機中引入了總線的概念,各器件共同享用總線,任何時候只能有一個器件發送數據(可以有多個器件同時接收數據) 。

計算機的總線分爲控制總線、地址總線和數據總線等三種。而數據總線用於傳送數據,控制總線用於傳送控制信號, 地址總線則用於選擇存儲單元或外設。
2、51單片機的三總線結構

數據總線是P0口,共8位;地址總線高8位是P2口,低8位是P0口,共16位。;數據總線有WR,RD等。

(1)數據總線

51 單片機的數據總線爲P0 口,P0 口爲雙向數據通道,CPU 從P0 口送出和讀回數據。

(2)地址總線

51 系列單片機的地址總線爲16 位。

爲了節約芯片引腳,採用P0 口複用方式,除了作爲數據總線外,在ALE 信號時序匹配下,通過外置的數據鎖存器,在總線訪問前半週期從P0口送出低8位地址,後半週期從P0 口送出8 位數據。

高8位地址則通過P2 口送出。

(3)控制總線

51 系列單片機的控制總線包括讀控制信號P3.7 和寫控制信號P3.6 等,二者分別作爲總線模式下數據讀和數據寫的使能信號。

原文鏈接:https://blog.csdn.net/lijinshanba/article/details/80911816

二、DS18B20溫度傳感器

DS18B20性能

①獨特的單線接口方式,DS18B20在與微處理器連接時僅需要一條口線即可實現微處理器與DS18B20的雙向通訊。

②測溫範圍-55℃~+125℃,固有測溫誤差(注意,不是分辨率,這裏之前是錯誤的)1℃。

③支持多點組網功能,多個DS18B20可以並聯在唯一的三線上,最多隻能並聯8個,實現多點測溫,如果數量過多,會使供電電源電壓過低,從而造成信號傳輸的不穩定。

④工作電源:3.0~5.5V/DC(可以數據線寄生電源)

⑤在使用中不需要任何外圍元件

⑥測量結果以9~12位數字量方式串行傳送

⑦不鏽鋼保護管直徑Φ6

⑧適用於DN1525,DN40DN250各種介質工業管道和狹小空間設備測溫

⑨標準安裝螺紋M10X1,M12X1.5,G1/2”任選

⑩PVC電纜直接出線或德式球型接線盒出線,便於與其它電器設備連接。
**

DS18B20引腳圖及功能

DS18B20內部結構主要由四部分組成:64位光刻ROM、溫度傳感器、非揮發的溫度報警觸發器TH和TL、配置寄存器。

利用DS18B20做一個溫控器(DS18B20引腳圖_工作原理及應用電路)
在這裏插入圖片描述
  1、GND爲電源地

2、DQ爲數字信號輸入/輸出端

3、VDD爲外接供電電源輸入端(在寄生電源接線方式時接地)。

DS18B20工作原理

DS18B20的讀寫時序和測溫原理與DS1820相同,只是得到的溫度值的位數因分辨率不同而不同,且溫度轉換時的延時時間由2s減爲750ms。
DS18B20測溫原理如圖所示。
圖中低溫度係數晶振的振盪頻率受溫度影響很小,用於產生固定頻率的脈衝信號送給計數器1。
高溫度係數晶振隨溫度變化其振盪率明顯改變,所產生的信號作爲計數器2的脈衝輸入。
計數器1和溫度寄存器被預置在-55℃所對應的一個基數值。計數器1對低溫度係數晶振產生的脈衝信號進行減法計數,
當計數器1的預置值減到0時,溫度寄存器的值將加1,計數器1的預置將重新被裝入,計數器1重新開始對低溫度係數晶振產生的脈衝信號進行計數,
如此循環直到計數器2計數到0時,停止溫度寄存器值的累加,此時溫度寄存器中的數值即爲所測溫度。
斜率累加器用於補償和修正測溫過程中的非線性,其輸出用於修正計數器1的預置值。
在這裏插入圖片描述

DS18B20指令及寄存器

1、溫度寄存器

2、精度寄存器
在這裏插入圖片描述
3、ROM指令表
在這裏插入圖片描述
4、RAM指令表
在這裏插入圖片描述
參考鏈接:https://blog.csdn.net/zhangxuechao_/article/details/74991985

三、AMPIRE128X64型LCD屏

1、引腳作用

在這裏插入圖片描述
CS1:左半屏選擇引腳,低電平有效。該引腳有效時左半屏幕操作有效。

CS2:右半屏選擇引腳,低電平有效。該引腳有效時右半屏幕操作有效。

GND:電源地

VCC:電源正

V0:LCD的驅動電壓,其實可以用它來調節LCD藍哇哇的皮膚的深淺。

RS:命令/數據控制引腳。該腳爲高電平是DB數據線上傳輸的是數據,該腳爲低電平是DB數據線上傳輸的是命令。

R/W:讀/寫控制引腳。該腳爲高電平時從LCD模塊中毒數據,該腳爲低電平時寫數據到LCD模塊中。

E:LCD讀寫使能引腳(E表示模塊使能引腳,但是注意這裏表示的是讀寫使能引腳,最好初始化的時候給個低電平,)

DB:數據總線。

RST:復位腳

-Vout:LCD的驅動電源。

2、軟件驅動程序

(1)選擇需要顯示的屏幕
通過CS1,CS2組合來選擇驅動的是左半邊屏幕還是右半邊屏幕,還是兩邊的屏幕一起驅動,還是說兩邊的屏幕都不驅動顯示。具體組合如下。
在這裏插入圖片描述
並不是說CS1==0 CD2 == 1就只顯示左邊屏幕而不顯示右邊屏幕。而是描述的是接下來的操作只與左邊屏幕有關,與右邊屏幕沒有關係。
當你在操作屏幕顯示的時候必須先指明要修改哪一邊屏幕的內容。
我們只需要知道要想讓屏幕顯示,就得先告訴他左右哪邊的屏幕顯示。
(2)設置顯示的行
整個屏幕從上到下共有64行
但是
但是
但是
真正讓我們選擇的只有8行
只有8行
一行就是一行164個像素點,也就是說所謂的設置顯示的行只是選擇顯示的在哪一頁
搞清楚了設置顯示的行(頁)的問題,那麼所謂的64行是什麼玩意,那又是怎麼回事呢。
其實還有條指令是設置開始顯示的首行位置,
也就是說,你可以通過設置開始行來選擇第一行的位置,
如果你設置第開始行是0行,
那麼第1頁就是0-7行,
第二頁就是8-15行,
如果你設置的開始行數是第1行,
那麼第一頁就是1-8行,
第二頁就是9-16行…。
其可以表示爲設置的首行爲x(x<64)行,
那麼第y頁的起始行數是 (y
8+x)%64,
結束行數是(y*8+x+7)%64;
不可以實現從任意行顯示。

(3)設置顯示的開始列
整個屏幕共有64128個像素點,也就是說共有64行和128列
前面說過,該LCD分爲左右兩塊屏幕,兩塊屏幕需要通過CS1與CS2組合來進行控制。這兩塊屏幕各佔64列,也就是說一塊屏幕的像素點是64
64,所以我們在設置顯示起始列的時候實際上能選擇的只有0-63列這個範圍。
起始列設置的在哪一列開始顯示,就在那一列開始顯示,並且每顯示完一列就自動加1。

(4)設置顯示的數據(圖像)
該LCD顯示的方式是一列一列開始顯示,每顯示完一列,記錄列數的地址自動加1,也就是說如果你送入的數據是0x88,那麼就會顯示當前頁的當前列的8個相熟點,由上往下爲10001000,瞭解這個對取模至關重要。
驅動的常用指令
#define LCD_CLEAR 0X01 //lcd清屏
#define LCD_SHOW_MODE(x) (0x02+x) //選擇顯示模式 0允許輸入IRAM地址 1允許輸入垂直捲動地址
#define LCD_SHOW_OFF 0X3E //lcd顯示關
#define LCD_SHOW_ON 0X3F //lcd顯示開
#define LCD_PAGE(x) (0xb8+x) //設置頁數
#define LCD_HANG(x) (0xc0+x) //設置起始行
#define LCD_LEI(x) (0x40+x) //設置起始列

寫一條數據到LCD中的流程
(1)查忙。

(2)RS = H/L(H:顯示數據 L:操作指令)

(3)RW = L(寫數據)

(4)E = H (使能讀寫數據)

(5)送入數據到DB口

(6)E = L (送入數據)
具體程序如下所示
void lcd12864_WriteCommed (unsigned char commed) //12864寫命令
{
lcd12864_Busy (); //12864查忙
lcdRsPin(PIN_LOW);
lcdRwPin(PIN_LOW);
lcdEnPin(PIN_HIGH);
LCD_DATA = commed;
lcd12864_delay (5); //延時函數
LCD_EN = 0;
}
void lcd12864_WriteData (unsigned char dat) //12864寫數據
{
lcd12864_Busy (); //12864查忙
lcdRsPin(PIN_HIGH);
lcdRwPin(PIN_LOW);
lcdEnPin(PIN_HIGH);
LCD_DATA = dat;
lcd12864_delay (5); //延時函數
lcdEnPin(PIN_LOW) ;
}
void lcd12864_Busy (void) //12864查忙
{

    LCD_DATA = 0XFF;
    lcdRsPin(PIN_LOW);
    lcdRwPin(PIN_HIGH);
    lcdEnPin(PIN_HIGH);
    while(LCD_DATA&0x80);
    lcdEnPin(PIN_LOW) ; 

}
https://blog.csdn.net/qq_33784286/article/details/103067878

四、程序實例

(一)發射端程序

1、DS18B20 溫度傳感器驅動程序

DS18B20.h

#ifndef  __18B20_H__
#define  __18B20_H__
#define uchar unsigned char
#define uint  unsigned int
sbit DQ=P1^0;
   void delay_18B20(unsigned int i);   //DS18B20延時
   Init_DS18B20(void);   //DS18B20初始化函數
   unsigned char ReadOneChar(void);  //讀取一個字節
   WriteOneChar(unsigned char dat);	  //寫入一個字節
   unsigned char ds18b2o_s(void);
#endif
、
、
、

DS18B20.c

#include<reg52.h>    
#include"18b20.h"
#include<intrins.h>   

/***********ds18b20延遲函數*******/ 
void delay_18B20(uint i)
{
	while(i--);
}

/**********ds18b20初始化函數**********************
 Init_DS18B20(void)	
{
    bit flag;
    DQ=1;         //DQ復位  DQ--數字信號輸入輸出端
	_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); 
	DQ=0;          //單片機將DQ拉低
	 delay_18B20(80); //精確延時 大於 480us
	DQ=1;         //拉高總線
	 delay_18B20(2);
	 if(DQ==1) flag=1 ;
     else flag=0;
	 delay_18B20(20);
}
/************從DS18B20讀取一個字節數據**************/ 
unsigned char ReadOneChar(void)
 {
	uchar i=0;
	uchar dat = 0;
	for (i=8;i>0;i--)
	 {	  _nop_();
		  DQ=0; // 給脈衝信號
		  DQ=1; 
		  dat>>=1;    //右移一位,空位補0
		  delay_18B20(2);
		  if(DQ)
		  dat|=0x80;	 //1000 0000  按位或	1|0=1   1|1=1  0|0=0		
		  delay_18B20(4);
	 }
 	return(dat);
}
/*********向DS18B20寫入一個字節***********/  
WriteOneChar(unsigned char dat)
{
    unsigned char i=0;
 	for (i=8; i>0; i--)
 	{
  	DQ=0;
		delay_18B20(1);
 	DQ = dat&0x01;     按位或與   0 & 0=0    0 & 1= 0    1 & 0= 0     1 & 1= 1delay_18B20(5);
 	DQ=1;
    	dat>>=1;
 }
   delay_18B20(4);
}



/**************讀取ds18b20當前溫度************/
uchar ds18b2o_s(void)
{
	uchar temp;
    while(Init_DS18B20()==1) ;
	WriteOneChar(0xCC);	// 跳過讀序號列號的操作    讀寫指令,可由上文ROM、RAM指令集查找
	WriteOneChar(0x44); 	// 啓動溫度轉換
    delay_18B20(1500);       // this message is wery important
    while(Init_DS18B20()==1) ;
	WriteOneChar(0xCC); 	//跳過讀序號列號的操作
	WriteOneChar(0xBE); 	//讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度
    delay_18B20(1500);
    DPL=ReadOneChar();    	//讀取溫度值低位
    DPH=ReadOneChar();   		//讀取溫度值高位
    temp=(((DPH)*256+DPL)>>4);    //當前採集溫度值除16得實際溫度值		 0.0625約爲1/16'c
	return(temp);
}

2、紅外發射程序

hongwaifashe.h

#ifndef __HONGWAIFASHE_H__
#define __HONGWAIFASHE_H__
#define uchar unsigned char 
#define uint  unsigned int 
extern uchar setdata[2]; 
void  ZZ(uchar x);
void  Z0(uchar temp);
void  TT0(bit BT,uint x);
#define SBM   0x80                //識別碼
#define m9    (65536-9000) 	      //約9mS
#define m4_5  (65536-4500) 	      //約4.5mS
#define m1_68  (65536-1680) 	      //約1.68mS
//#define m_65  (65536-580) 	      //約0.65mS
#define m_56  (65536-560) 	      //約0.56mS
#define m40   (65536-40000)       //約40mS
//#define m56   (65536-56000)       //56mS
//#define m2_25 (65536-2250)        //約2.25mS

sbit IR = P3^0;				  //定義發射引腳(接PNP三極管基極,) 三極管起電流放大作用

extern void hongwaifashe(void);
#endif
/
/
/
/
hongwaifashe.c

#include <reg52.h>
#include <intrins.h>
#include "hongwaifashe.h"

 void hongwaifashe(void)
{ 

  TMOD = 0x01;         //T0 16位工作方式
  IR=1;				   //發射端口常態爲高電平

ZZ(setdata[0]);
ZZ(setdata[1]);
}


  void ZZ(uchar x)
{ 
  TT0(1,m9);		   //高電平9mS
  TT0(0,m4_5);	       //低電平4.5mS

  /*┈ 發送4幀數據 ┈*/
  Z0(SBM);													                               
  Z0(~SBM);
  Z0(x);
  Z0(~x);

  /*┈┈ 結束碼 ┈┈*/
  TT0(1,m_56);
  TT0(0,m40);
}

/*┈┈┈┈┈┈┈單幀發送程序┈┈┈┈┈┈┈┈*/
void Z0(uchar temp)
{ 
  uchar v;
  for (v=0;v<8;v++)                     //循環8次移位 
       {     
	         TT0(1,m_56);		        //高電平0.65mS         
			 if(temp&0x01) TT0(0,m1_68); //發送最低位
			 else          TT0(0,m_56);     
			 temp >>= 1;                //右移一位 
        }    
}

/*┈┈┈┈┈┈┈38KHz脈衝發射 + 延時┈┈┈┈┈┈*/
void TT0(bit BT,uint x)
{
  TH0 = x>>8;	            //輸入T0初始值
  TL0 = x;
  TF0=0;			        //清0
  TR0=1;			        //啓動定時器0
  if(BT == 0) while(!TF0);	//BT=0時不發射38KHz脈衝只延時;BT=1發射38KHz脈衝且延時;
  else while(1)			    //38KHz脈衝,佔空比1:5
         {
		  IR = 0;
		  if(TF0)break;
 	      if(TF0)break;
		  IR = 1;
  	      if(TF0)break;
   	      if(TF0)break;
   	      if(TF0)break;
		  if(TF0)break;
   	      if(TF0)break;
   	      if(TF0)break;
   	      if(TF0)break;
   	      if(TF0)break;
   	      if(TF0)break;
		  if(TF0)break;
		 }
  TR0=0;			        //關閉定時器0
  TF0=0;			        //標誌位溢出則清0

  IR =1;			        //脈衝停止後,發射端口常態爲高電平
}

3、主函數

main.c

#include<reg52.h>  
#include"18b20.h"
#include"lamp.h"
#include "hongwaifashe.h"
#define uchar unsigned char
#define uint  unsigned int
uchar setdata[2];
void main(void)
{
 while(1)
 {
  setdata[0]=ds18b20_s();
  setdata[1]=lamp();
  hongwaifashe();
 }
}


## (二)接收端程序

**1、LCD  12864 驅動程序**
LCD.h


```c
   #ifndef _12864_H_
    #define _12864_H_
 	#define LCD P0  /*LCD端口*/
	#define uint unsigned int 
    #define uchar	unsigned char
    /****漢字數組聲明****/
extern	uchar code WUYOU[2][32];
extern	uchar code XIAN[32];
extern	uchar code HUAN[32];
extern	uchar code JING[32];
extern 	uchar code JIAN[32];
extern	uchar code CE[32];
extern  uchar code WEN[32];
extern  uchar code DU[32];
extern  uchar code MAOHAO[32];
extern  uchar code LIANG[32];
extern  uchar code DUHAO[32];
extern  uchar code SHUZI[10][32];

   

	/*控制信號宏定義*/
    sbit CS1  = P2^1;
	sbit CS2  = P2^0;
	sbit E    = P2^3;
	sbit RW   = P2^4;
	sbit RS   = P2^5;
	
	sbit busy_bit =P0^7;
   	extern void lcd_mwc( uchar i);
	extern void lcd_mwd( uchar i );
	extern void lcd_clear(void);
    extern void lcd_init(void);
    extern void dispm_zi_up( uchar code *zi);
	extern void dispm_zi_down( uchar code *zi);
 	
	#endif	

/
/
/
LCD.c

#include<reg52.h>
	#include"12864.h"
	#include<intrins.h>
	 uchar code WUYOU[2][32]={{0x00,0x40,0x42,0x42,0x42,0x42,0xFE,0x42,
	                    0xC2,0x42,0x43,0x42,0x60,0x40,0x00,0x00,
                        0x00,0x80,0x40,0x20,0x18,0x06,0x01,0x00,
                        0x3F,0x40,0x40,0x40,0x40,0x40,0x70,0x00},
						{0x04,0x04,0x04,0x84,0xE4,0x3C,0x27,0x24,
	                     0x24,0x24,0x24,0xF4,0x24,0x06,0x04,0x00,
                         0x04,0x02,0x01,0x00,0xFF,0x09,0x09,0x09,
                         0x09,0x49,0x89,0x7F,0x00,0x00,0x00,0x00}};
	 uchar code XIAN[32]={0x00,0x20,0x30,0xAC,0x63,0x20,0x30,0x20,
	                      0x20,0xFF,0x90,0x92,0x94,0xD0,0x80,0x00,
                          0x20,0x62,0x23,0x12,0x12,0x12,0x41,0x41,
                          0x21,0x17,0x18,0x24,0x42,0x80,0xE0,0x00};
	 uchar code HUAN[32]={0x42,0x42,0xFE,0x43,0x42,0x04,0x04,0x04,
	                      0x84,0xE4,0x1C,0x84,0x04,0x06,0x04,0x00,
                          0x20,0x60,0x3F,0x10,0x10,0x04,0x02,0x01,
                          0x00,0xFF,0x00,0x00,0x01,0x03,0x06,0x00};
	 uchar code JING[32]={0x20,0x20,0xFF,0x20,0x20,0x24,0xA4,0xAC,
	                      0xB5,0xA6,0xB4,0xAC,0xE6,0xB4,0x20,0x00,
                          0x10,0x30,0x1F,0x08,0x88,0x80,0x4F,0x3A,
                          0x0A,0x0A,0x7A,0x8A,0x8F,0x80,0xE0,0x00};
 	 uchar code JIAN[32]={0x00,0x00,0xFC,0x00,0x00,0xFF,0x00,0x20,
	                      0x10,0x0F,0x18,0x28,0x6C,0x08,0x00,0x00,
                          0x40,0x40,0x7E,0x42,0x42,0x7F,0x42,0x42,
                          0x42,0x7E,0x42,0x42,0x7F,0x42,0x40,0x00};
	 uchar code CE[32]={0x10,0x22,0x6C,0x00,0x80,0xFC,0x04,0xF4,
	                    0x04,0xFE,0x04,0xF8,0x00,0xFE,0x00,0x00,
                        0x04,0x04,0xFE,0x01,0x40,0x27,0x10,0x0F,
                        0x10,0x67,0x00,0x47,0x80,0x7F,0x00,0x00};
     uchar code WEN[32]={0x10,0x22,0x64,0x0C,0x80,0x00,0xFE,0x92,
	                     0x92,0x92,0x92,0x92,0xFF,0x02,0x00,0x00,
                         0x04,0x04,0xFE,0x01,0x40,0x7E,0x42,0x42,
                         0x7E,0x42,0x7E,0x42,0x42,0x7E,0x40,0x00};
     uchar code DU[32]={0x00,0x00,0xFC,0x24,0x24,0x24,0xFC,0xA5,
	                    0xA6,0xA4,0xFC,0x24,0x34,0x26,0x04,0x00,
                        0x40,0x20,0x9F,0x80,0x42,0x42,0x26,0x2A,
                        0x12,0x2A,0x26,0x42,0x40,0xC0,0x40,0x00};
     uchar code MAOHAO[32]={0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,
	                        0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x31,
							0x31,0x30,0x00,0x00,0x00,0x00,0x00,0x00};

     uchar code DUHAO[32]={ 0x00,0x06,0x09,0x09,0xE6,0xF0,0x18,0x08,
	                        0x08,0x08,0x18,0x30,0x78,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x07,0x0F,0x18,0x30,
                            0x20,0x20,0x20,0x10,0x08,0x00,0x00,0x00};

 	 uchar code LIANG[32]={0x00,0x02,0x02,0x7A,0x4A,0x4A,0x4A,0x4B,
	                       0x4A,0x4A,0x4A,0x7E,0x0B,0x02,0x00,0x00,
                           0x04,0x83,0x81,0x41,0x3D,0x05,0x05,0x05,
                           0x05,0x05,0x7F,0x85,0x81,0x85,0xE3,0x00};
	
						   
	 
						   					   
	 uchar code SHUZI[10][32]={{0x00,0x00,0xE0,0xF0,0xF0,0x18,0x08,0x08,
	                            0x08,0x08,0x08,0x38,0xF0,0xE0,0xC0,0x00,
                                0x00,0x01,0x0F,0x1F,0x1F,0x30,0x20,0x20,
                                0x20,0x20,0x20,0x38,0x1F,0x0F,0x07,0x00},
								{0x00,0x00,0x00,0x00,0x10,0x10,0x10,0xF8,
								 0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,
                                 0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x3F,
                                 0x3F,0x3F,0x20,0x20,0x20,0x20,0x00,0x00},
								{0x00,0x00,0x20,0x70,0x78,0x08,0x08,0x08,
								 0x08,0x08,0x88,0xF8,0xF8,0x70,0x00,0x00,
                                 0x00,0x00,0x30,0x30,0x38,0x3C,0x34,0x36,
                                 0x32,0x33,0x31,0x31,0x30,0x38,0x08,0x00},
								{0x00,0x00,0x30,0x30,0x38,0x08,0x88,0x88,
								 0x88,0x88,0xD8,0xF8,0x70,0x20,0x00,0x00,
                                 0x00,0x00,0x18,0x18,0x38,0x20,0x21,0x21,
                                 0x21,0x21,0x21,0x3B,0x1E,0x1E,0x04,0x00},
								{0x00,0x00,0x00,0x00,0x80,0x80,0x40,0x60,
								 0x30,0xF0,0xF8,0xF8,0x00,0x00,0x00,0x00,
                                 0x00,0x00,0x06,0x07,0x05,0x04,0x24,0x24,
                                 0x24,0x3F,0x3F,0x3F,0x24,0x24,0x24,0x00},
								{0x00,0x00,0x00,0xF8,0xF8,0x88,0x88,0x88,
							 	 0xC8,0xC8,0x88,0x88,0x88,0x08,0x00,0x00,
                                 0x00,0x00,0x18,0x1D,0x39,0x20,0x20,0x20,
                                 0x20,0x20,0x20,0x3B,0x1F,0x0F,0x06,0x00},
								{0x00,0x00,0xC0,0xE0,0xF0,0x98,0x88,0x88,
								 0x88,0x88,0x98,0x98,0xB8,0x10,0x00,0x00,
                                 0x00,0x03,0x0F,0x1F,0x1F,0x31,0x20,0x20,
                                 0x20,0x20,0x20,0x31,0x1F,0x1F,0x0E,0x00},
								{0x00,0x00,0x30,0x38,0x18,0x18,0x08,0x08,
								 0x08,0x88,0xC8,0x68,0x38,0x18,0x08,0x00,
                                 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x3E,
                                 0x3F,0x03,0x00,0x00,0x00,0x00,0x00,0x00},
								{0x00,0x00,0x70,0xF0,0xD8,0xC8,0x88,0x88,
							     0x88,0x88,0x88,0x88,0xF8,0x70,0x20,0x00,
                                 0x00,0x08,0x1E,0x1E,0x33,0x21,0x21,0x21,
                                 0x21,0x21,0x23,0x23,0x1E,0x1E,0x0C,0x00},
								{0x00,0x00,0x70,0xF0,0xD8,0xC8,0x88,0x88,
								 0x88,0x88,0x88,0x88,0xF8,0x70,0x20,0x00,
                                 0x00,0x08,0x1E,0x1E,0x33,0x21,0x21,0x21,
                                 0x21,0x21,0x23,0x23,0x1E,0x1E,0x0C,0x00}};
	/*發命令i到主窗口*/
extern	void lcd_mwc( uchar i)
	{
	   
		RW=1;		   
		RS=0;
		do{ _nop_(); E=1;E=0;}
		 while(busy_bit);
		 RW=0;
		 E=1;
		 LCD=i;
		 E=0;
     }

    /*發數據i到主窗口*/
extern	 void  lcd_mwd( uchar i )
	 {	 	
	    
		 RW=1;
		 RS=0;
		do{ _nop_(); E=1;E=0;}
		 while(busy_bit);
		 RW=0;
		 RS=1;
		 E=1;
		 LCD=i;
		 E=0;
	  }

	
	  /*清屏*/
	  void lcd_clear(void)
	  {
	    uchar i,page;
		for(page=0xb8;page<0xc0;page++)
		{
		   lcd_mwc(page);
		   lcd_mwc(0x40);
		   for(i=0;i<64;i++)
		   lcd_mwd(0x00);
		 }
	 }
		  
	    /*初始化LCD*/
extern	 void lcd_init(void)
	 {	  
	  	lcd_mwc(0x3f);
		lcd_mwc(0x0c0);
	  }
     

	   /*dispm_zi_up()顯示漢字上半部*/
	 extern  void dispm_zi_up(uchar code *zi)
	   {
	      uchar i;
		  for(i=0;i<16;i++)
		  lcd_mwd(*(zi+i));
	   }

		    /*dispm_zi_down()顯示漢字下半部*/
	  extern void dispm_zi_down(uchar code *zi)
	   {
	      uchar i;
		  for(i=16;i<32;i++)
		  lcd_mwd(*(zi+i));
	   }

2、主函數
main.c

#include<reg52.h>
#include"12864.h"
#include<intrins.h> 
sbit IR=P3^2;           //將IR位定義爲P3.2引腳
unsigned char a[4];    //儲存用戶碼、用戶反碼與鍵數據碼、鍵數據反碼
unsigned char zai=0,om,pm,qm;

unsigned int LowTime,HighTime; //儲存高、低電平的寬度 
void fenjie()
{	
  if(a[2]==0x80)
     zai=0;
	  else if(a[2]==0xc0)
	  zai=1;
           else
		   {
		     om=a[2]/100;
			 pm=a[2]/10%10;
			 qm=a[2]%100%10;
		   }
   
}
bit DeCode(void)        
{
    
   unsigned char  i,j;
	unsigned char temp;    //儲存解碼出的數據
	for(i=0;i<4;i++)      //連續讀取4個用戶碼和鍵數據碼
	  {
		 for(j=0;j<8;j++)  //每個碼有8位數字
			 {
	         temp=temp>>1;  //temp中的各數據位右移一位,因爲先讀出的是高位數據									
			   TH0=0;         //定時器清0
			   TL0=0;         //定時器清0
			   TR0=1;         //開啓定時器T0
		      while(IR==0)   //如果是低電平就等待
	               ;	      //低電平計時
		  	   TR0=0;         //關閉定時器T0
			   LowTime=TH0*256+TL0;    //保存低電平寬度
			   TH0=0;         //定時器清0
			   TL0=0;         //定時器清0
			   TR0=1;         //開啓定時器T0
			  while(IR==1)   //如果是高電平就等待
			       ;			   
			   TR0=0;        //關閉定時器T0
			   HighTime=TH0*256+TL0;   //保存高電平寬度
			   if((LowTime<360)||(LowTime>680))   
			  		    return 0;        //如果低電平長度不在合理範圍,則認爲出錯,停止解碼			
			   if((HighTime>400)&&(HighTime<680))   //如果高電平時間在560微秒左右,即計數560/1.085=516次
			           temp=temp&0x7f;       //(520-100=420, 520+100=620),則該位是0
			   if((HighTime>1400)&&(HighTime<1850)) //如果高電平時間在1680微秒左右,即計數1680/1.085=1548次
			           temp=temp|0x80;       //(1550-250=1300,1550+250=1800),則該位是1
		     }  			            
	   a[i]=temp;	//將解碼出的字節值儲存在a[i]																					 
    }  				 		 
  if(a[2]=~a[3])  //驗證鍵數據碼和其反碼是否相等,一般情況下不必驗證用戶碼
	 return 1;     //解碼正確,返回1
}
void init(void)
{
    E=1;
	CS1=0;CS2=0;	 
    lcd_clear();
    lcd_init();
	EA=1;        //開啓總中斷
  
   ET0=1;       //定時器T0中斷允許
   IT0=1;       //外中斷的下降沿觸發  
    TMOD=0x01;   //使用定時器T0的模式1	
	TR0=0;       //定時器T0關閉
  EX0=1;       //開外中斷0
  
}
void display()
{
   CS1=0;
	 CS2=1;
   lcd_mwc(0xb8);	// 無線環境監測 
   lcd_mwc(0x50);
   dispm_zi_up(&WUYOU[0][0]);
   dispm_zi_up(&XIAN);
   dispm_zi_up(&HUAN);
   
  

   lcd_mwc(0xb9);
   lcd_mwc(0x50);
   dispm_zi_down(&WUYOU[0][0]);
   dispm_zi_down(&XIAN);
   dispm_zi_down(&HUAN);
  

   lcd_mwc(0xba);	// 溫度 
   lcd_mwc(0x40);
   dispm_zi_up(&WEN);
   dispm_zi_up(&DU);
   dispm_zi_up(&MAOHAO);
   dispm_zi_up(&SHUZI[om][0]);
  



   lcd_mwc(0xbb);
   lcd_mwc(0x40);
   dispm_zi_down(&WEN);
   dispm_zi_down(&DU);
   dispm_zi_down(&MAOHAO);
   dispm_zi_down(&SHUZI[om][0]);
  

   lcd_mwc(0xbc);		 //亮度
   lcd_mwc(0x40);
   dispm_zi_up(&LIANG);
   dispm_zi_up(&DU);
   dispm_zi_up(&MAOHAO);
 
  

   lcd_mwc(0xbd);
   lcd_mwc(0x40);
   dispm_zi_down(&LIANG);
   dispm_zi_down(&DU);
   dispm_zi_down(&MAOHAO);
  
  		CS1=1;
		CS2=0;
   lcd_mwc(0xb8);	// 無線環境監測 
   lcd_mwc(0x40);
   dispm_zi_up(&JING);
   dispm_zi_up(&JIAN);
   dispm_zi_up(&CE);

	lcd_mwc(0xb9);
    lcd_mwc(0x40);
    dispm_zi_down(&JING);
    dispm_zi_down(&JIAN);
    dispm_zi_down(&CE);

	lcd_mwc(0xba);	// 溫度 
    lcd_mwc(0x40);
	dispm_zi_up(&SHUZI[pm][0]);
    dispm_zi_up(&SHUZI[qm][0]);
    dispm_zi_up(&DUHAO);

	lcd_mwc(0xbb);
    lcd_mwc(0x40);
    dispm_zi_down(&SHUZI[pm][0]);
    dispm_zi_down(&SHUZI[qm][0]);
    dispm_zi_down(&DUHAO);

	lcd_mwc(0xbc);		 //亮度
    lcd_mwc(0x40);
	dispm_zi_up(&WUYOU[zai][0]);

	lcd_mwc(0xbd);
    lcd_mwc(0x40);
    dispm_zi_down(&WUYOU[zai][0]);	 

}
void main(void)
{		
    init();
	while(1)
	{ 
	   // fenjie(); 
  	display();


    }
 
}


/************紅外線觸發的外中斷處理************/
void Int0(void) interrupt 0
  {	 
     EX0=0;      //關閉外中斷0,不再接收二次紅外信號的中斷,只解碼當前紅外信號
	  TH0=0;      //定時器T0的高8位清0
	 TL0=0;      //定時器T0的低8位清0
	  TR0=1;	    //開啓定時器T0	 
	  while(IR==0);          //如果是低電平就等待,給引導碼低電平計時
	  TR0=0;                //關閉定時器T0     
	  LowTime=TH0*256+TL0;  //保存低電平時間
	  if(((LowTime>8500)&&(LowTime<9500))!=1) {EX0=1;return;} 
	  TH0=0;      //定時器T0的高8位清0
	  TL0=0;      //定時器T0的低8位清0
	fenjie();   TR0=1;	    //開啓定時器T0
 while(IR==1);  //如果是高電平就等待,給引導碼高電平計時
	  
	  
	  TR0=0;        //關閉定時器T0
	  HighTime=TH0*256+TL0;	//保存引導碼的高電平長度
  if((HighTime>4000)&&(HighTime<5000))
		{	 
                	DeCode();
                   fenjie();     
		 
          }
		  
	EX0=1; 
 
  }

五、proteus仿真

仿真圖如下
在這裏插入圖片描述

原文鏈接:https://blog.csdn.net/qq_33784286/article/details/103067878

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章