|
發布時間: 2021-10-14 14:36
正文摘要:購買了STC 8G1K08-38I-SOP16的最小系統板和紅外接收模塊。想通過紅外遙控器,控制單片機P1.0口的輸出,驅動led,這個紅外接收程序在51單片機上能正常使用,到STC 8G上按遙控器后,能檢測到外部中斷,P1.0口輸出沒反 ... |
| 你直接在線仿真, 然后控制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 |