4 7
您的位置: 电子制作DIY -> 单片机 -> 51单片机 -> 单片机红外遥控开关程序及设计
本帖共有642个阅读者
发表帖子 发表投票 回复主题
单片机红外遥控开关程序及设计
尊贵身份标志
wujinlin(VIP会员)
wujinlin
头衔:社区公民
帮派:无帮无派
帖数:26
金钱:380
积分:112
注册时间:2020/12/30
楼主信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线
单片机红外遥控开关程序及设计

一、发射部分的工作原理

发射系统开始运行时,单片机首先调用程序里面的按键扫描子程序,按键扫描子
程序不停的扫描 16 个按键,检测是否有按键按下,无按键按下时,系统处于等待状 态;一旦有按键按下时,单片机根据按键值,然后转入发射子程序,发射子程序根据
预定的要求装入不同的脉冲个数,然后调制成 40KHz 的载波信号,通过单片机的 P3.5
口发出,为了提高抗干扰和降低能耗,经过三极管放大后然后由红外发射管想空中发射。

编码方式是采用码分编码,通过不同的脉冲个数来编码的。不同的脉冲个数代表
不同的编码,按键 0 的编码的脉冲个数是 2,按键1 是 3 个脉冲,依次类推,按键 15 是 17 个脉冲。为了接收可靠,第一位码的码宽我们设计成
3ms,其余的为 1ms,遥 控的数据帧间大于 10ms。

图 4.1 P3-5
输出口编码波形图

二、接收部分原理

系统上电初始化后,对单片机的
P3-1 口进行检测,当红外线接收管输出脉冲数 据帧时,第一位码是低电平时,单片机将启动中断程序,实时的接收数据帧,同时对
第一位码的码宽进行验证,如果第一位码的低电码宽小于 2ms 时,单片机将作为错误处理,如果间隔位高电平脉宽大于
3ms,便结束接收。然后系统根据累加器中的脉冲个数,来执行相应的程序,操作单片机的各个输出口,来控制小灯的亮灭和显示发
射端的按键值和队可控亮度小灯进行亮度控制和亮度值显示。

遥控系统的编码及解码

图 4.2

第三节  
遥控发射及接收控制程序流程图

一、 遥控发射控制流程图

图 4.3
遥控发射程序控制流程图

图4.3,左边是发射部分的主程序,先进行初始化,然后执行键盘扫描。右边是 按键扫描程序,先是程序不断扫描键盘是否有按键按下,如果有按键按下,便调用发
射子程序和显示子程序。

图 4.4
遥控发射控制流程图

图 4.4 是发射过程,首先按照我们自己定义的协议,装入脉冲个数,第一个脉冲 发送的是 3ms
的脉冲,方便接收端识别,然后发1ms 脉冲,停发是 1ms 脉冲,直到
发完所有的脉冲便结束这个过程

最全单片机红外开关设计论文预览:

单片机源程序如下:
#include "reg51.h"
#include "intrins.h"              //_nop_();延时函数用
#define uchar unsigned char
#define uint unsigned int
sbit              remoteout=P3^5;              //  遥控输出口
uchar temp,key;
uint              m;
uchar code              table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
/***********延时化函数**********/
void              delayms(uint xms)
{
uint i,j;
for(i=xms;i>0;i--)
for(j=120;j>0;j--);
}
/***********初始化函数**********/
clearmen()
{
remoteout=0;              //关遥控输出
IE=0x00;              //IE 单片机寄存器              此句表示单片机复位
IP=0x01;              //开启外部中断 0
TMOD=0x22;              //单片机工作在方式2 即 8 位自动重装 模式
TH1=0xf3;              //40KHZ 初值
TL1=0xf3;              //当 TF1 计数溢出时,常数 TH0
里的常数重装入 TL1
EA=1;              //开总中断
}
/***********按键显示函数**********/
void display(uchar num)
{
P0=table[num];
}
/**********发射函数************/
sed()
{
ET1=1;              //开计数器 1 中断
TR1=1;              //开定时器 1
delayms(3);
ET1=0;              //关
TR1=0;
remoteout=0;              //40KHZ 发 3 毫秒
for(m=key;m>0;m--)
{
delayms(1);              //停 1 毫秒
ET1=1; TR1=1; delayms(1);

ET1=0; TR1=0;
remoteout=0;              //40KHZ 发 1 毫秒
}
delayms(10);
}
tx()              //这个子函数是在发射脉冲个数,
不同的按键装入不同的按键个数
{
switch(key)
{
case 0:key=key+1;sed();break; case 1:key=key+1;sed();break; case 2:key=key+1;sed();break; case 3:key=key+1;sed();break; case 4:key=key+1;sed();break; case 5:key=key+1;sed();break; case 6:key=key+1;sed();break; case 7:key=key+1;sed();break; case 8:key=key+1;sed();break; case 9:key=key+1;sed();break; case 10:key=key+1;sed();break; case 11:key=key+1;sed();break; case 12:key=key+1;sed();break; case 13:key=key+1;sed();break; case 14:key=key+1;sed();break; case 15:key=key+1;sed();break; default:break;
}
}
/***********按键扫描函数**********/
void matrixkeyscan()
{
P2=0xfe; temp= P2; temp=temp&0xf0; if(temp!=0xf0)
{
delayms(10);
temp= P2; temp=temp&0xf0; if(temp!=0xf0)
{ temp=P2; switch(temp)
{
case 0xee:   key=0;break; case 0xde:    key=1;break; case 0xbe:    key=2;break; case 0x7e:    key=3;break;
}
while(temp!=0xf0)
{ temp=P2; temp=temp&0xf0;
}
display(key);

tx();
}
}
P2=0xfd; temp=P2; temp=temp&0xf0; if(temp!=0xf0)
{
delayms(10);
temp=P2; temp=temp&0xf0; if(temp!=0xf0)
{ temp=P2; switch(temp)
{
case 0xed:    key=4;break; case 0xdd:   key=5;break; case 0xbd:   key=6;break; case 0x7d:   key=7;break;
}
while(temp!=0xf0)
{
temp=P2;temp=temp&0xf0;
}
display(key);
tx();
}
} P2=0xfb;temp=P2;temp=temp&0xf0; if(temp!=0xf0)
{ delayms(10);temp=P2;temp=temp&0xf0; if(temp!=0xf0)
{ temp=P2; switch(temp)
{
case 0xeb:              key=8;break; case 0xdb:              key=9;break; case 0xbb:              key=10;break; case 0x7b:              key=11;break;
}
while(temp!=0xf0)
{
temp=P2;temp=temp&0xf0;
}
display(key);
tx();
}
} P2=0xf7;temp=P2;temp=temp&0xf0; if(temp!=0xf0)
{
delayms(10);
temp=P2;

temp=temp&0xf0;
if(temp!=0xf0)
{
temp=P2;
switch(temp)
{
case 0xe7:    key=12;break; case 0xd7:   key=13;break; case 0xb7:    key=14;break; case 0x77:    key=15;break;
}
while(temp!=0xf0)
{ temp=P2; temp=temp&0xf0;
} display(key); tx();
}
}
}
/***********主函数**********/
void main()
{
clearmen();
   while(1)
{
matrixkeyscan();
}
}
/*********40KHZ 发生器***********/
//              定时中断 T1
void time_intt1(void) interrupt 3
{
remoteout=~remoteout;              //遥控开关取反
}
//*********************结束**************************//
接收端
/*********************************************************************/
/
/*********************************************************************/
//              接收端
/*********************************************************************/
//使用 AT89C52 单片机,12MHZ 晶振,
//
//#pragma src(E:\remote.asm)
#include "reg51.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
#define disout P2
sbit  dula=P3^7;
uchar code  table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
sbit sbit sbit   remotein=P3^1; sin=P3^0; K1=P0^0;
// 遥控输入
//基准正弦波相位输入
sbit  K2=P0^1;
sbit K3=P0^2;
sbit K4=P0^3;
sbit K5=P0^4;
sbit K6=P0^5;
sbit K7=P0^6;
sbit K8=P0^7;
uint i,j,m,n,k,s=1;
uint keyvol;              //值存放
//
/*********1 毫秒延时程序**********/
delay1ms(uint t)
{
for(i=0;i<t;i++)
for(j=0;j<120;j++);
}
/***********初始化函数**********/
clearmen()
{ dula=0; EX0=1;
EA=1;              //开总中断
}
/**********函数************/
loop()
{
switch(disout&0x07)
{
case 0:{s=1;break;}
case 1:{s=2;break;} case 2:{s=3;break;} case 3:{s=4;break;} case 4:{s=5;break;} case 5:{s=6;break;} case 6:{s=7;break;} case 7:{s=8;break;} default:break;}
}
xianshi()
{
dula=1; P1=table[keyvol-2] ; dula=0;
}
/***********主函数***************/
main()
{
clearmen();              //初始化
loop();
while(1)
{
while(sin==1); delay1ms(s); K8=0;delay1ms(1);K8=1;
}
}
/************外中断遥控接收函数**************/
//外中断 0
void intt0(void) interrupt 0
{
EX0=0;keyvol=0;
if(remotein==0)
{delay1ms(1);
if(remotein==0)
{while(1)
{while(remotein==0);
keyvol++;k=0;
while(remotein==1){delay1ms(1);k++;if(k>2){ xianshi();goto OOUUTT; xianshi();};}
}
OOUUTT:
switch(keyvol)
{
case 2:{K1=~K1;break;}
case 3:{K2=~K2;break;} case 4:{K3=~K3;break;} case 5:{K4=~K4;break;} case 6:{K5=~K5;break;} case 7:{K6=~K6;break;} case 8:{K7=~K7;break;}
case 9:{if(disout==0x00){disout=0xff;}else{disout--;}loop();break;}
default:break;
}
}
}
EX0=1;
}
//
//*********************结束**************************//


「该帖子被 wujinlin 在 2020/12/30 23:50:22 编辑过」

这家伙很懒,什么也没有留下!
等级:VIP会员 参考IP地址:*.*.*.*
2020/12/30 23:01:11
Copyright © 2011 电子制作DIY. All rights reserved.电子制作DIY7256 Call, 1 Queries, Processed in 429.688 millisecond(2),