📄 pt2272.c
字号:
/********** 用单片机代替PT2272解码PT2262的程序说明*********************************************
当按键有效时 PT2262 发送四次编码每发送一次编码都有14ms 宽度的低电平分开而42ms 的编码是有A0~A11
十二个码组成A0 在前A11 在后我们现在把A8~A11 用来当作数据发送了
因为每检测到按键有效一次,PT2262发送四次编码.我们可以利用这一特点来解码 先检测有没有接收到信息当
有的时候我们就去掉第一次编码的信号检测14ms的低电平来检测编码的开始信号后才开始解码
我们可以发现每个码的长度都是3.5ms左右 每个编码都是由高电平开始然后到低电平又到高电平又回到低电平
我们从第一个高电平的宽度可以把1 码区分出来
剩下的悬空码和0 码可以从第二个高电平的宽度具体区分出来的
单片机译码方法如下
由高电平开始检测到上升沿时就延时870us 读取接收的状态记为A0 然后再检测下一个上升沿降沿后又延时870us
读取接收的状态记为A1 这样就把一个编码给译出来了
A0 A1 和悬空1 码0 码的关系如下:
A0 A1 代码
0 0 0码
0 1 悬空
1 0 错误
1 1 1码
***********************************************************************************************/
#include<pic.h>
#include "C:\HT-PIC\samples\delay\delay.h"
#define W_REM GP3 //遥控器入口
#define LED0 GP0 //
#define LED1 GP1 //
//编码设定为:A0~A7地址编码为:悬空
#define addr_user_a0 0x00
#define addr_user_a1 0xff
//定义共用体
union
{
unsigned int word;
struct
{
unsigned char byte_data;
unsigned char byte_addr;
}bytes;
}a_0,a_1;
//位定义
unsigned char recv_flg, //接收正确位标志(1:正确 0:错误)
//因为当按住PT2262的按键不放的时候PT2262会把编码不断的送出
//设置lianji_flg位用来检测按键有没有放开过如果没有放开则不再响应
lianji_flg; //按键没有放开过标志(1:连击 0:点击)
// 函数声明部份
void remote_2272_deco();
fastcall void set_port(void);
fastcall void PT2272_deco();
fastcall void work();
// 主函数
void main(void)
{
//上电初始化.
set_port();
while(1)
{
remote_2272_deco(); //接收遥控码
asm("clrwdt");
work(); //控制输出
}
}
fastcall void set_port(void)
{
TRIS =0x08;
GPIO=0x00;
OPTION=0xCF;
}
fastcall void PT2272_deco() //解码
{
unsigned char i;
signed char cnt;
unsigned int temp;
if(lianji_flg) ;
else
{
//清除上次解码内容
recv_flg=0;
//先找出接收码的开头即13.5ms左右的低电平
for(i=0;i<100;i++)//延时12mS 检测和等待12ms的低电平
{
if(W_REM)i=0 ;
else DelayUs(120);
}
//等待在2ms内接收到的低电平
for(i=0;i<35;i++)
{ //延时2mS
if(W_REM) break;
else DelayUs(100);
}
//12ms到15ms内接收到上升沿则跳去解码否则返回
if(i>30) //超出15ms接收错误返回
{
lianji_flg =0; //清按键没有放开过标志
recv_flg=0;
return;
}
a_0.word=a_1.word=0;
if((W_REM)&&(i<30))
for(cnt=11;cnt>=0;cnt--)
{
//等待870us后采集接收信号
DelayUs(335);
DelayUs(335);
//采集接收信号并记录
if(W_REM) temp=1;
else temp=0;
a_0.word |= (temp<<cnt);//保存键值
//等待第二个上升沿
if(W_REM)while(W_REM) ;
while(!W_REM);
//等待870us后采集接收信号
DelayUs(335);
DelayUs(335);
//采集接收信号并记录
if(W_REM)temp=1;
else temp=0;
a_1.word |= (temp<<cnt);//保存键值
//等待第二个码值的上升沿
if(W_REM)while(W_REM) ;
if(cnt>=0)while(!W_REM);
}
//把接收的编码左移4位将8位密码放在同一字节上
a_0.word <<=4;
a_1.word <<=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;
}
}
}
/*
void remote_2272_deco() //接收遥控码(解码程序)
{
unsigned int i,k=0;
for(i=0;i<4000;i++)//检测220ms内有没有编码接收
{
if(W_REM)
{
DelayUs(60); //50uS延时
if(W_REM&&(!recv_flg))
{
PT2272_deco(); //解码
break;
}
}
else
{ k++;
// if(k>500)
{
recv_flg =0;
lianji_flg =0;
GPIO=0x00;
}
}
}
// lianji_flg =0;//清按键没有放开过标志
}
*/
void remote_2272_deco() //接收遥控码(解码程序)
{
unsigned int i;
for(i=0;i<3000;i++)//检测220ms内有没有编码接收
{
if(W_REM)
{
DelayUs(60); //50uS延时
if(W_REM)
{
PT2272_deco(); //解码
break;
}
}
else
{
DelayUs(100);
}
}
if(i>2900) lianji_flg =0;
else lianji_flg =1;
//清按键没有放开过标志
}
fastcall void work() //控制输出
{
if(recv_flg||lianji_flg ) //接收不正确,退出zz
{
recv_flg=0; //清接收正确标志位
switch(a_0.bytes.byte_data)
{
case 0x80:LED1=1;
break;
case 0x40:LED0=1;
break;
case 0x20:LED0=1;
break;
case 0x10:LED1=1;
break;
default:
{
GPIO=0x00;
} break;
}
//lianji_flg =0;
}
else GPIO=0x00;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -