已經有結果了,想追求完美最后還是初完美打敗。已經做出了跟原始波形一樣的了,但就是不起做用,不明原因,反而是那填充了載波的長條圖波形能正常遙控。
把程序里 remoteout=0; //關紅外發射 變成 remoteout=1; //開紅外發射 波形就從正波變成負波了。
- i=remotedata[n];
- ET1=1;
- TR1=0; //開定時
- 。。。。。。。。。。。
- ET1=0;
- TR1=1;//不發送調制脈沖
復制代碼
然后把ET1和TR1改成上面的就可以出線條圖而不是填充載波的長條圖
整個代碼如下,基本全注釋了,能搞清楚這代碼為什么不實用的大神請M我
- /********學習型遙控器程序*********/
- /*
- 該程序只對紅外脈沖波形復制并不解碼是真正的萬能學習型,程序是根據論壇公開程序資料修改完成的,
- 對多種遙控都能學習包括:電視遙控,機頂盒遙控,空調遙控等....學習到的波形脈沖總寬度幾乎一致.
-
- 源碼調試:風中有你 2015.11.29
-
-
- 2021年8月25日
- 改為低電平亮燈,芯片用STC8F1K08S2,波形跟原始波一樣都是線條形,波形也是負波,但就是無效果
- */
- #include"stc8.h"
- #include<intrins.h> //延時函數
- #define uchar unsigned char
- #define uint unsigned int
- sbit studylamp=P5^4; //學習指示燈
- sbit lamp=P1^1; //發射指示燈
- sbit studykey=P3^4; //學習鍵
- sbit txkey=P3^5; //發射鍵
- sbit remotein=P3^2; //遙控信號輸入口 高阻
- sbit remoteout=P5^5; //遙控信號輸出口 強推
- uint i,j,m=5000,n,k,s;
- uint remotedata[207]; //存脈沖寬度數據用
- uint remdata; //脈沖計數
- bit tag;//學習狀態標志
- /****1ms*t延時程序****/
- void delay1ms(uint t)
- {
- for(i=0;i<t;i++)
- for(j=0;j<120;j++)
- ;
- }
- /****2us*t秒延時程序****/
- void Delay2us(uchar y) //@12.000MHz
- {
- unsigned char i;
- i = y;//數越大長度越短
- while (--i);
- }
- void Timer1Init(void) //38Khz@12.000MHz
- {
- AUXR &= 0xBF; //定時器時鐘12T模式 1011 1111
- TMOD |= 0x20; //設置定時器模式 10 0000
- TH1=0xf3;//38KHz初值
- TL1=0xf3;
- }
- void clr_ram()
- {
- for(i=0;i<207;i++)
- {
- remotedata[i]=0x00;
- } //清內存
- }
- /////////////////////
- /****初始化程序****/
- void clearmen(void)
- {
- // I/O 口特殊功能寄存器,這里不定義還好,定義后就不可用了,不明白
- //P3M0=0x04; P3M1=0x00;//P3.2 紅外輸入 高阻
- //P5M0=0x00; P5M1=0x20;//P5.5 紅外輸出 推挽輸出
-
- /*
- P0M0[1:0] P0M1[1:0]
- 0 0 準雙向口(傳統8051 I/O口模式)灌電流可達20mA
- 0 1 推挽輸出(強上拉輸出,可達20mA,要加限流電阻)
- 1 0 僅為輸入(高阻)
- 1 1 開漏(Open Drain),內部上拉電阻斷開,要外加
- */
-
-
-
- studylamp=1;//關學習指示燈
- lamp=1; //關發射指示燈
- remoteout=0; //關遙控輸出
- remotein=1; // 遙控輸入置高電平
- IE=0x00;//IE是中端允許寄存器,這里面包括了定時器和外部中斷還有EA等
- IP=0x01;//IP是中斷優先級控制寄存器
- Timer1Init();
- EA=1; //開總中斷
- clr_ram();
- }
- /*
- (IP.7:保留)
- (IP.6:保留)
- PT2(IP.5):若=1,定時器2中斷設為高優先級(只適用于8052及其增強型)
- PS(IP.4):若=1,串行中斷設為高優先級
- PT1(IP.3):若=1,定時器1中斷設為高優先級
- PX1(IP.2):若=1,外部中斷1設為高優先級
- PT0(IP.1):若=1,定時器0中斷設為高優先級
- PX0(IP.0):若=1,外部中斷0設為高優先級
- */
- /*****發送鍵功能函數****/
- void keywork(void)
- {
- if (txkey==0) //如發射按鍵按下
- {
- delay1ms(10);//延時10毫秒防抖
- while(txkey==0);//等待發射鍵釋放,釋放后txkey==1,釋放后才繼續執行下去就是為了防止按鍵一按下就無數次循環了
- n=0;//計數用
- lamp=0;//學習燈亮
- while(1) //開始發射調制波形
- {
- i=remotedata[n]; //把讀到的數組數據第0個賦給i
- ET1=1;//開啟T1中斷 關閉也無波
- TR1=0; //關閉定時器T1不發送調制脈沖
- while(i--)
- {
- Delay2us(2);//延時2個2毫秒
- _nop_();//單片機空跑一周期
- _nop_();//單片機空跑一周期
- }
- /*
- 方式1:上面的ET1=1 TR1=1 下面的ET1=0 TR1=0 出有色波,能遙控
-
- 0001不出波
- 0010不出波
- 0011全黃,全輸出載波,沒得停了
- 0100不出波
- 0101不出波
- 0110一直高電平
- 0111全黃,全輸出載波,沒得停了
- 1000不出波
- 1001出跟原始波一樣的線條波形,方向反,不能遙控
- 1010不出波
- 1011全黃
- 1100出有色波,能遙控
- 1101出有色波,能遙控
- 1110也有色波但跟方式1有點不一樣,在遙控碼中部有一上電平線,能遙控
- 1111全黃
- */
-
- ET1=0;//關閉T1中斷
- TR1=1;//開啟定時器T1發送調制脈沖 TR1=0且上面那個TR1=1時波形有填充色且能遙控,燈充滿電遙控較遠,
- //TR1=1且上面的TR1=0時波形跟原始波一樣無填充色,但不能遙控
- remoteout=1; //關紅外發射
- n++;//下一組脈沖寬度地址
- i=remotedata[n]; //把讀到的數組數據第n個賦給i
- while(i--) //根據i值發送計時
- {
- Delay2us(2);//延時2個2毫秒
- _nop_();//單片機空跑一周期
- _nop_();//單片機空跑一周期
- }
- //等待該位時間結束
- n++; //下一組脈沖寬度地址
- if((remotedata[n]==0)||(n>206))//如果數值為0了或超過了206個//該位地址數據為0或地址計數大于設定值就結束
- {
- delay1ms(10);//延時10毫秒
- break;//結束退出
- }
-
- }
- }
- lamp=1; //滅燈
- }
-
- /****40KHz載波發生函數*****/
- void time_intt(void)interrupt 3 //定時器1
- {
- remoteout=~remoteout;
- }
- /*
- 外部中斷0 interrupt 0
- 定時器0 interrupt 1
- 外部中斷1 interrupt 2
- 定時器1 interrupt 3
- 串口中斷 interrupt 4
- 定時器2 interrupt 5
- */
- //*********學習紅外函數*************
- void studywork()
- {
- while(studykey==0)//按鍵按下放
- {
- while(studykey==1);//等待鍵釋放
- studylamp=0; //學習燈亮
- lamp=1;//發射燈滅
- tag=1; //學習標致置1
- n=0;
- remdata=0x00;//脈寬計數器清零
- while(remotein==1);//等待遙控碼輸入
- while(tag)//當tag是1在學習狀態就一直循環
- {
- while(remotein==0)//當低電平時有遙控碼輸入
- {
- Delay2us(4);//延時4個2微秒
- remdata++; //記錄低電平脈寬時間
- if(remdata>m) //計數大于設定值退出 m設為5000,這個值不懂怎么來的,設為255只有一條豎線
- {
- remotedata[n]=0x00; //肪沖寬度置0
- tag=0;//學習標志置0,結束學習
- goto end;//跳到結束
- }
- }
- remotedata[n]=remdata;//如果低電平肪寬時間remdata不大于5000就把值賦給脈沖寬度數組remotedata[n],就是說這個值有效吧記錄下來
- remdata=0x00;//脈寬計數器清零
- n++;//電平脈寬數據個數加1
- if(n>206) //緩存滿退出,remotedata[n]設為最大207
- {
- remotedata[n]=0x00;//一組數是206,大于就清0
- tag=0;//學習標志置0,結束學習
- goto end;//跳到結束,兩燈都滅了
- }
- while(remotein==1)//當高電平時無遙控碼輸入
- {
- Delay2us(4);//延時4個2微秒
- remdata++; //高電平計數
- if(remdata>m) //計數大于設定值退出 m設為5000,這個值不懂怎么來的,設為255只有一條豎線
- {
- remotedata[n]=0x00; //肪沖寬度置0
- tag=0;//學習標志置0,結束學習
- goto end;//跳到結束,兩燈都滅了
- }
- }
- remotedata[n]=remdata; //存高電平脈寬數據
- remdata=0x00;//脈寬計數器清零
- n++;//電平脈寬數據個數加1
- }
- }
- end:
- {//學習結束
- lamp=1;//發射燈滅
- studylamp=1; //學習燈滅
- }
- }
- /******主函數****/
- void main()
- {
- clearmen();
- remoteout=0; //關紅外發射
- studylamp=0; //學習燈滅
- tag=0;
- studykey=1;
- while(1)
- {
- keywork(); // 發射
- studywork(); //學習
- }
- }
復制代碼
|