摘要
超再生技术是直放式的一种,是利用正反馈原理,把经过放大了的信息回馈到输入端,再放大。所谓直放,是与超外差技术相对应的。也就是说信号本身不经过变频,直接进行处理。 与超外差技术相比,超再生技术电路简单、灵敏度高、体积小成本低,但不足之处在于灵敏度不稳定起伏较大、抗干扰能力差、频率稳定性差易产生频率漂移、近距接收时易产生阻塞。
结构图
- 固定码: 编码芯片的地址是不变的,如型号以EV1527、PT2262
- 滚动码: 编码芯片的地址是变化的,如型号以HS300、HS301
- 模拟码 编码和解码都是根据数据帧结构约定的规则进行发送数据的编码和接收数据的解码
数据帧结构
编码
数据位的“1”和“0”是由高低电平宽度(脉冲宽度)的比例决定的。
如果高电平宽度为低电平宽度的 3 倍,就表示逻辑“1”,
反之如果低电平为高电平宽度的 3 倍,就表示逻辑“0”。
同步脉冲高电平和低电平的比例固定为 4:124.
采用一个IO口和定时器做模拟编码,定时器做电平宽度的控制,IO口做上下沿的切换
1.宏定义脉冲宽度
#define FACTOR 115
#define XS 10
#define SYNC_H ( 4*FACTOR/XS)
#define SYNC_L (125*FACTOR/XS)
#define DAT1_H ( 12*FACTOR/XS)
#define DAT1_L ( 4*FACTOR/XS)
#define DAT0_H ( 4*FACTOR/XS)
#define DAT0_L ( 12*FACTOR/XS)
2.定时器初值
#define TIM_Value(x) do{TIM_COUNT=x;}while(0) //时间值
3.数据帧结构
3.1 同步头
Tx_SetD_Hi();
TIM_Value(SYNC_H); //同步头
t_flag=1;
3.2 发送数据
Tx_SetD_Lo();
TIM_Value(SYNC_L);
t_idx=0;
da=t_val;//发送的数据
t_flag=2;
if(t_idx>=t_len)
{
if(--t_cnt==0)//发送次数
{//发送完成
t_flag=0xff;
Tim_OFF();
}
else
{
LED_Turn;
t_flag=0;
TIM_Value(1);
}
}
else
{
Tx_SetD_Hi();
TIM_Value((da&(1ul<<23))?DAT1_H:DAT0_H);
t_flag=3;
}
解码
- 启用定时器,装入初值并开启中断,定时进入中断服务程序
- 在中断服务程序中,装入初值并开启中断,定时进入中断服务程序
- 查询数据输入管脚的状态,如果为高电平,就在高电平状态累加计数,反之就在低电平状态计数;
- 当电平发生上升沿变化的时候,判断接收到的高低电平宽度的值是否符合同步信号的要求,
如果符合就进入数据位的接收,以同样的方式判断逻辑“1”或逻辑“0”。
如果接受过程中出现不符合要求的电平状态,就退出接收。为了增加可靠性,一般要求规定时间内, 成功接收到完全相同的 2 帧数据才算有效,接收完成后,24 个数据位被放入 3 个字节中。- 对接收到的数据进行处理,判断编码的类型,分离地址码和按键码。
1.定时器中断接收
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
rx_val();
}
}
2.解码过程
if (!RF) {
lle_w++; // 检测到低电平 低电平时间加1,
myFlag.oneBit.old_bit=0;
}
else // 检测到高电平
{
hle_w++;//记录高电平时间
if (!myFlag.oneBit.old_bit)// 检测到从低到高的跳变,已检测到一个完整(高-低)电平周期
{
if (((hle_w>=2)&&(hle_w<=7))&&((lle_w>=50)&&(lle_w<=170))) //判同步码
{
if((lle_w>=90)&&(lle_w<=170))//if((ll_w>=110)&&(ll_w<=170))
{
ma_n=0;
myFlag.oneBit.tb_ok=1;
bma=0;
myFlag.oneBit.bt_auto=0;//TMR0=0xA6;
}
}
else if ((myFlag.oneBit.tb_ok)&&((lle_w>=10)&&(lle_w<=17))) //数据低电平
{
//已经接收到同步码,判为0
bma=bma<<1;
if(ma_n==23)
{
if(!myFlag.oneBit.rf_ok1)//第一次接收
{
mma=bma;
myFlag.oneBit.rf_ok1=1;
ma_n=0;
myFlag.oneBit.tb_ok=0;
myFlag.oneBit.bt_auto=0;
s_TO=1500;
}
else
{
myFlag.oneBit.rf_ok2=1;
ma_n=0;
myFlag.oneBit.tb_ok=0;
myFlag.oneBit.bt_auto=0;
}
}
ma_n++;
}
else if ((myFlag.oneBit.tb_ok)&&((lle_w>=2)&&(lle_w<=7))) //数据高电平 取数据1
{
bma=bma<<1;
if(ma_n<23)
{
bma+=1;
}
if(ma_n==23)
{
bma+=1;
if(!myFlag.oneBit.rf_ok1)//第一次接收
{
mma=bma;//接收到的编码
myFlag.oneBit.rf_ok1=1;
myFlag.oneBit.tb_ok=0;
myFlag.oneBit.bt_auto=0;
ma_n=0;
s_TO=1500;
}
else //第二次接收数据
{
myFlag.oneBit.rf_ok2=1;
myFlag.oneBit.tb_ok=0;
myFlag.oneBit.bt_auto=0;
ma_n=0;
}
}
ma_n++;
}
else //解码失败
{
ma_n=0;
myFlag.oneBit.tb_ok=0;
myFlag.oneBit.bt_auto=0;
bma=0;
hle_w=1;
lle_w=0;
}
lle_w=0;
hle_w=1;
}
myFlag.oneBit.old_bit=1; // 记录本次电平状态
}