|
包含了紅外解碼,自動根據波特率設置定時器溢出率以及使用定時器延時
串口部分:
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
2018-8-5 21:31 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
288.26 KB, 下載次數: 28, 下載積分: 黑幣 -5
評分
-
查看全部評分
|