📄 2262_decode.c
字号:
#include <iom16v.h>
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
#include "key_dis.c"
#pragma interrupt_handler capt:iv_TIMER1_CAPT
#pragma interrupt_handler ov1:iv_TIMER1_OVF
//STD z_wide 窄脉冲宽度(4.7M振荡电阻)450us/2,STDk_wide 宽脉冲宽度1350us/2 (4MHz)
// 窄脉冲宽度(3.3M振荡电阻)330us/2,STDk_wide 宽脉冲宽度990us/2 (4MHz)
// 窄脉冲宽度(2.2M振荡电阻)210us/2,STDk_wide 宽脉冲宽度630us/2 (4MHz)
//设置窄脉冲最大值
#define z_widem 150
//#define z_wide 112
//#define k_wide 337
uint capt_time[4]; //捕捉时TCR1的值
uint a_wide; //捕捉的窄脉冲宽度
uint z_wide,k_wide; //窄脉冲宽脉冲宽度
uchar capt_code[13]; //12位码字
//uchar capt_cs; //捕捉次数
uchar number_byte; //第几位位码
uchar cs_byte; //边沿捕捉次数
uchar have_capt; //捕捉标志
uchar got_guide; //检测到引导码
//因为当按住PT2262的按键不放的时候PT2262会把编码不断的送出
//设置lianji_flg位用来检测按键有没有放开过如果没有放开则不再响应
//lianji_flg; //按键没有放开过标志(1:连接 0:点击)
/*---------------------初始化子程序-----------------*/
void init(void)
{
uchar i;
SREG&=~(1<<7); //关闭CPU总中断请求
init_1602();
for(i=0;i<4;i++) capt_time[i]=0;
a_wide=z_wide=k_wide=0;
DDRB|=(1<<DDB1);
//DDRB|=(1<<DDB0);
//PORTB|=(1<<PB0);
DDRB&=~(1<<DDB0); //PBO set to input
}
/*---------------------T1捕捉初始化子程序-----------------*/
void t1_init(void)
{
//capt_cs=0; //捕捉次数清0
have_capt=0; //捕捉标志清0
number_byte=0; //字码位数清0
cs_byte=0; //边沿捕捉次数清0
got_guide=0; //引导码标志清0
TCCR1A=0x00;
TCCR1B=0xC2; //T1普通模式,上升沿捕捉,8分频
TCNT1H=0X00; //计数器初值
TCNT1L=0X00;
TIMSK=0x00;
TIMSK|=(1<<TICIE1); //捕捉中断使能
TIFR|=(1<<ICF1); //捕捉中断标志清0 ***very important!!**
SREG|=(1<<7); //打开CPU总中断请求
}
/*---------------------T1捕捉中断处理子程序-----------------*/
void capt()
{
SREG&=~(1<<7); //关CPU总中断
TIFR|=(1<<ICF1); //捕捉中断标志清零
capt_time[cs_byte]=ICR1;
have_capt=1;
//capt_cs++;
if((TCCR1B&(1<<ICES1))==0x40) TCCR1B&=~(1<<ICES1);
else TCCR1B|=(1<<ICES1); //捕捉边沿取反
SREG|=(1<<7); //开CPU总中断
}
/*---------------------T1溢出中断处理子程序-----------------*/
void ov1()
{
TCNT1H=0X00; //计数器初值
TCNT1L=0X00;
}
/*---------------------位码判断子程序-----------------*/
uchar decode_byte()
{
uint wide_1,wide_2;
uchar w1,w2,byte;
//sreg=(SREG&BIT(7)); //保存SREG bit 7
SREG&=~(1<<7); //关闭CPU总中断请求
wide_1=capt_time[1]-capt_time[0]; //位码两脉冲宽度
wide_2=capt_time[3]-capt_time[2];
w1=z_wide/3; //%30余量
w2=k_wide/3;
if((wide_1>(z_wide-w1))&&(wide_1<(z_wide+w1)))
{
if((wide_2>(z_wide-w1))&&(wide_2<(z_wide+w1)))
byte='0'; //2窄,位码为0
else if((wide_2>(k_wide-w2))&&(wide_2<(k_wide+w2)))
byte='f'; //窄宽,位码为f
else
byte=9; //误码
}
else if((wide_1>(k_wide-w2))&&(wide_1<(k_wide+w2)))
{
if((wide_2>(z_wide-w1))&&(wide_2<(z_wide+w1)))
byte=9; //宽窄,误码
else if((wide_2>(k_wide-w2))&&(wide_2<(k_wide+w2)))
byte='1'; //宽宽,位码为1
else
byte=9;
}
else
byte=9;
//SREG|=sreg; //恢复SREG bit 7
SREG|=(1<<7); //开CPU总中断请求
return byte;
}
/*---------------------解码子程序-----------------*/
uchar decode()
{
uchar decode,byte_code;
while(number_byte<12) //已解码12位位码?
{
if(have_capt==1)
{
have_capt=0;
if(cs_byte==3)
{
cs_byte=0;
byte_code=decode_byte(); //解码位码
if(byte_code==9)
{
decode=0;
goto bb;
}
else
capt_code[number_byte]=byte_code; //位码输出
number_byte++;
}
else
cs_byte++;
}
}
//TIMSK&=~(1<<TICIE1); //关捕捉中断
decode=1;
bb: number_byte=0; //字码位数清0
return decode;
}
/*---------------------引导码检测子程序-----------------*/
uchar detect_guide()
{
uchar i,b,guide,sreg;
uint low_cs; //检测低电平次数
//TIMSK&=~(1<<TICIE1); //关捕捉中断
//sreg=(SREG&BIT(7)); //保存SREG bit 7
SREG&=~(1<<7); //关闭CPU总中断请求
a_wide=capt_time[1]-capt_time[0]; //计算脉冲宽度
if(a_wide>=z_widem) //大于窄脉冲最大值,非引导码,返回
{
guide=0;
goto kk;
}
//delay50(1);
low_cs=a_wide*16*2/50; //4MHz
//间隔50us,连续检测PB0低电平low_cs次(约16倍窄脉冲时间),均为低时确认为引导码
for(i=0;i<low_cs;i++)
{
b=PINB;
if((PINB&(1<<PB0))==0x01)
{
guide=0;
goto kk;
}
delay50(1);
}
guide=1; //检测到引导码返回1
z_wide=a_wide; //确定窄脉冲和宽脉冲宽度
k_wide=z_wide*3;
kk: //TIMSK|=(1<<TICIE1); //开捕捉中断
SREG|=(1<<7); //开CPU总中断请求
//SREG|=sreg; //恢复SREG bit 7
return guide;
}
/*---------------------错误处理子程序-----------------*/
void error_code(uchar i)
{
write_com(0X01); //display clear
wait1602ready();
setxy_1602(0,0);
switch(i)
{
case 1:
write_str("decode error!!");
case 2:
write_str("not guide!!");
default:
write_str("no type error!!");
}
delay(1);
}
/*---------------------输出控制子程序-----------------*/
void work()
{
write_com(0X01); //display clear
wait1602ready();
setxy_1602(0,0);
write_str(capt_code);
setxy_1602(0,1);
write_dat(capt_code[1]);
delay(5);
}
/********************主程序*************************/
void main()
{
uchar k,l,gd,de,sreg;
init();
delay(1); //4M 1000us
delay50(1); //4M 49.75us
delay50(5); //4M 195.25us
t1_init(); //T1捕捉初始化
while(1)
{
//按键处理
//TIMSK|=(1<<TICIE1); //开捕捉中断
sreg=(SREG&BIT(7)); //保存SREG bit 7
SREG&=~(1<<7); //关闭CPU总中断请求
k=key_press();
if(k)
{
write_com(0X01); //display clear
//delay(5);
wait1602ready();
l=key_scan();
switch(l)
{
case(1):
PORTB|=(1<<PB1);
setxy_1602(1,0);
write_str("remote open");
delay(1);
break;
case(2):
PORTB&=~(1<<PB1);
setxy_1602(1,0);
write_str("remote close");
delay(1);
break;
default:
delay(1);
}
k=0;
}
SREG|=sreg; //恢复SREG bit 7
if(have_capt==1)
{
have_capt=0;
cs_byte++;
if(cs_byte>=2)
{
cs_byte=0;
gd=detect_guide(); //引导码判断
if(gd)
{
t1_init(); //T1捕捉初始化
de=decode(); //解码
if(de)
{
SREG&=~(1<<7); //关闭CPU总中断请求
work(); //输出
delay(100);
SREG|=(1<<7); //开CPU总中断请求
}
else
{
SREG&=~(1<<7); //关闭CPU总中断请求
error_code(1); //报错
delay(100);
SREG|=(1<<7); //开CPU总中断请求
}
}
/*else
{
SREG&=~(1<<7); //关闭CPU总中断请求
error_code(2); //报错
delay50(1);
SREG|=(1<<7); //开CPU总中断请求
} */
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -