求一份基于51单片机4X4矩阵键盘红外发射C语言程序,最好附原理图哦!!

2025-04-06 07:15:30
推荐回答(1个)
回答1:

#include "reg52.h"
sbit ir=P2^0;//红外发射管控制脚,使用24M晶振
sbit led = P2^1;
sbit ka=P1^0;
sbit kb=P1^1;
sbit kc=P1^2;
sbit kd=P1^3;
unsigned int count, set_count; //中断计数,设定中断次数
bit irflag,keyflag; //红外发送标志位,按键标志位
unsigned char irsys[]={0x00,0xff};//16位用户码
unsigned char irdata,ircode; //发送的红外数据
//---------------------------------------------------------------------------
void delay(unsigned int a)//延时约1ms,晶振24M ,此处延时不需很精确
{
unsigned char i;
while(--a!=0)
for(i=300;i>0;i--); //若是12M晶振i=125
}
//---------------------------------------------------------------------------
void keyscan() // 按键扫描
{
if(ka==0)
{ delay(5);
while(!ka);
keyflag=1;irdata=0x0a;

} //a键按下,则发射数据0x0a
if(kb==0)
{ delay(5);
while(!kb);
keyflag=1;irdata=0x0b;

} //a键按下,则发射数据0x0a
if(kc==0)
{ delay(5);
while(!kc);
keyflag=1;irdata=0x0c;

} //a键按下,则发射数据0x0a
if(kd==0)
{ delay(5);
while(!kd);
keyflag=1;irdata=0x0d;

} //a键按下,则发射数据0x0a
}
//---------------------------------------------------------------------------
void ir_sendbyte() //红外发送一个字节数据
{
unsigned char i;
for(i=0;i<8;i++) //发送8位数据
{
set_count=43;//35; //发送编码中的0.56ms高电平 (//后为12M晶振下的数值)
irflag=1; //启动红外发射二极管发射
count=0; //中断计数先清0
TR0=1; //开启定时器0
while(count TR0=0; //关闭定时器0
if(ircode&0x01) set_count=130;//130; //判断红外编码最低位,若为1则1.69ms的低电平 (//后为12M晶振下的数值)
else set_count=43;//35; //为0则0.565ms的低电平 (//后为12M晶振下的数值)
irflag=0; //低电平则不发射
count=0; //中断计数清0
TR0=1; //开启定时器0
while(count TR0=0; //关闭定时器0
ircode=ircode>>1; //将数据右移,即从低位到高位发送
}
}
//---------------------------------------------------------------------------
void ir_send() //发送红外数据
{
set_count=692;//672; //发送编码中的引导码(9ms高电平+4.5ms低电平) (//后为12M晶振下的数值) tc9012
irflag=1; //启动红外发射二极管发射
count=0; //中断计数清0
TR0=1;
while(count TR0=0;
set_count=346;//336; //发送编码中的4.5ms低电平(//后为12M晶振下的数值)
irflag=0; //低电平则不发射
count=0;
TR0=1;
while(count TR0=0;
ircode=irsys[0]; //发送16位用户码的前1-8位
ir_sendbyte();
ircode=irsys[1]; //发送16位用户码的前9-16位
ir_sendbyte();
ircode=irdata; //发送8位数据码
ir_sendbyte();
ircode=~irdata; //发送8位数据反码
ir_sendbyte();
set_count=43;//35; //发送编码中的0.56ms高电平 (//后为12M晶振下的数值)
irflag=1;
count=0;
TR0=1;
while(count TR0=0;
ir=1;
delay(23); //延时23ms(编码中的23ms低电平)
set_count=692;//670; //发送编码中的引导码(9ms高电平+4.5ms低电平) (//后为12M晶振下的数值)
irflag=1;
count=0;
TR0=1;
while(count TR0=0;
set_count=346;//336; //发送编码中的4.5ms低电平(//后为12M晶振下的数值)
irflag=0;
count=0;
TR0=1;
while(count TR0=0;
set_count=43;//35; //发送编码中的0.56ms高电平 (//后为12M晶振下的数值)
irflag=1;
count=0;
TR0=1;
while(count TR0=0;
ir=1; //发射完了关闭红外发射二极管
}
//---------------------------------------------------------------------------
void timer0_init() //定时器初始化
{
EA=1;
TMOD=0x02; //定时0 8位自动重装模式
ET0=1;
TH0=0xe6;//0xf3; //定时13us,38K红外矩形波,晶振24M (//后为12M晶振下的数值)
TL0=0xe6;
}
//---------------------------------------------------------------------------
void main()
{
timer0_init(); //定时0初始化
count=0; //中断计数先清0
irflag=0; //红外发射标志先置0
while(1)
{
keyscan(); //键值扫描
if(keyflag) //若有按键按下
{
led = 0;
delay(10);
ir_send(); //发送红外编码
delay(500);
keyflag=0; //按键标志清零
delay(100);
}
else
{
led = 1;
}
}
}
//---------------------------------------------------------------------------
void timer0() interrupt 1 //定时器0中断
{
count++;
if(irflag==1) ir=~ir; //有发射标志,则发射38khz的矩形波
else ir=1; //否则不发射,即相当于发射编码中的低电平
}