找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 4877|回復(fù): 4
打印 上一主題 下一主題
收起左側(cè)

紅外使用單片機(jī)外部中斷+定時(shí)器解碼

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:61973 發(fā)表于 2018-8-5 21:36 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
包含了紅外解碼,自動(dòng)根據(jù)波特率設(shè)置定時(shí)器溢出率以及使用定時(shí)器延時(shí)
串口部分:
void UART1_Init(u32 Boud)
{
        u16 Temp = (65536 - FOSC/Boud/4);
        SCON = 0x50;
    T2L = Temp;        
    T2H = Temp >> 8;
    AUXR |= 0x15;                                //啟動(dòng)定時(shí)器
    ES = 1;                                     //使能串口中斷
}
char putchar(u8 c)
{
        SBUF = c;
        while(!TI);
        TI = 0;
        return c;
}
void UART1_ISR() interrupt 4 using 1
{
    if(RI)
    {
        RI = 0;                                 //清中斷標(biāo)志
    }
//        if(TI)
//        {
//                TI = 0;                                 //清中斷標(biāo)志
//        }
}

//定時(shí)器延時(shí)部分
#include "delay.h"
#define TICK_US                (FOSC/1000000/12)
volatile u16 told = 0;                                //計(jì)數(shù)器舊值               
volatile u16 tnow = 0;                                //計(jì)數(shù)器新值               
volatile u16 tick = 0;                                //計(jì)數(shù)值               
volatile u16 delay_tick = 0;                //延時(shí)計(jì)數(shù)值
void delay_init(void)
{
        T4L = 0;                                
    T4H = 0;
        T4T3M &= 0x0F;
        T4T3M |= B1000_0000;         //啟動(dòng)定時(shí)器 12T
        told = 0;                        
        tnow = 0;
        tick = 0;
        delay_tick = 0;
}
void delay(u16 us)
{
        told = T4H << 8 | T4L;                        
        tnow = 0;tick = 0;
        delay_tick = us * TICK_US;
        while(1)
        {
                tnow = T4H << 8 | T4L;
                if(tnow != told)
                {
                        if(tnow > told)
                        {
                                tick += tnow - told;
                        }
                        else                                //定時(shí)器溢出
                        {
                                tick += 65535 + tnow - told;
                        }
                        told = tnow;
                        if(tick >= delay_tick)
                                break;
                }
        }
}

//紅外解碼
#include "INT.h"
#include "USART.h"
u8 IR_Cnt = 0;
#define T51                                (FOSC/1000000/12)
#define REMOTE_ID                 0   
//遙控器接收狀態(tài)
//[7]:收到了引導(dǎo)碼標(biāo)志
//[6]:得到了一個(gè)按鍵的所有信息
//[5]:保留        
//[4]:標(biāo)記上升沿是否已經(jīng)被捕獲                                                                  
//[3:0]:溢出計(jì)時(shí)器
u8 IR_sta = 0;
u32 IR_Rec = 0;
sbit INT0 = P3^2;
void IR_Init(void)
{
        IT0 = 0;            //使能INT0上升沿和下降沿中斷
    EX0 = 1;             //使能INT0中斷
        AUXR &= 0x7F;                //定時(shí)器時(shí)鐘12T模式
        TMOD &= 0xF0;                //設(shè)置定時(shí)器模式
        TMOD |= 0x01;                //設(shè)置定時(shí)器模式
        TF0 = 0;                //清除TF0標(biāo)志
        TL0 = 0;                //設(shè)置定時(shí)初值
        TH0 = 0;                //設(shè)置定時(shí)初值
        TR0 = 0;                //定時(shí)器0開始計(jì)時(shí)
        ET0 = 1;
}
//處理紅外鍵盤
//返回值:
//         0,沒有任何按鍵按下
//其他,按下的按鍵鍵值.
u8 IR_Scan(void)
{      
        u8 Key = 0;      
        if(IR_sta & (1<<6))//得到一個(gè)按鍵的所有信息了
        {  
                u8 TEMP[2];
            TEMP[0] = IR_Rec>>24;                        //得到地址碼
            TEMP[1] = (IR_Rec>>16)&0xff;        //得到地址反碼
             if((TEMP[0] == (u8)~TEMP[1]) && TEMP[0] == REMOTE_ID)//檢驗(yàn)遙控識(shí)別碼(ID)及地址
            {
                TEMP[0] = IR_Rec>>8;
                TEMP[1] = IR_Rec;         
                if(TEMP[0] == (u8)~TEMP[1])
                                Key = TEMP[0];//鍵值正確         
                }
                if(Key == 0||(IR_sta&0X80) == 0)//按鍵數(shù)據(jù)錯(cuò)誤/遙控已經(jīng)沒有按下了
                {
                        IR_sta&=~(1<<6);//清除接收到有效按鍵標(biāo)識(shí)
                        IR_Cnt = 0;                //清除按鍵次數(shù)計(jì)數(shù)器
                }
        }  
    return Key;
}

void INT0_ISR(void) interrupt 0 using 1
{
        if(INT0)//上升沿捕獲
        {
                TL0 = 0;                //設(shè)置定時(shí)初值
                TH0 = 0;                //設(shè)置定時(shí)初值
                TR0 = 1;                //定時(shí)器0開始計(jì)時(shí)
                IR_sta |= 0X10;                                        //標(biāo)記上升沿已經(jīng)被捕獲
        }
        else //下降沿捕獲
        {
                u16 Count_Time = 0;
                Count_Time = TH0 << 8|TL0;                                
                TL0 = 0;                //設(shè)置定時(shí)初值
                TH0 = 0;                //設(shè)置定時(shí)初值
                if(IR_sta & 0X10)                                        //完成一次高電平捕獲
                {
                        if(IR_sta & 0X80)//接收到了引導(dǎo)碼
                        {
                                if(Count_Time > (300 * T51) && Count_Time < (800 * T51))                        //560為標(biāo)準(zhǔn)值,560us
                                {
                                        IR_Rec <<= 1;        //左移一位.
                                        IR_Rec |= 0;        //接收到0        
                                }
                                else if(Count_Time > (1400 * T51) && Count_Time < (1800 * T51))        //1680為標(biāo)準(zhǔn)值,1680us
                                {
                                        IR_Rec <<= 1;        //左移一位.
                                        IR_Rec |= 1;        //接收到1
                                }
                                else if(Count_Time > (2200 * T51) && Count_Time < (2600 * T51))        //得到按鍵鍵值增加的信息 2500為標(biāo)準(zhǔn)值2.5ms
                                {
                                        IR_Cnt++;                 //按鍵次數(shù)增加1次
                                        IR_sta&=0XF0;        //清空計(jì)時(shí)器        
                                }
                        }
                        else if(Count_Time > (4200 * T51) && Count_Time < (4700 * T51))                //4500為標(biāo)準(zhǔn)值4.5ms
                        {
                                IR_sta|=1<<7;        //標(biāo)記成功接收到了引導(dǎo)碼
                                IR_Cnt=0;                //清除按鍵次數(shù)計(jì)數(shù)器
                        }                                                
                }
                IR_sta &=~(1<<4);
        }               
}
void TIME0_ISR(void) interrupt 1 using 1
{
    TL0 = 0;                //設(shè)置定時(shí)初值
        TH0 = 0;                //設(shè)置定時(shí)初值
        if(IR_sta&0x80)//上次有數(shù)據(jù)被接收到了
        {        
                IR_sta &= ~0X10;                                                //取消上升沿已經(jīng)被捕獲標(biāo)記
                if((IR_sta&0X0F) == 0X00)
                        IR_sta|=1<<6;//標(biāo)記已經(jīng)完成一次按鍵的鍵值信息采集        
                if((IR_sta&0X0F) < 14)
                        IR_sta++;
                else
                {
                        TR0 = 0;                //定時(shí)器0開始計(jì)時(shí)
                        IR_sta&=~(1<<7);//清空引導(dǎo)標(biāo)識(shí)
                        IR_sta&=0XF0;        //清空計(jì)數(shù)器        
                }                        
        }        
}


STC8.rar

288.26 KB, 下載次數(shù): 28, 下載積分: 黑幣 -5

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:290576 發(fā)表于 2018-8-22 00:22 | 只看該作者
標(biāo)記下  感謝樓主
回復(fù)

使用道具 舉報(bào)

板凳
ID:337813 發(fā)表于 2018-10-21 23:22 | 只看該作者
感謝您的無私分享,謝謝你。!
回復(fù)

使用道具 舉報(bào)

地板
ID:298008 發(fā)表于 2018-10-22 15:39 | 只看該作者
謝謝樓主分享
回復(fù)

使用道具 舉報(bào)

5#
ID:615610 發(fā)表于 2020-6-24 20:10 | 只看該作者
謝謝樓主分享
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表