久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4868|回復: 4
打印 上一主題 下一主題
收起左側

紅外使用單片機外部中斷+定時器解碼

[復制鏈接]
跳轉到指定樓層
樓主
ID:61973 發表于 2018-8-5 21:36 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
包含了紅外解碼,自動根據波特率設置定時器溢出率以及使用定時器延時
串口部分:
void UART1_Init(u32 Boud)
{
        u16 Temp = (65536 - FOSC/Boud/4);
        SCON = 0x50;
    T2L = Temp;        
    T2H = Temp >> 8;
    AUXR |= 0x15;                                //啟動定時器
    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;                                 //清中斷標志
    }
//        if(TI)
//        {
//                TI = 0;                                 //清中斷標志
//        }
}

//定時器延時部分
#include "delay.h"
#define TICK_US                (FOSC/1000000/12)
volatile u16 told = 0;                                //計數器舊值               
volatile u16 tnow = 0;                                //計數器新值               
volatile u16 tick = 0;                                //計數值               
volatile u16 delay_tick = 0;                //延時計數值
void delay_init(void)
{
        T4L = 0;                                
    T4H = 0;
        T4T3M &= 0x0F;
        T4T3M |= B1000_0000;         //啟動定時器 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                                //定時器溢出
                        {
                                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   
//遙控器接收狀態
//[7]:收到了引導碼標志
//[6]:得到了一個按鍵的所有信息
//[5]:保留        
//[4]:標記上升沿是否已經被捕獲                                                                  
//[3:0]:溢出計時器
u8 IR_sta = 0;
u32 IR_Rec = 0;
sbit INT0 = P3^2;
void IR_Init(void)
{
        IT0 = 0;            //使能INT0上升沿和下降沿中斷
    EX0 = 1;             //使能INT0中斷
        AUXR &= 0x7F;                //定時器時鐘12T模式
        TMOD &= 0xF0;                //設置定時器模式
        TMOD |= 0x01;                //設置定時器模式
        TF0 = 0;                //清除TF0標志
        TL0 = 0;                //設置定時初值
        TH0 = 0;                //設置定時初值
        TR0 = 0;                //定時器0開始計時
        ET0 = 1;
}
//處理紅外鍵盤
//返回值:
//         0,沒有任何按鍵按下
//其他,按下的按鍵鍵值.
u8 IR_Scan(void)
{      
        u8 Key = 0;      
        if(IR_sta & (1<<6))//得到一個按鍵的所有信息了
        {  
                u8 TEMP[2];
            TEMP[0] = IR_Rec>>24;                        //得到地址碼
            TEMP[1] = (IR_Rec>>16)&0xff;        //得到地址反碼
             if((TEMP[0] == (u8)~TEMP[1]) && TEMP[0] == REMOTE_ID)//檢驗遙控識別碼(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)//按鍵數據錯誤/遙控已經沒有按下了
                {
                        IR_sta&=~(1<<6);//清除接收到有效按鍵標識
                        IR_Cnt = 0;                //清除按鍵次數計數器
                }
        }  
    return Key;
}

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


STC8.rar

288.26 KB, 下載次數: 28, 下載積分: 黑幣 -5

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

沙發
ID:290576 發表于 2018-8-22 00:22 | 只看該作者
標記下  感謝樓主
回復

使用道具 舉報

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

使用道具 舉報

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

使用道具 舉報

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

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 成人av播放 | 香蕉视频91| 久久久久久国产免费视网址 | 国产成人精品久久 | 天天躁日日躁狠狠的躁天龙影院 | 亚洲国产视频一区 | 亚洲人成人一区二区在线观看 | 欧美一区二区三区在线观看 | 成人久草 | 国产在线一区观看 | 欧美激情一区二区 | 亚洲a视频 | 欧美日韩中文国产一区发布 | 国产精品免费一区二区三区四区 | 在线观看中文字幕视频 | a成人| 国产成人综合一区二区三区 | 国产色婷婷精品综合在线播放 | 日本一道本视频 | 免费影视在线观看 | 自拍视频精品 | 国产精品激情 | 国产精品高清在线 | 国产亚洲网站 | 黑人粗黑大躁护士 | 91国产精品在线 | 久久久久久高潮国产精品视 | 日韩不卡在线 | 久久草在线视频 | 精品一区二区三 | 男女羞羞视频在线 | 日韩在线小视频 | 在线成人免费视频 | 亚洲国产一区在线 | 国产成人一区二区三区 | 日本天天操 | 日韩精品网站 | 91视频在线观看 | 久久久久免费观看 | 亚洲欧美日韩精品久久亚洲区 | 国产精品视频在线观看 |