开篇先说一句废话····
本旺名字叫萨摩耶,,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);