你直接在线仿真, 然后控制P1.0 看看有没有反映, 然后、在线仿真看看红外到底收到什么码,比这里问,我们替你猜,效率高多了。 |
【到STC 8G上按遥控器后,能检测到外部中断】 既如此,就将红外接收端接到外部中断口,中断后给LED的端口改变一下。不就好了。 几句就搞定了,不用这么复杂吧。 |
#include<STC15W408AS.H> #include<intrins.h> //包含_nop_()函数定义的头文件 #define uchar unsigned char #define uint unsigned int //#define CCP_S0 0x10 //P_SW1.4 //#define CCP_S1 0x20 //P_SW1.5 #define LED_Port P1 #define CMD_IDLE 0 //空闲模式 #define CMD_READ 1 //IAP字节读命令 #define CMD_PROGRAM 2 //IAP字节编程命令 #define CMD_ERASE 3 //IAP扇区擦除命令 //#define ENABLE_IAP 0x80 //if SYSCLK<30MHz //#define ENABLE_IAP 0x81 //if SYSCLK<24MHz //#define ENABLE_IAP 0x82 //if SYSCLK<20MHz #define ENABLE_IAP 0x83 //if SYSCLK<12MHz //#define ENABLE_IAP 0x84 //if SYSCLK<6MHz //#define ENABLE_IAP 0x85 //if SYSCLK<3MHz //#define ENABLE_IAP 0x86 //if SYSCLK<2MHz //#define ENABLE_IAP 0x87 //if SYSCLK<1MHz #define IAP_ADDRESS 0x0000 //测试地址 sbit led1 = P1^4; sbit led2 = P1^3; sbit led3 = P1^2; //sbit led4 = P3^3; //sbit led5 = P1^3; //p1.3 //sbit led6 = P3^1; //sbit led7 = P3^0; //sbit led8 = P1^7; //sbit led9 = P5^5; //sbit led10= P5^4; //sbit IRIN=P3^2; //红外接收器数据线 sbit IR_Out = P3^2; uchar num,sum,mode; sbit IR_Flag = P1^1; unsigned char dat[4] = {0,0,0,0}; void led(); void key(); void IapIdle(); uchar IapReadByte(uint addr); void IapProgramByte(uint addr, uchar dat); void IapEraseSector(uint addr); void delay(uint z) { uint x,y; for(x=0;x<50;x++) for(y=z;y>0;y--); } void main() { P1M0=0xFF; P1M1=0x00; P3M0=0x00; P3M1=0x00; P5M0=0xFF; P5M1=0x00; ACC = P_SW1; //ACC &= ~(CCP_S0|CCP_S1); //CCP_S0=0 CCP_S1=0 P_SW1 = ACC; //(P1.2/ECI, P1.1/CCP0, P1.0/CCP1, P3.7/CCP2) CCON = 0; //初始化PCA控制寄存器 //PCA定时器停止 //清除CF标志 //清除模块中断标志 CL = 0; //复位PCA寄存器 CH = 0; CMOD = 0x02; //设置PCA时钟源 //禁止PCA定时器溢出中断 PCA_PWM0 = 0x00; //PCA模块0工作于8位PWM CCAP0H = CCAP0L = 0xFF; //PWM0的占空比为87.5% ((100H-20H)/100H) CCAPM0 = 0x42; //PCA模块0为8位PWM模式 CR = 1; //PCA定时器开始工作 //EA =1; //EX0=1; //IT0=1; //IRIN=1; IR_Out = 1; TMOD = 0x01; // 定时器0,方式1 IT0 = 1; // 外部中断0,下降沿触发 EX0 = 1; // 准许外部中断 EA = 1; // CPU准许中断 led1=led2=led3=0; //sum=IapReadByte(0x0010); //num=IapReadByte(0x0020); mode=IapReadByte(0x0030); while(1) { key(); switch(mode) { case 0x01:led1=led2=led3=0;break; case 0x02:CCAP0H = CCAP0L = 0x00;led();key();break; case 0x03:CCAP0H = CCAP0L = 0x96;led();key();break; case 0x04:CCAP0H = CCAP0L = 0xD2;led();key();break; default :led1=led2=led3=0;break; } } } void Int0() interrupt 0 { unsigned char i,j; EX0 = 0; // 关闭外部中断0 IR_Flag = 0; // 执行中断程序时,LED灯亮 i = 10; // 0.793ms延时,运行10次 while( --i ) { TH0 = 0xfc; // 定时0.793ms,延时0.793ms*10=7.93ms TL0 = 0xe7; TR0 = 1; while( !TF0 ); TF0 = 0; TR0 = 0; // 这7.93ms期间只要IR_Out变高电平,就非合法的红外信号,跳出 if( IR_Out ) { EX0 = 1; // 准许中断 return ; } } // 程序进行到这里,表明是合法的红外信号(利用9ms判断) while( !IR_Out ); // 等待9ms低电平过去 // 程序进行到这里,表明经过9ms低电平 TH0 = 0xf6; TL0 = 0xff; TR0 = 1; while( !TF0 ); TF0 = 0; TR0 = 0; // 延时2.305ms // IR_Out 为低表明是连发码,不予理睬,跳出 if( !IR_Out ) { EX0=1; return; } // 程序进行到这里,表明是引导码,等待4.5ms高电平的过去 while( IR_Out ); for(i=0; i<4; i++) // 开始接收用户码 { for(j=0; j<8; j++) { while( !IR_Out ); // 等待低电平过去 dat[i] >>= 1; // 把上次的数据位右移一位 TH0 = 0xfc; TL0 = 0xe7; TR0 = 1; while( !TF0 ); TR0=0; TF0=0; //延时0.793ms // 若为数据"1",则延时后IR_Out为高电平 if( IR_Out ) { dat[i] |= 0x80; // 所有数据位1放最高位 while( IR_Out );// 等待高电平过去 } } } //LED_Port = dat[2]; num = dat[2]; EX0=1; // 开中断 return; } 给一个给你参考下,最近我弄的,芯片是用STC15W408AS 内部频率110.592M |