|
本帖最后由 zlkj 于 2016-11-29 21:03 編輯
請(qǐng)教!這個(gè)按鍵如何增加連發(fā)程序?

(原文件名:TP0.jpg)
//*********************【 NEC解碼頭文件 】*******************
//
// 簡(jiǎn)介:本程序適用于NCE解碼:(9ms+4.5ms)引導(dǎo)碼+32位編碼。
// 兼容STC所有型號(hào)(包括 1T 和 12T 系列),可以定義任意I/O作紅外接收腳,
// 自適應(yīng)解碼主頻:6MHz ~ 40MHz。
//
// 使用條件:占用系統(tǒng)定時(shí)器0,開(kāi)啟定時(shí)器0中斷(如使用其它定時(shí)器請(qǐng)自改IR_Init();初始化函數(shù))
//
// 使用說(shuō)明:填相關(guān)宏定義:USER_H、USER_L、Check_EN、CPU_Fosc、IR,
// 上電初始化函數(shù)IR_Init(),
// 在定時(shí)器0中斷中調(diào)用IR_NEC()解碼函數(shù),
// 解碼有效時(shí),IR_BT=2即短按,IR_BT=3即長(zhǎng)按,由用戶清0,
// 解碼存放:用戶碼高8位NEC[0],用戶碼低8位NEC[1],操作碼NEC[2],操作碼反碼NEC[3]。
//
//【供用戶調(diào)用的函數(shù)】
// IR_Init(); //接收初始化,開(kāi)啟定時(shí)器0中斷400us
// IR_NEC(); //紅外線解碼(解NEC編碼)
//
//***************************************************************/
#ifndef __IR_NEC_H__
#define __IR_NEC_H__
//【用戶必填項(xiàng):USER_H、USER_L、Check_EN、CPU_Fosc、IR】
#define USER_H 0x80 //用戶碼高8位
#define USER_L 0x7F //用戶碼低8位
#define Check_EN 0 //是否要校驗(yàn)16位用戶碼:不校驗(yàn)填0,校驗(yàn)則填1
#define CPU_Fosc 12000000L //輸入主頻,自適應(yīng)解碼(單位:Hz,范圍:6MHz ~ 40MHz)
#define CA_S 8 //長(zhǎng)按時(shí)間設(shè)置,單位:108mS(即 108mS整數(shù)倍,10倍以上為宜)
sbit IR = P3^6; //紅外線接口(任意引腳)
#define Step 400 //紅外采樣步長(zhǎng):400us
#define TH_H ((65536-Step*(CPU_Fosc/300)/40000)/256) //定時(shí)器高8位基準(zhǔn)賦值
#define TH_L ((65536-Step*(CPU_Fosc/300)/40000)%256) //定時(shí)器低8位基準(zhǔn)賦值
uint8 IR_BT; //解碼效果返回:0無(wú)效,1有效,2短按,3長(zhǎng)按
uint8 NEC[4]; //解碼存放:16位用戶碼、操作碼正反碼
uint8 cntCA; //長(zhǎng)按計(jì)數(shù)
uint16 cntStep; //步數(shù)計(jì)
bit IRa,IRb; //接收腳電位狀態(tài)保存
bit IRsync; //同步標(biāo)志
uint8 BitN; //位碼裝載數(shù)
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函數(shù):紅外線解碼初始化
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void IR_Init()
{
TMOD &= 0xF0; //清定時(shí)器0
TMOD |= 0x01; //定時(shí)器0:16位定時(shí)器
TL0 = TH_L; //每步時(shí)間
TH0 = TH_H;
ET0 = 1;
EA = 1;
TR0 = 1;
}
/*┈┈┈┈┈┈┈┈┈┈ 基準(zhǔn) ┈┈┈┈┈┈┈┈┈┈┈*/
#define Boot_Limit ((9000+4500 +1000)/Step) //引導(dǎo)碼周期上限
#define Boot_Lower ((9000+4500 -1000)/Step) //引導(dǎo)碼周期下限
#define Bit1_Limit ((2250 +800)/Step) //“1”周期上限
#define Bit0_Limit ((1125 +400)/Step) //“0”周期上限
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函數(shù):紅外線NEC周期采樣解碼法(定時(shí)中斷,下降沿查詢周期時(shí)間)
全局變量:IR_BT = 0無(wú)效
1有效,待繼續(xù)判斷長(zhǎng)、短按(如不需要判斷長(zhǎng)、短按,則直接使用)
2短按
3長(zhǎng)按
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void IR_NEC()
{
TL0 = TH_L; //重賦值
TH0 = TH_H;
cntStep++; //步數(shù)累加
if(IR_BT==1)if(cntStep>300)IR_BT=2; //解碼有效后,如果無(wú)長(zhǎng)按,120ms(400us×300)后默認(rèn)短按
IRb = IRa; //保存上次電位狀態(tài)
IRa = IR; //保存當(dāng)前電位狀態(tài)
if(IRb && !IRa) //是否下降沿(上次高,當(dāng)前低)
{
if(cntStep > Boot_Limit) //超過(guò)同步時(shí)間?
{
if(IR_BT==1)if(++cntCA>CA_S)IR_BT=3; //解碼有效后,繼續(xù)按住遙控>CA_S即長(zhǎng)按
IRsync=0; //同步位清0
}
else if(cntStep > Boot_Lower){ IRsync=1; BitN=32; } //同步位置1,裝載位碼數(shù)32
else if(IRsync) //如果已同步
{
if(cntStep > Bit1_Limit)IRsync=0;
else
{
NEC[3] >>= 1;
if(cntStep > Bit0_Limit)NEC[3] |= 0x80; //“0”與“1”
if(--BitN == 0)
{
IRsync = 0; //同步位清0
#if (Check_EN == 1)
if((NEC[0]==USER_H)&&(NEC[1]==USER_L)&&(NEC[2]==~NEC[3])) //校驗(yàn)16位用戶碼、操作碼正反碼
{ IR_BT=1; cntCA=0; } //解碼有效,接下來(lái)判斷:短按?長(zhǎng)按?
#else
if(NEC[2]==~NEC[3]){ IR_BT=1; cntCA=0; } //只校驗(yàn)操作碼正反碼
#endif
}
else if((BitN & 0x07)== 0) //NEC[3]每裝滿8位,移動(dòng)保存一次(即 BitN%8 == 0)
{ NEC[0]=NEC[1]; NEC[1]=NEC[2]; NEC[2]=NEC[3]; }
}
}
cntStep = 0; //步數(shù)計(jì)清0
}
}
//取消相關(guān)宏定義
#undef CPU_Fosc
#endif
主程序
#include "INC\STC89C52RC.H"
#include "INC\MY_SET.H"
#include "INC\IR_NEC.H" //調(diào)用NEC解碼頭文件
sfr SE = 0x80; //數(shù)碼管段選 P0:0x80 P1:0x90
sbit WX1 = P2^0; //數(shù)碼管位顯
sbit WX2 = P2^1;
sbit WX3 = P2^2;
sbit WX4 = P2^3;
sbit WX5 = P2^4;
sbit WX6 = P2^5;
sbit WX7 = P2^6;
sbit WX8 = P2^7;
uint8c tab[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0X88,0X83,0XC6,0XA1,0X86,0X8E,0xFF};
uint8 Xn,X1,X2,X3,X4,X5,X6;
void KZ0(); //短按處理
void KZ1(); //長(zhǎng)按處理
/***************** 主函數(shù) ********************/
void main(void)
{
IR_Init(); //紅外線解碼初始化
while(1)
{
//遙控檢測(cè)
if((IR_BT==2)||(IR_BT==3))
{
if(IR_BT==2)KZ0(); //短按處理
else KZ1(); //長(zhǎng)按處理
IR_BT =0; //清有效標(biāo)志
X1 = NEC[0]/16; //更新顯示
X2 = NEC[0]%16;
X3 = NEC[1]/16;
X4 = NEC[1]%16;
X5 = NEC[2]/16;
X6 = NEC[2]%16;
}
}
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函數(shù):遙控短按處理
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void KZ0()
{
switch(NEC[2])
{
case 0x12: P10 = !P10; break;
case 0x05: break;
case 0x1E: break;
case 0x55: break;
case 0x01: break;
case 0x1B: break;
case 0x03: break;
case 0x6B: break;
case 0x07: break;
case 0x08: break;
case 0x09: break;
case 0x68: break;
case 0x22: break;
case 0xE6: break;
case 0x33: break;
case 0xE2: break;
default:break;
}
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函數(shù):遙控長(zhǎng)按處理
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void KZ1()
{
switch(NEC[2])
{
case 0x12: P14 = !P14; break;
case 0x05: break;
case 0x1E: break;
case 0x55: break;
case 0x01: break;
case 0x1B: break;
case 0x03: break;
case 0x6B: break;
case 0x07: break;
case 0x08: break;
case 0x09: break;
case 0x68: break;
case 0x22: break;
case 0xE6: break;
case 0x33: break;
case 0xE2: break;
default:break;
}
}
/*********************數(shù)碼管掃描*************************/
void XS(void)
{
if(++Xn > 7)Xn=0;
switch(Xn)
{
case 0: WX8=1; NOP; //屏蔽上個(gè)位顯
SE=tab[X1]; //送段碼
WX1=0; //開(kāi)位顯
break;
case 1: WX1=1; NOP; SE=tab[X2]; WX2=0; break;
case 2: WX2=1; NOP; SE=tab[X3]; WX3=0; break;
case 3: WX3=1; NOP; SE=tab[X4]; WX4=0; break;
case 4: WX4=1; NOP; SE=tab[16]; WX5=0; break;
case 5: WX5=1; NOP; SE=tab[16]; WX6=0; break;
case 6: WX6=1; NOP; SE=tab[X5]; WX7=0; break;
case 7: WX7=1; NOP; SE=tab[X6]; WX8=0; break;
default:break;
}
}
/********************** 定時(shí)器0中斷函數(shù)************************/
void time0(void) interrupt 1
{
IR_NEC();
XS();
}
接收源程序+仿真
點(diǎn)擊此處下載 ourdev_689713KCBR6N.rar(文件大小:111K) (原文件名:NEC(任意接收引腳,支持長(zhǎng)短按).rar)
遙控器源程序
點(diǎn)擊此處下載 ourdev_689745J4Z85P.rar(文件大小:94K) (原文件名:遙控器源程序.rar)
/***************************************************************
作品:紅外線遙控發(fā)射(NEC編碼)
單片機(jī):STC89C52RC
晶振:12M
***************************************************************/
//
// 發(fā)射引腳(接PNP三極管b極)
// PNP三極管e極接2Ω電阻,c極接紅外發(fā)射管
#include <REG51.h>
#include "INC\MY_SET.h"
#include "INC\LCD1602_6IO.h"
sbit IR = P3^6; //發(fā)射引腳(接PNP三極管基極)
#define USER_H P2 //用戶碼高8位
#define USER_L P0 //用戶碼低8位
uint8c tab[16] = { //操作碼
0x12,0x05,0x1e,0x55,
0x01,0x1b,0x03,0x6b,
0x07,0x08,0x09,0x68,
0x22,0xE6,0x33,0xe2};
#define m9 (65536-9000) //9mS
#define m4_5 (65536-4500) //4.5mS
#define m1_6 (65536-1650) //1.65mS
#define m_56 (65536-560) //0.56mS
#define m40 (65536-40000) //40mS
#define m56 (65536-56000) //56mS
#define m2_25 (65536-2250) //2.25mS
void SanZhuan();
uint8 KEY(void);
void ZZ(uint8 x); //NEC編碼發(fā)送程序
void Z0(uint8 temp); //單幀(8位數(shù)據(jù))發(fā)送程序
void TT0(bit BT,uint16 x); //38KHz載波發(fā)射 + 延時(shí)程序
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函數(shù):主程序
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void main(void)
{
TMOD = 0x01; //T0 16位工作方式
IR=1; //發(fā)射端口常態(tài)為高電平
L1602_Init();
L1602_clr();
L1602_xy(0,0);
L1602_ZIFUC("UserCode :0x");
L1602_xy(0,1);
L1602_ZIFUC("Opcode :0x");
while(1)
{
L1602_xy(12,0);
L1602_JZ(USER_H,16,1);
L1602_JZ(USER_L,16,1);
SanZhuan();
}
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函數(shù):4×4矩陣鍵盤(pán)
【 線翻轉(zhuǎn)法鍵值表 】
P1.0 P1.1 P1.2 P1.3 P1.4 P1.5 P1.6 P1.7
│ │ │ │ │ │ │ │
│ │ │ └──7e be de ee
│ │ └─────7d bd dd ed
│ └────────7b bb db eb
└─────────── 77 b7 d7 e7
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
uint8 KEY(void)
{
uint8 Key = 0;
P1 = 0xf0; //鍵盤(pán)初始:行值=0,列值=1
NOP; //緩沖,待IO端口電位穩(wěn)定
Key = P1&0xf0; //得到行標(biāo)志
P1 = 0x0f; //翻轉(zhuǎn)鍵盤(pán)接口輸出
NOP;
Key |= (P1&0x0f); //列標(biāo)志 + 行標(biāo)志
return Key; //返回鍵值
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函數(shù):散轉(zhuǎn)程序
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void SanZhuan()
{
uint8 v;
v = KEY(); //鍵盤(pán)檢測(cè)
switch(v)
{
case 0x7e:ZZ(tab[0]);break;
case 0xbe:ZZ(tab[1]);break;
case 0xde:ZZ(tab[2]);break;
case 0xee:ZZ(tab[3]);break;
case 0x7d:ZZ(tab[4]);break;
case 0xbd:ZZ(tab[5]);break;
case 0xdd:ZZ(tab[6]);break;
case 0xed:ZZ(tab[7]);break;
case 0x7b:ZZ(tab[8]);break;
case 0xbb:ZZ(tab[9]);break;
case 0xdb:ZZ(tab[10]);break;
case 0xeb:ZZ(tab[11]);break;
case 0x77:ZZ(tab[12]);break;
case 0xb7:ZZ(tab[13]);break;
case 0xd7:ZZ(tab[14]);break;
case 0xe7:ZZ(tab[15]);break;
default:break;
}
v=0;
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函數(shù):NEC編碼發(fā)送程序
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void ZZ(uint8 Value)
{
L1602_xy(12,1);
L1602_JZ(Value,16,1); //更新顯示
TT0(1,m9); //高電平9mS
TT0(0,m4_5); //低電平4.5mS
/*┈ 發(fā)送4幀數(shù)據(jù)┈*/
Z0(USER_H); //用戶碼高8位
Z0(USER_L); //用戶碼低8位
Z0(Value); //操作碼
Z0(~Value); //操作碼反碼
/*┈┈ 結(jié)束碼 ┈┈*/
TT0(1,m_56);
TT0(0,m40);
/*┈┈ 重復(fù)碼 ┈┈*/
while(KEY() != 0xFF)
{
TT0(1,m9);
TT0(0,m2_25);
TT0(1,m_56);
TT0(0,m40);
TT0(0,m56);
}
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函數(shù):?jiǎn)螏?位數(shù)據(jù))發(fā)送程序
入口:temp
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void Z0(uint8 temp)
{
uint8 v;
for(v=0;v<8;v++)
{
TT0(1,m_56); //高電平0.65mS
if(temp&0x01) TT0(0,m1_6); //發(fā)送最低位
else TT0(0,m_56);
temp >>= 1; //右移一位
}
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函數(shù):38KHz載波發(fā)射 + 延時(shí)程序
入口:(是否發(fā)射載波,延時(shí)約 x (uS))
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void TT0(bit BT,uint16 x)
{
TH0 = x>>8; //輸入定時(shí)值
TL0 = x;
TF0=0; //溢出標(biāo)志位清0
TR0=1; //啟動(dòng)定時(shí)器0
if(BT == 0) while(!TF0); //BT=0時(shí),不發(fā)射38KHz載波只延時(shí);
else while(1) //BT=1時(shí),發(fā)射38KHz脈沖+延時(shí);38KHz載波(低電平)占空比5:26
{
IR = 0;
if(TF0)break;if(TF0)break;
IR = 1;
if(TF0)break;if(TF0)break;
if(TF0)break;if(TF0)break;
if(TF0)break;if(TF0)break;
if(TF0)break;if(TF0)break;
if(TF0)break;if(TF0)break;
}
TR0=0; //關(guān)閉定時(shí)器0
IR =1; //載波停止后,發(fā)射端口常態(tài)為高
} |
|
-
-
NEC(任意接收引腳,支持長(zhǎng)短按).rar
2016-11-19 20:31 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
110.81 KB, 下載次數(shù): 4, 下載積分: 黑幣 -5
-
-
遙控器源程序.rar
2016-11-19 20:31 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
93.91 KB, 下載次數(shù): 4, 下載積分: 黑幣 -5
|