一路红外学习开关,感觉路数不够 自己寻思加一路。但是自己搞好程序下载进去之后第二路无法遥控。开关按键有效用作指示的led 会动作。但是长按学习之后就不起效了。感觉应该是写入eeprom出问题了。单片机C语言水平不行,之前学过一点但是不熟练。最近又打算研究研究 。。各位师博帮忙看一下那里出问提 修改一下谢谢
#include<stc15f104e.h>
#include<intrins.h>
#include"IR.h"
#include"EEPROM.h"
#define uint unsigned int
#define uchar unsigned char
sbit led=P3^0; //指示灯
sbit turn=P3^2; //开关控制
sbit key=P3^4; //按键
sbit turn1=P3^1; //开关控制1
sbit key1=P3^5; //按键1
uchar keyon; //按键按下标签
uchar cou; //掉电计数器
/***************************************
//30ms延时,按键处理用
***************************************/
void Delay() //@12.000MHz 30毫秒
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 2;
j = 95;
k = 43;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
/***************************************
//500ms延时,指示灯用
***************************************/
void Delay500ms() //@12.000MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 23;
j = 205;
k = 120;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
/***************************************
//500ms延时,掉电计时用
***************************************/
void Timer2Init(void) // 定时器2 50ms
{
T2L = 0xB0; //装初值
T2H = 0x3C;
AUXR |= 0x10; //开始计时
IE2 |=0x04; //允许中断
}
/***************************************
//定时器2中断处理
***************************************/
void timer2() interrupt 12{
cou++; //掉电计时
if(cou>100){
cou=0;
PCON=0x02; //进入掉电模式
}
}
/*****************************************
//开关状态切换
*****************************************/
void SW(){
led=1;
turn=~turn; //开关状态切换
Delay500ms();
led=0;
cou=0; //重置掉电计时
}
/*****************************************
//开关状态切换
*****************************************/
void SW1(){
led=1;
turn1=~turn1; //开关1状态切换
Delay500ms();
led=0;
cou=0; //重置掉电计时
}
/***************************************
//红外学习 对keyon进行判断如果为1则证明按键被按下对扇区0进行操作,如果不为1则对扇区1进行操作
***************************************/
void IR_get(){
uchar i;
uchar i1;
bit flag; //学习标志位
cou=0; //重置掉电计时
led=1;
while(!irok){//等待红外解码完成
i++;
flag=0;
if(i==255) break; //等待超时,退出学习
Delay();
flag=1;
}
if(flag){
if(keyon==1)
{
SectorErase(0); //擦除扇区
for(i=0;i<4;i++){ //写入红外编码信息
byte_write(i,IRcode[i]);
}
}
else
SectorErase(0x0200); //擦出扇区1
for(i=0;i<4;i++){
i1=i+0x0200; //将写入地址加上扇区1的起始地址0x0200
byte_write(i1,IRcode[i]);
}
}
led=0;
irok=0;
}
/**************************************
//红外比对
***************************************/
void Compare(){
uchar i=1;
uchar i1; //避开第一个信号,只比对用户反码、按键码、按键反码
while(IRcode[i]==byte_read(i)){ //依次比较
if(i==3){
SW(); //开关状态切换
}
i++;
}
i=1; //比对第1扇区内的数据是否相符,如果相符调用SW1()
while(IRcode[i]==byte_read(i1)){
if(i==3){
SW1();
}
i++;
i1=i+0x0200;
}
}
/**************************************
//按键处理
****************************************/
void key_scan(){
uchar i=0;
uchar i1=0;
if(key==0){
EA=0; //防止中断发生
while(key==0){
i++;
Delay();
if(i>50) break; //超过50次为长按
}
if(i>50){ //长按进入红外学习
EA=1; //重开中断
keyon=1; //按键按下 标志(按键1)
IR_get();
}
if(i<50){ //短按切换开关状态
EA=1; //重开中断
SW();
}
}
//判断按键1是否被按下,是长按进入学习短按切换开关量
if(key1==0){
EA=0; //防止中断发生
while(key1==0){
i1++;
Delay();
if(i1>50) break; //超过50次为长按
}
if(i1>50){ //长按进入红外学习
EA=1; //重开中断
IR_get();
}
if(i1<50){ //短按切换开关状态
EA=1; //重开中断
SW1();
}
}
}
/********************************
//主函数
********************************/
void main(){
Timer2Init(); //定时器2初始化
IRinit(); //红外初始化
turn=1;
led=0;
while(1){
key_scan(); //按键扫描
if(irok){ //红外查询
Compare();
irok=0;
}
}
}
附件列表