51单片机学习篇-- --红外通信(倒计时数字钟)

开篇先说一句废话····
本旺名字叫萨摩耶,,Please 叫我旺财,,,哈哈,招财进宝嘛!

开篇

这篇文章就是把之前的《倒计时数字钟–矩阵按键可调》稍加修改,把本来的矩阵按键调试换成了红外遥控调试。具体项目要求参考超链接文章。

项目分析

《倒计时数字钟–矩阵按键可调》这个项目和本项目的区别就是矩阵按键换成了红外遥控,其他都没变。可以直接在矩阵按键项目上修改。

  • 首先要知道红外遥控每个按键的数据码上篇文章总计已提到,可以在上篇文章的程序上采集起来存放到数组中。
  • u8 irdata[]={0x45,0x46,0x47,0x44,0x40,0x43,0x07,0x15,0x09,0x16,0x19, 0x0d,0x0c,0x18,0x5e,0x08,0x1c,0x5a,0x42,0x52,0x4a};
  • 初始化的时候注意初始化外部中断0和P3^2口即可
  • 矩阵按键需要按键检测,因为红外通信使用外部中断,不需要通信检测,直接红外通信处理
//红外处理
void Irpross(){
	u8 med;
	med=IrData[2];
	if(flag3==1){
		flag3=0;
		switch(IrData[2]){
			case(0x45):Funcpross();break;
			case(0x44):Enterpross();break;
			case(0x40):Downpross();break;
			case(0x43):Uppross();break;
			case(0x16):Numpross(0);break;
			case(0x0c):Numpross(1);break;
			case(0x18):Numpross(2);break;
			case(0x5e):Numpross(3);break;
			case(0x08):Numpross(4);break;
			case(0x1c):Numpross(5);break;
			case(0x5a):Numpross(6);break;
			case(0x42):Numpross(7);break;
			case(0x52):Numpross(8);break;
			case(0x4a):Numpross(9);break;
		}
	}
}

具体case条件对应遥控器按键可自行验证或者修改

完整代码

//main.c
#include "smg.h"

void main(){
	Init();
	while(1){
		Irpross();
		Datapross();
		if(flag==1)
			twinkle(flag1);
		else
			Showsmg();
		
	}
}

//数码管显示函数
void Showsmg(){      
	u8 i;
	for(i=0;i<8;i++)
	{
	   switch(7-i)	  //位选
	   {
		  case 0: LSA=0;LSB=0;LSC=0;break;
		  case 1: LSA=1;LSB=0;LSC=0;break;
		  case 2: LSA=0;LSB=1;LSC=0;break;
		  case 3: LSA=1;LSB=1;LSC=0;break;
		  case 4: LSA=0;LSB=0;LSC=1;break;
		  case 5: LSA=1;LSB=0;LSC=1;break;
		  case 6: LSA=0;LSB=1;LSC=1;break;
		  case 7: LSA=1;LSB=1;LSC=1;break;
	   }
	  P0=Display[i];
	  Delay(100);
	  P0=0x00;
	}
}
//延时函数
void Delay(u16 i)   //11.0592 10us
{
	while(i--);
} 
//初始化函数
void Init(){
	//参数初始化
	hour=0;
	minute=0;
	second=0;
	t0=0;
	flag=0;
	flag1=0;
	flag2=0;
	//定时器0初始化
	TMOD=0x01;
	TH0=(65536-9174)/256;   //10ms
	TL0=(65536-9174)%256;
	EA=1;
	ET0=1;
	TR0=0;
	//外部中断0初始化
	IT0=1;
	EX0=1;
	EA=1;
	
	INIR=1;
}

//红外处理
void Irpross(){
	u8 med;
	med=IrData[2];
	if(flag3==1){
		flag3=0;
		switch(IrData[2]){
			case(0x45):Funcpross();break;
			case(0x44):Enterpross();break;
			case(0x40):Downpross();break;
			case(0x43):Uppross();break;
			case(0x16):Numpross(0);break;
			case(0x0c):Numpross(1);break;
			case(0x18):Numpross(2);break;
			case(0x5e):Numpross(3);break;
			case(0x08):Numpross(4);break;
			case(0x1c):Numpross(5);break;
			case(0x5a):Numpross(6);break;
			case(0x42):Numpross(7);break;
			case(0x52):Numpross(8);break;
			case(0x4a):Numpross(9);break;
		}
	}
}
//数据处理
void Datapross(){
	if(flag2==1){
		flag2=0;
		second--;
		if(second>59){
			if(minute==0){
				if(hour==0){
					second=0;
					minute=0;
					hour=0;
					TR0=0;
					return;
				}
				else{
					hour--;
					minute=59;
					second=59;
				}
			}
			else{
				minute--;
				second=59;
			}	
		}	
	}
	Display[0]=smgduan[hour/10];
	Display[1]=smgduan[hour%10];
	Display[2]=0x40;
	Display[3]=smgduan[minute/10];
	Display[4]=smgduan[minute%10];
	Display[5]=0x40;
	Display[6]=smgduan[second/10];
	Display[7]=smgduan[second%10];
}
//按键数字处理
void Numpross(u8 dat){
	u8 tp;
	if(flag==1){
		switch(flag1){
			case 0:tp=hour%10;hour=tp+dat*10;break;
			case 1:tp=hour/10;hour=tp*10+dat;break;
			case 3:tp=minute%10;minute=tp+dat*10;break;
			case 4:tp=minute/10;minute=tp*10+dat;break;
			case 6:tp=second%10;second=tp+dat*10;break;
			case 7:tp=second/10;second=tp*10+dat;break;
		}
	}
}
//Up功能处理
void Uppross(){
	if(flag==1){
		flag1++;
		if(flag1>7){
			flag1=0;
		}
		if((flag1==5)||(flag1==2)){
			flag1++;
		}
	}
}
//Down功能处理
void Downpross(){
	if(flag==1){
		flag1--;
		if(flag1<0)
			flag1=7;
		if((flag1==5)||(flag1==2)){
			flag1--;
		}
	}
}
//Func功能处理
void Funcpross(){
	TR0=0;	//停止计时
	flag=1; //允许设置时间
}
//Enter功能处理
void Enterpross(){
	flag=0;		//清零,不允许设置时间
	flag1=0;
	if(hour>23)
		hour=23;
	if(minute>59)
		minute=59;
	if(second>59)
		second=59;
	TR0=1;		//开始计时
}
//Back功能处理
void Backpross(){
//暂无功能
}
//某一位闪烁
void twinkle(unsigned char t)				
{	
	unsigned char i;
	num%=50;
	for(i=0;i<8;i++)
	{
		switch(7-i)	  //位选
	   {
		  case 0: LSA=0;LSB=0;LSC=0;break;
		  case 1: LSA=1;LSB=0;LSC=0;break;
		  case 2: LSA=0;LSB=1;LSC=0;break;
		  case 3: LSA=1;LSB=1;LSC=0;break;
		  case 4: LSA=0;LSB=0;LSC=1;break;
		  case 5: LSA=1;LSB=0;LSC=1;break;
		  case 6: LSA=0;LSB=1;LSC=1;break;
		  case 7: LSA=1;LSB=1;LSC=1;break;
	   }
		if((i==t)&&(num<25)){
			P0=0x00;
			Delay(100);
			P0=0x00;
//			continue;
		}
		else
		{
			P0=Display[i];
			Delay(100);
			P0=0x00;
			
		}
	}
	num++;
}
void ReadIr() interrupt 0{
	u8 i,j;
	u16 err;
	time=0;
	Delay(700);
	if(INIR==0){
		err=1000;
		while((INIR==0)&&(err>0)){
			Delay(1);
			err--;
		}
		if(INIR==1){
			err=500;
			while((INIR==1)&&(err>0)){
				Delay(1);
				err--;
			}
			for(i=0;i<4;i++){
				for(j=0;j<8;j++){
					err=60;
					while((INIR==0)&&(err>0)){
						Delay(1);
						err--;
					}
					err=500;
					while((INIR==1)&&(err>0)){
						Delay(10);
						time++;
						err--;
						if(time>30){
							return;
						}
					}
					IrData[i]>>=1;
					if(time>=8){
						IrData[i]|=0x80;
					}
					time=0;
				}
			}
		}
		if(IrData[2]!=~IrData[3]){
			return;
		}
	}
	flag3=1;	//有数据传送
}
void Timer0() interrupt 1{
	TH0=(65536-9174)/256;   //重置
	TL0=(65536-9174)%256;
	t0++;
	if(t0==100){
		t0=0;
		flag2=1;
	}
}

//smg.h
#include "reg52.h"
#include "intrins.h"

typedef unsigned int u16;
typedef unsigned char u8;
#define GPIO_KEY P1

u8 smgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//u8 irdata[]={0x45,0x46,0x47,0x44,0x40,0x43,0x07,0x15,0x09,0x16,0x19,
//			 0x0d,0x0c,0x18,0x5e,0x08,0x1c,0x5a,0x42,0x52,0x4a};
u8 t0,KeyVal,Display[8],flag,flag1,flag2,flag3;
u16 hour,minute,second;	
u8 IrData[6],time,num=0;			 
//38译码器					 
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit INIR=P3^2;
			 
//数码管显示函数
void Showsmg();
//延时函数
void Delay(u16 i);
//初始化函数
void Init();
//红外处理
void Irpross();
//数据处理
void Datapross();
//按键数字处理
void Numpross(u8 dat);
//Up功能处理
void Uppross();
//Down功能处理
void Downpross();
//Func功能处理
void Funcpross();
//Enter功能处理
void Enterpross();
//Back功能处理
void Backpross();
//某一位闪烁
void twinkle(unsigned char t);
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值