【原创+整理】基于红外通信的温度监测仿真

【原创+整理】基于红外通信的温度监测仿真+用到的知识整理

一、总线

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

发布了3 篇原创文章 · 获赞 0 · 访问量 180

猜你喜欢

转载自blog.csdn.net/weixin_44127810/article/details/104035634
今日推荐