前期我發帖稱也談51單片機紅外通信(附四種方案),現對第一方案一處錯誤進行修正。前期貼鏈接附在下面:
也談51單片機紅外通信(附有四種紅外解碼源碼) - 單片機DIY制作 (51hei.com)
- /*-----------------------------------------------
- 【實驗平臺】: QX-MCS51 單片機開發板
- * 【外部晶振】: 11.0592Mhz
- * 【主控芯片】: STC89C52
- * 【編譯環境】: Keil μVisio4
- * 【編 程】:wzqwxx 水上人家
- 名稱:遙控器紅外解碼數碼管顯示
- 內容:按配套遙控器會在數碼管上對應顯示鍵碼值,實測通過
- NEC 標準下的編碼表示
- 其中:引導碼高電平約9000us 左右,低電平約4500us 左右;
- 接收端:引導碼低電平約9000us 左右,高電平約4500us 左右;
- 用戶碼16 位,數據碼16 位,共32位;
- 發送端: 數據0 是用“高電平約560us +低電平約560us”表示。
- 數據1 可用“高電平約560us+低電平約1680us”表示
- 接收端反轉:數據0 是用“低電平約560us +高電平約560us”表示。
- 數據1 可用“低電平約560us+高電平約1680us”表示
- ------------------------------------------------*/
- #include<reg52.h> //包含頭文件,頭文件包含特殊功能寄存器的定義
- #include <stdio.h>
- #include "SMG.H"
- sbit IR=P3^2; //紅外接口
- sbit beep = P2^3;//蜂鳴器接口
- unsigned char irtime; //紅外用全局變量 計數延時,識別比特位電平高低
- unsigned char IRcord[4]= {0x12,0x34,0x56,0x78};//存儲鍵碼
- void tim0_isr (void) interrupt 1 //STC89C52 11.0592M
- {
- irtime++; //用于計數2個下降沿之間的時間 每個溢出中斷時長256*1.085069us=277.77us
- }
- void EX0_ISR (void) interrupt 0 //外部中斷0服務函數
- {
- static unsigned char i,blag; //接收紅外信號處理
- if(blag == 1)
- {
- if( irtime <3 || irtime >51)goto end; //兩個下降沿延時過短(少于833us)或過長不解碼 濾除干擾波
- if(irtime > 28 && irtime < 55)//跳過引導碼 頭碼,9ms+4.5ms
- { i=0; goto end;}
- IRcord[i/8] >>= 1; //i/8每處理8位換下一個元素,總的處理4個字節共32位的數據
- if(irtime > 5 ) IRcord[i/8] |= 0x80; //位0電平時長計數上限4,位1高電平計數上限8
- i++; //這里取6為0/1 的識別分界
- if(i > 31){ i = 0; blag = 0; beep = 0; delay(30); beep = 1; } //beep 鳴叫一聲 解碼成功
- }
- else
- {blag = 1;}
- end:irtime=0;
- }
- //void UART_init()
- //{
- // TMOD |= 0x20; //T1工作模式2 8位自動重裝
- // TH1 = 0xfd;
- // TL1 = 0xfd; //比特率9600 時鐘頻率11.0592MHZ
- // TR1 = 1; //啟動T1定時器
- // SM0 = 0;
- // SM1 = 1; //串口工作方式1 10位異步
- // REN = 1; //串口允許接收
- // TI = 1;
- //}
- void TIM0init(void)//定時器0初始化
- {
- TMOD|=0x02;//定時器0工作方式2,TH0是重裝值,TL0是初值
- TH0=0x00; //重載值
- TL0=0x00; //初始化值
- ET0=1; //開中斷
- TR0=1;
- }
- void EX0init(void)
- {
- IT0 = 1; //指定外部中斷0下降沿觸發,INT0 (P3.2)
- EX0 = 1; //使能外部中斷
- EA = 1; //開總中斷
- }
- void main(void)
- {
- // UART_init();
- EX0init(); //初始化外部中斷
- TIM0init();//初始化定時器
- while(1)//主循環
- {
- SMGXSSZ(IRcord);
- // printf(" %bx %bx %bx %bx \n ",IRcord[0],IRcord[1],IRcord[2],IRcord[3]) ;
- }
- }
-
-
復制代碼
- #include "SMG.H"
- uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
- 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
- //0-F的碼表
- uchar code wen_code[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //數碼管位數選擇碼表
- void delay(uint i)//延時毫秒程序
- {
- uint m,n;
- for(m=i;m>0;m--)
- for(n=114;n>0;n--);
- }
-
- //一位數碼管顯示,參數1:位,參數2:數
- void smgxs(uchar we,uchar shu)
- {
-
- P0=table[shu];
- du=1;
- du=0;
- P0=wen_code[we];
- we=1;
- we=0;
- delay(2);
- }
- //void smgxs8w(unsigned long shu) //數碼管顯示8位大數
- //{
- // unsigned long shu_temp=shu;
- // uchar i=8;
- // if(shu>0)
- // {
- // while(shu_temp)
- // {
- // i--;
- // smgxs(i,shu_temp%10);
- // shu_temp=shu_temp/10;
- // }
- // } else {smgxs(7,0);}//歸零數碼管顯一個零
- //}
- void SMGXSSZ(uchar shuz[]) //數碼管顯示數組
- {
- uchar i;
- for(i = 0;i < 4;i++)
- {
- smgxs(i*2+1,shuz[i]&0x0f); //顯示十六進制數
- smgxs(i*2,shuz[i]>>4);
- }
- }
復制代碼
|