导航:首页 > 操作系统 > 基于51单片机的遥控器

基于51单片机的遥控器

发布时间:2023-06-13 18:14:55

❶ 基于51单片机红外遥控代码(C语言)

以下文件是51单片机实现遥控解码,通过数码管显示键码的程序,P0口驱动数码管段选,p2.6和p2.7为数码管位选,接收头连到P3.2口。此程序以通过验证,可以直接编译使用,另外还有一个继电器和蜂鸣器的控制,不用可以屏蔽掉。

;********************************************************************************
;* 描述: *
;* 遥控键值读取器 *
;* 数码管显示, P0口为数码管的数据口 *
;* *
;********************************************************************************
;遥控键值解码-数码管显示 *
;********************************************************************************/

#include <reg51.h>
#include <intrins.h>

void IR_SHOW();
void delay(unsigned char x);//x*0.14MS
void delay1(unsigned char ms);
void beep();

sbit IRIN = P3^2;
sbit BEEP = P3^7;
sbit RELAY= P1^3;
sbit GEWEI= P2^7;
sbit SHIWEI= P2^6;

unsigned char IRCOM[8];
unsigned char code table[16] =
{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
main()
{
IE = 0x81; //允许总中断中断,使能 INT0 外部中断
TCON = 0x1; //触发方式为脉冲负边沿触发
delay(1);

IRIN=1;
BEEP=1;
RELAY=1;
for(;;)
{
IR_SHOW();
}

} //end main

void IR_IN() interrupt 0 using 0
{
unsigned char i,j,k,N=0;
EA = 0;
I1:
for (i=0;i<4;i++)
{
if (IRIN==0) break;
if (i==3) {EA =1;return;}
}
delay(20);
if (IRIN==1) goto I1; //确认IR信号出现
while (!IRIN) //等 IR 变为高电平
{delay(1);}

for (j=0;j<4;j++)
{
for (k=0;k<8;k++)
{
while (IRIN) //等 IR 变为低电平
{delay(1);}
while (!IRIN) //等 IR 变为高电平
{delay(1);}
while (IRIN) //计算IR高电平时长
{
delay(1);
N++;
if (N>=30) {EA=1;return;}
}
IRCOM[j]=IRCOM[j] >> 1;
if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;}
N=0;
}//end for k
}//end for j

if (IRCOM[2]!=~IRCOM[3]) {EA=1;return;}
IRCOM[5]=IRCOM[2] & 0x0F;
IRCOM[6]=IRCOM[2] & 0xF0;
IRCOM[6]=IRCOM[6] >> 4;
beep();
EA = 1;

}

void IR_SHOW()
{
P0 = table[IRCOM[5]];
GEWEI = 0;
SHIWEI = 1;
delay1(4);
P0 = table[IRCOM[6]];
SHIWEI = 0;
GEWEI = 1;
delay1(4);
}

void beep()
{
unsigned char i;
for (i=0;i<100;i++)
{
delay(5);
BEEP=!BEEP;
}
BEEP=1;
}

void delay(unsigned char x)//x*0.14MS
{
unsigned char i;
while(x--)
{
for (i = 0; i<13; i++) {}
}
}

void delay1(unsigned char ms)
{
unsigned char i;
while(ms--)
{
for(i = 0; i<120; i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}

❷ 用51单片机制作学习型红外遥控器的原理

以下是程序,调试成功,LCD1602显示

//本解码程序适用于NEC的upd6121及其兼容芯片的解码,支持大多数遥控器实验板采用11.0592MHZ晶振

#include<reg52.h>//包含单片机寄存器的头文件

#include<intrins.h>//包含_nop_()函数定义的头文件

sbitIR=P3^2;//将IR位定义为P3.2引脚

sbitRS=P2^0;//寄存器选择位,将RS位定义为P2.0引脚

sbitRW=P2^1;//读写选择位,将RW位定义为P2.1引脚

sbitE=P2^2;//使能信号位,将E位定义为P2.2引脚

sbitBF=P0^7;//忙碌标志位,,将BF位定义为P0.7引脚

sbitBEEP=P3^6;//蜂鸣器控制端口P36

unsignedcharflag;

unsignedcharcodestring[]={"1602IR-CODETEST"};

unsignedchara[4];//储存用户码、用户反码与键数据码、键数据反码

unsignedintLowTime,HighTime;//储存高、低电平的宽度

/*****************************************************

函数功能:延时1ms

***************************************************/

voiddelay1ms()

{

unsignedchari,j;

for(i=0;i<10;i++)

for(j=0;j<33;j++)

;

}

/*****************************************************

函数功能:延时若干毫秒

入口参数:n

***************************************************/

voiddelay(unsignedcharn)

{

unsignedchari;

for(i=0;i<n;i++)

delay1ms();

}

/*********************************************************/

voidbeep()//蜂鸣器响一声函数

{

unsignedchari;

for(i=0;i<100;i++)

{

delay1ms();

BEEP=!BEEP;//BEEP取反

}

BEEP=1;//关闭蜂鸣器

delay(250);//延时

}

/*****************************************************

函数功能:判断液晶模块的忙碌状态

返回值:result。result=1,忙碌;result=0,不忙

***************************************************/

unsignedcharBusyTest(void)

{

bitresult;

RS=0;//根据规定,RS为低电平,RW为高电平时,可以读状态

RW=1;

E=1;//E=1,才允许读写

_nop_();//空操作

_nop_();

_nop_();

_nop_();//空操作四个机器周期,给硬件反应时间

result=BF;//将忙碌标志电平赋给result

E=0;

returnresult;

}

/*****************************************************

函数功能:将模式设置指令或显示地址写入液晶模块

入口参数:dictate

***************************************************/

voidWriteInstruction(unsignedchardictate)

{

while(BusyTest()==1);//如果忙就等待

RS=0;//根据规定,RS和R/W同时为低电平时,可以写入指令

RW=0;

E=0;//E置低电平(根据表8-6,写指令时,E为高脉冲,

//就是让E从0到1发生正跳变,所以应先置"0"

_nop_();

_nop_();//空操作两个机器周期,给硬件反应时间

P0=dictate;//将数据送入P0口,即写入指令或地址

_nop_();

_nop_();

_nop_();

_nop_();//空操作四个机器周期,给硬件反应时间

E=1;//E置高电平

_nop_();

_nop_();

_nop_();

_nop_();//空操作四个机器周期,给硬件反应时间

E=0;//当E由高电平跳变成低电平时,液晶模块开始执行命令

}

/*****************************************************

函数功能:指定字符显示的实际地址

入口参数:x

***************************************************/

voidWriteAddress(unsignedcharx)

{

WriteInstruction(x|0x80);//显示位置的确定方法规定为"80H+地址码x"

}

/*****************************************************

函数功能:将数据(字符的标准ASCII码)写入液晶模块

入口参数:y(为字符常量)

***************************************************/

voidWriteData(unsignedchary)

{

while(BusyTest()==1);

RS=1;//RS为高电平,RW为低电平时,可以写入数据

RW=0;

E=0;//E置低电平(根据表8-6,写指令时,E为高脉冲,

//就是让E从0到1发生正跳变,所以应先置"0"

P0=y;//将数据送入P0口,即将数据写入液晶模块

_nop_();

_nop_();

_nop_();

_nop_();//空操作四个机器周期,给硬件反应时间

E=1;//E置高电平

_nop_();

_nop_();

_nop_();

_nop_();//空操作四个机器周期,给硬件反应时间

E=0;//当E由高电平跳变成低电平时,液晶模块开始执行命令

}

/*****************************************************

函数功能:对LCD的显示模式进行初始化设置

***************************************************/

voidLcdInitiate(void)

{

delay(15);//延时15ms,首次写指令时应给LCD一段较长的反应时间

WriteInstruction(0x38);//显示模式设置:16×2显示,5×7点阵,8位数据接口

delay(5);//延时5ms

WriteInstruction(0x38);

delay(5);

WriteInstruction(0x38);

delay(5);

WriteInstruction(0x0C);//显示模式设置:显示开,有光标,光标闪烁

delay(5);

WriteInstruction(0x06);//显示模式设置:光标右移,字符不移

delay(5);

WriteInstruction(0x01);//清屏幕指令,将以前的显示内容清除

delay(5);

}

/************************************************************

函数功能:对4个字节的用户码和键数据码进行解码

说明:解码正确,返回1,否则返回0

出口参数:dat

*************************************************************/

bitDeCode(void)

{

unsignedchari,j;

unsignedchartemp;//储存解码出的数据

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<370)||(LowTime>640))

return0;//如果低电平长度不在合理范围,则认为出错,停止解码

if((HighTime>420)&&(HighTime<620))//如果高电平时间在560微秒左右,即计数560/1.085=516次

temp=temp&0x7f;//(520-100=420,520+100=620),则该位是0

if((HighTime>1300)&&(HighTime<1800))//如果高电平时间在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])//验证键数据码和其反码是否相等,一般情况下不必验证用户码

return1;//解码正确,返回1

}

/*------------------二进制码转换为压缩型BCD码,并显示---------------*/

voidtwo_2_bcd(unsignedchardate)

{

unsignedchartemp;

temp=date;

date&=0xf0;

date>>=4;//右移四位得到高四位码

date&=0x0f;//与0x0f想与确保高四位为0

if(date<=0x09)

{

WriteData(0x30+date);//lcd显示键值高四位

}

else

{

date=date-0x09;

WriteData(0x40+date);

}

date=temp;

date&=0x0f;

if(date<=0x09)

{

WriteData(0x30+date);//lcd显示低四位值

}

else

{

date=date-0x09;

WriteData(0x40+date);

}

WriteData(0x48);//显示字符'H'

}

/************************************************************

函数功能:1602LCD显示

*************************************************************/

voidDisp(void)

{

WriteAddress(0x40);//设置显示位置为第一行的第1个字

two_2_bcd(a[0]);

WriteData(0x20);

two_2_bcd(a[1]);

WriteData(0x20);

two_2_bcd(a[2]);

WriteData(0x20);

two_2_bcd(a[3]);

}

/************************************************************

函数功能:主函数

*************************************************************/

voidmain()

{

unsignedchari;

LcdInitiate();//调用LCD初始化函数

delay(10);

WriteInstruction(0x01);//清显示:清屏幕指令

WriteAddress(0x00);//设置显示位置为第一行的第1个字

i=0;

while(string[i]!='')//''是数组结束标志

{//显示字符WWW.RICHMCU.COM

WriteData(string[i]);

i++;

}

EA=1;//开启总中断

EX0=1;//开外中断0

ET0=1;//定时器T0中断允许

IT0=1;//外中断的下降沿触发

TMOD=0x01;//使用定时器T0的模式1

TR0=0;//定时器T0关闭

while(1);//等待红外信号产生的中断

}

/************************************************************

函数功能:红外线触发的外中断处理函数

*************************************************************/

voidInt0(void)interrupt0

{

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;//保存低电平时间

TH0=0;//定时器T0的高8位清0

TL0=0;//定时器T0的低8位清0

TR0=1;//开启定时器T0

while(IR==1);//如果是高电平就等待,给引导码高电平计时

TR0=0;//关闭定时器T0

HighTime=TH0*256+TL0;//保存引导码的高电平长度

if((LowTime>7800)&&(LowTime<8800)&&(HighTime>3600)&&(HighTime<4700))

{

//如果是引导码,就开始解码,否则放弃,引导码的低电平计时

//次数=9000us/1.085=8294,判断区间:8300-500=7800,8300+500=8800.

if(DeCode()==1)//执行遥控解码功能

{

Disp();//调用1602LCD显示函数

beep();//蜂鸣器响一声提示解码成功

}

}

EX0=1;//开启外中断EX0

}

❸ 急需基于51单片机的红外遥控开关的设计原理图和程序(c语言版)

/*------------------------------------------------*/
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义

sbit IR=P3^2; //红外接口标志

#define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换
sbit DUAN=P2^6;//定义锁存使能端口 段锁存
sbit WEI=P2^7;// 位锁存
/*------------------------------------------------
全局变量声明
------------------------------------------------*/
unsigned char code dofly_DuanMa[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};// 显示段码值0~F
unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码
unsigned char TempData[8]; //存储显示值的全局变量
unsigned char irtime;//红外用全局变量

bit irpro_ok,irok;
unsigned char IRcord[4];
unsigned char irdata[33];

/*------------------------------------------------
函数声明
------------------------------------------------*/

void Ir_work(void);
void Ircordpro(void);
/*------------------------------------------------
显示函数,用于动态扫描数码管
输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示
如输入0表示从第一个显示。
Num表示需要显示的位数,如需要显示99两位数值则该值输入2
------------------------------------------------*/
void Display(unsigned char FirstBit,unsigned char Num)
{
static unsigned char i=0;

DataPort=0; //清空数据,防止有交替重影
DUAN=1; //段锁存
DUAN=0;

DataPort=dofly_WeiMa[i+FirstBit]; //取位码
WEI=1; //位锁存
WEI=0;

DataPort=TempData[i]; //取显示数据,段码
DUAN=1; //段锁存
DUAN=0;

i++;
if(i==Num)
i=0;

}
/*------------------------------------------------
定时器0中断处理
------------------------------------------------*/

void tim0_isr (void) interrupt 1 using 1
{
irtime++; //用于计数2个下降沿之间的时间
}
/*------------------------------------------------
定时器中断子程序
------------------------------------------------*/
void Timer1_isr(void) interrupt 3
{

TH1=(65536-2000)/256; //重新赋值 2ms
TL1=(65536-2000)%256;

Display(0,8); // 调用数码管扫描

}
/*------------------------------------------------
外部中断0中断处理
------------------------------------------------*/
void EX0_ISR (void) interrupt 0 //外部中断0服务函数
{
static unsigned char i; //接收红外信号处理
static bit startflag; //是否开始处理标志位

if(startflag)
{
if(irtime<63&&irtime>=33)//引导码 TC9012的头码,9ms+4.5ms
i=0;
irdata[i]=irtime;//存储每个电平的持续时间,用于以后判断是0还是1
irtime=0;
i++;
if(i==33)
{
irok=1;
i=0;
}
}
else
{
irtime=0;
startflag=1;
}

}

/*------------------------------------------------
定时器0初始化
------------------------------------------------*/
void TIM0init(void)//定时器0初始化
{

TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值
TH0=0x00; //重载值
TL0=0x00; //初始化值
ET0=1; //开中断
TR0=1;
}
/*------------------------------------------------
定时器初始化子程序
------------------------------------------------*/
void Init_Timer1(void)
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
//TH1=0x00; //给定初值
//TL1=0x00;
EA=1; //总中断打开
ET1=1; //定时器中断打开
TR1=1; //定时器开关打开
}
/*------------------------------------------------
外部中断0初始化
------------------------------------------------*/
void EX0init(void)
{
IT0 = 1; //指定外部中断0下降沿触发,INT0 (P3.2)
EX0 = 1; //使能外部中断
EA = 1; //开总中断
}
/*------------------------------------------------
键值处理
------------------------------------------------*/

void Ir_work(void)//红外键值散转程序
{

TempData[0]=dofly_DuanMa[IRcord[0]/16];
TempData[1]=dofly_DuanMa[IRcord[0]%16];
TempData[2]=dofly_DuanMa[IRcord[1]/16];
TempData[3]=dofly_DuanMa[IRcord[1]%16];
TempData[4]=dofly_DuanMa[IRcord[2]/16];
TempData[5]=dofly_DuanMa[IRcord[2]%16];
TempData[6]=dofly_DuanMa[IRcord[3]/16];
TempData[7]=dofly_DuanMa[IRcord[3]%16];
//Display(0,8); // 调用数码管扫描
irpro_ok=0;//处理完成标志

}
/*------------------------------------------------
红外码值处理
------------------------------------------------*/
void Ircordpro(void)//红外码值处理函数
{
unsigned char i, j, k;
unsigned char cord,value;

k=1;
for(i=0;i<4;i++) //处理4个字节
{
for(j=1;j<=8;j++) //处理1个字节8位
{
cord=irdata[k];
if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差
value|=0x80;
if(j<8)
{
value>>=1;
}
k++;
}
IRcord[i]=value;
value=0;
}
irpro_ok=1;//处理完毕标志位置1
}

/*------------------------------------------------
主函数
------------------------------------------------*/
void main(void)
{
EX0init(); //初始化外部中断
TIM0init();//初始化定时器
Init_Timer1();

while(1)//主循环
{
if(irok) //如果接收好了进行红外处理
{
Ircordpro();
irok=0;
}

if(irpro_ok) //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等
{
Ir_work();
}
}
}

51P3^2是外部中断,红外接收管接这个引脚就能接收到数据然后显示在数码管上

❹ N51如何生成遥控器

生成共有五个步骤。
一.同样使用51单片机作为控制芯片,同样只需要一个芯片和一个晶振电路单片机就能运行,但是注意可以将需要的引脚外拉。二.将按键开关的两端,一端连接到单片机引脚,另一端接到地,接单片机的一端再通过一个10K电阻上拉到5V,也可以不上拉,亲试能用,上拉的话稳定一些,能够防干扰,按键数目自行而定,按照遥控器的那件分布来在洞洞板上焊接。三.蓝牙信号脚要结对,只需要单片机的发射脚,即P3.1接到蓝牙模块的接收脚,注意和之前的不一样;蓝牙模块设置成主模块,但是注意车上的蓝牙设置成从模块,注意波特率一致。四.需要两节18650电池(两节7.2V),使用一个lm2940稳压芯片就可以产生5V电压给设备供电,或使用其他的5V电源来供电,比如说充电宝。五.启动程序。
单片机是一种控制芯片,一个微型的计算机,加上晶振,存储器,地址锁存器,逻辑门,显示器,按钮,扩展芯片,接口等构成单片机系统。利用51单片机内部UART功能和蓝牙模块实现单片机之间的无限遥控,主要通过编程用于控制其他单片机或微机系统。

❺ 基于51单片机的玩具车遥控器设计

与51单片机的玩具车的话,遥控器设计的遥控器的设计的话,你可以通过它的红外线控制

❻ 用51单片机制作电视机红外线遥控器需要哪些元器件,求电路图和流程图以及编程,最好是汇编编程

你这个程序,别说20 废物币,给 500 rmb,都没有人做的

❼ 可以用51单片机做红外遥控器吗

用 51单片机做红外接收比较好,发射器的话直接用普通电视或空调遥控器成品,成本很低,省去许多麻烦。

❽ 有关基于51单片机红外遥控器的问题

没有干扰的话,就是程序问题

阅读全文

与基于51单片机的遥控器相关的资料

热点内容
达内程序员培训西安 浏览:498
人保送车主惠app上怎么年检 浏览:604
android手机开机密码 浏览:480
linux查看某个进程命令 浏览:525
闲置的腾讯云服务器 浏览:437
rar压缩包mac 浏览:626
php混淆加密工具 浏览:581
java把数字拆分 浏览:464
如何下载svn服务器旧版本 浏览:559
命令与征服4攻略 浏览:914
实数四则运算法则概念 浏览:294
cs16优化命令 浏览:871
Minecraft云服务器免费 浏览:828
png压缩最小 浏览:182
老韩综app怎么看不了了 浏览:229
只有一个程序员的体验 浏览:323
用服务器地址怎么有网 浏览:552
路由器服务器昵称是什么 浏览:715
程序员男友消失了 浏览:401
程序员搜索框自动提示 浏览:28