高电平来检测编码的开始信号接收到5ms 的高电平后才开始解码我们可以发现每个码的长度都是1.2ms
左右每一个编码都是由低电平开始然后到高电平又到低电平又回到高电平我们从第一个高电平
的宽度可以把1 码区分出来剩下的悬空码和0 码可以从第二个高电平的宽度区分出来
具体的单片机译码方法如下
由高电平开始检测到下降沿时就延时300us 读取接收的状态记为A0 然后再检测下一个下降沿
降沿后又延时300us 读取接收的状态记为A1 这样就把一个编码给译出来了
A0 A1 和悬空1 码0 码的关系如下:
A0 A1 代码
0 0 1 码
0 1 错误
1 0 悬空
1 1 0 码
******************************************************************************/
#i nclude <STC516AD.H>
#define uchar unsigned char
#define uint unsigned int
//定义共用体
union
{
uint word;
struct { //结构bytes
uchar byte_addr;
uchar byte_data;
}bytes;
}a_0,a_1;
//位定义
sbit W_REM =P3^3; //遥控接收输入脚
sbit LED0 =P1^0;
sbit LED2 =P1^2;
bit bdata recv_flg, //接收正确位标志(1:正确 0:错误)
//因为当按住PT2262的按键不放的时候PT2262会把编码不断的送出
//设置lianji_flg位用来检测按键有没有放开过如果没有放开则不再响应
lianji_flg; //按键没有放开过标志(1:连接 0:点击)
uchar
// addr_a0, //接收的8位地址编码A0
// addr_a1, //接收的8位地址编码A1
// data_a0, //接收的4位数据编码A0
// data_a1, //接收的4位数据编码A1
addr_user_a0, //设定的8位地址密码A0
addr_user_a1; //设定的8位地址密码A1
// led_out; //输出控制
//------------------------------------- sub functon ----------------------------------------------
//------------------------------------- sub functon ----------------------------------------------
//------------------------------------- sub functon ----------------------------------------------
//------------------------------------- sub functon ----------------------------------------------
//------------------------------------- sub functon ----------------------------------------------
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//void d1ms (uint ljh_in) /*1mS延时函数*/
//{
// uint data ljh_i;
// uchar data ljh_j;
// for(ljh_i=0;ljh_i<ljh_in;ljh_i++){
// for(ljh_j=0;ljh_j<108;ljh_j++){
// _nop_(); _nop_();
// _nop_(); _nop_();
// _nop_(); _nop_();
// }
// }
//}
//<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void d50us(uchar n) //50uS延时
{
uchar data i,j;
for(j=n;j;j--) { //[1T+2T+(2i+2)T+1T+2T]*n+1T+2T+2T=(2i+8)*n+5T
for(i=21;i;i--) ;//延时2T+2T*i=(2i+2)T
}
}
//<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
PT2272_deco() //解码
{
uchar i,cnt;
if(recv_flg) ;
else {
//清除上次解码内容
cnt =12; //接收12位编码
//解码 ------------------------------------------------------------------------
//先找出接收码的开头即5ms左右的高电平 ----------------------------------
//设置高电平时间为4~6ms
//检测和等待4ms的高电平
for(i=80;i;i--) { //延时4mS
if(!W_REM) i=80;
else d50us(1);
}
//等待在2ms内接收到的低电平 --------------------------------------------
for(i=40;i;i--) { //延时4mS
if(!W_REM) break;
else d50us(1);
}
//4ms到6ms内接收到下降沿则跳去解码否则返回
//超出6ms接收错误返回
if(i) {
recv_flg =0; //清按键没有放开过标志
goto PT2272_deco_exit; //返回 --------------------------------
}
//等待300us后采集接收信号
d50us(6);
//采集接收信号并记录
a_0.word=a_1.word=0;
for(i=0;i<6;i++) {
if(W_REM) {
a_0.word |=0x01;
}
a_0.word <<=1;
// MOV C,W_REM //读A0数据
// MOV A,DATA_A0
// RLC A
// MOV DATA_A0,A //保存相应位的A0
// MOV A,ADD_A0
// RLC A
// MOV ADD_A0,A //高位转移
//等待第二个下降沿
while(!W_REM) ;
while(W_REM) ;
// JNB W_REM,$
// JB W_REM,$
//等待300us后采集接收信号
d50us(6);
// MOV 40H,#150 //2T
// DJNZ 40H,$ //2T 延时:2T+2T*150=302T
if(W_REM) {
a_1.word |=0x01;
}
a_1.word <<=1;
// MOV C,W_REM //读A1数据
// MOV A,DATA_A1
// RLC A
// MOV DATA_A1,A //保存相应位的A1
// MOV A,ADD_A1
// RLC A
// MOV ADD_A1,A //高位转移
//等待第二个码值的下降沿
while(!W_REM) ; //___wd___
while(W_REM) LED2=~LED2;
// JNB W_REM,$
// JB W_REM,$
// DJNZ 34H,REMOTE6 //接收12 位编码 --------------------------------
}
//把接收的编码左移4位将8位密码放在同一字节上----------------------------
a_0.word <<=4;
a_1.word <<=4;
// MOV 40H,#4
//REMOTE7:
// CLR C
// MOV A,DATA_A0
// RLC A //送出低8位的bit7
// MOV DATA_A0,A //低8位的A0左移1位
// MOV A,ADD_A0
// RLC A //接收低8位的bit7
// MOV ADD_A0,A //高8位的A0左移1位
// CLR C
// MOV A,DATA_A1
// RLC A //送出低8位的bit7
// MOV DATA_A1,A //低8位的A1左移1位
// MOV A,ADD_A1
// RLC A //接收低8位的bit7
// MOV ADD_A1,A //高8位的A1左移1位
// DJNZ 40H,REMOTE7 //左移4位
// //把4位数据编码由高4位移到低4位上 ---------------------------------
// MOV A,DATA_A0
// SWAP A
// MOV DATA_A0,A //把4位数据编码A0由高4位移到低4位?
// MOV A,DATA_A1
// SWAP A
// MOV DATA_A1,A //把4位数据编码A1由高4位移到低4位?
//比较密码 --------------------------------------------------------------
if((a_0.bytes.byte_addr==addr_user_a0)&&(a_1.bytes.byte_addr==addr_user_a1)) {
recv_flg =1;
lianji_flg =1;
} else {
recv_flg =0;
lianji_flg =0;
}
// MOV A,ADD_A0
// XRL A,ADD_USER_A0
// JNZ REMOTE8 //密码不正确则跳转
//
// MOV A,ADD_A1
// XRL A,ADD_USER_A1
// JNZ REMOTE8 //密码不正确则跳转
// //置接收正确位 ---------------------------------------------------------
// SETB RECEIVE
// //置ENABLE 用于检测按键有没有放开 --------------------------------
// SETB ENABLE
// RET //接收正确返回 -----------------------------------------
//REMOTE8:
// CLR ENABLE
// CLR RECEIVE
// RET //接收不正确返回 ---------------------------------------
}
PT2272_deco_exit:
return;
}
//<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void remote_2272_deco() //接收遥控码(解码程序)
{
uint i;
//检测50ms内有没有编码接收
for(i=1000;i;i--) {
if(!W_REM) {
PT2272_deco(); //解码
break;
}
else d50us(1); //50uS延时
}
recv_flg =0; //清按键没有放开过标志
}
//<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void work() //控制输出 //把选中的LED取反
{
if(recv_flg) { //接收不正确,退出
recv_flg=0; //清接收正确标志位
a_0.bytes.byte_data =~a_0.bytes.byte_data;
P1 =P1^a_0.bytes.byte_data;
}
//WORK:
// JNB RECEIVE,WORK_END //接收不正确,退出
// //每次按键都一次响应
// CLR RECEIVE //清接收正确标志位
// MOV A,DATA_A1
// CPL A
// ORL A,#0FH //屏蔽低4位
// MOV DATA_A1,A
// MOV A,LCD_OUT
// XRL A,DATA_A1
// ORL A,#0FH
// MOV LCD_OUT,A
// MOV P1,LCD_OUT
// NOP
//WORK_END:
// RET
// END
}
//<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<-<
// ==================================== main function ============================================
// ==================================== main function ============================================
// ==================================== main function ============================================
// ==================================== main function ============================================
// ==================================== main function ============================================
// ==================================== main function ============================================
void main (void)
{
//上电初始化 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P1 =0xff;
P3 =0xff;
for(addr_user_a1=100;addr_user_a1;addr_user_a1--) d50us(200); //50uS延时
//编码设定为:A0~A7地址编码为:悬空 +++++++++++++++++++++++++++++++++++++++++++++
addr_user_a0 =0xff;
addr_user_a1 =0x00;
//start: //================================================================================
while(1) {
remote_2272_deco(); //接收遥控码
work(); //控制输出
LED0 =!LED0;
}
}