【Proteus仿真】51单片机红外无线通信实验
【Proteus仿真】51单片机红外无线通信实验
- Proteus仿真

- 使用说明
接收端的单片机加载接收端的Hex文件,发射端加载发射端的Hex文件,仿真过程中,接收端响应有点慢,当长时间无数据发送时,接收端LCD12864屏幕会不显示的bug问题,基本可以实现功能的仿真,但是不是很完美。
接收端主程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
| #include<reg52.h> #include"12864.h" #include<intrins.h> //包含\_nop\_()函数定义的头文件 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 return 0; } 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; }
|
发射端主程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| #include<reg51.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]=ds18b2o\_s(); setdata[1]=lamp(); hongwaifashe(); } }
|
程序源码和仿真资源
1 2 3
| 链接:https://pan.baidu.com/s/1BlRccMQaNfeW2xAkrJZ\_fg 提取码:9y60
|
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!