433无线通讯技术简介
- 发射器和接收器:433MHz无线通信系统由发射器和接收器组成。发射器将数据编码成射频信号并通过天线发送出去,接收器则通过天线接收这些信号并解码以获取原始数据。
- 调制方式:通常使用幅度移键(ASK)调制方式,简单且成本低。
-
ASK介绍
ASK是幅移键控,通过调幅将数据发送出去,所以发送与接收都是多位二进制数。ASK如何区分0和1?
0:发送 433.92Mhz 无线波形(载波频率)振幅低
1:发送 433.92Mhz 无线波形(载波频率)振幅高OOK 如何区分 0 和 1?(OOK 是 ASK 的一种特殊形式)
0:不发送数据(振幅为0)
1:发送 433.92Mhz 无线波形(载波频率) - 频率和传输距离:工作频率为433.92MHz,传输距离在开阔环境下可达90米。
应用场景
- 智能家居:用于智能开关、传感器、门窗控制器等设备,实现家庭自动化。
- 工业控制:用于远程设备监控和管理,特别是在需要长距离、稳定通信的场景中。
- 物联网(IoT):连接各种智能设备,实现数据传输和共享。
- 遥控器:如家用电器遥控器、车库门遥控器等。
- 无线门禁系统:提供便捷的出入控制和安全保障。
优势
- 低功耗:相比其他无线技术,433MHz的功耗较低,适合电池供电的设备。
- 长距离传输:具有较好的穿透能力和较长的传输距离。
- 成本效益:设备制造成本较低,适合大规模应用。
不足
- 数据传输速率低:传输速率较低,不适合需要高速数据传输的应用。
- 缺乏统一的通信协议:不同设备之间的兼容性可能存在问题。
- 安全性问题:由于通常采用数据透明传输协议,安全性较差,容易被攻击
433常见编码协议
1.EV1527编码
数据帧结构
- 同步码:每帧数据以同步码开始,通常由一个较短的高电平(如400微秒)和一个较长的低电平(如9毫秒)组成。
- 地址码:由20位组成,每个芯片的地址码是固定的,出厂前预设,理论上每个芯片的地址码是唯一的。
- 按键码:由4位组成,对应芯片上的K0-K3四根数据线,不同的按键状态会产生不同的按键码。
编码规则
- 逻辑“0”:通常由较短的高电平和较长的低电平组成,例如400微秒高电平加800微秒低电平。
- 逻辑“1”:通常由较长的高电平和较短的低电平组成,例如1毫秒高电平加200微秒低电平
2.PT2262编码
PT2262/2272是普城公司生产的一种CMOS工艺制造的低功耗低价位通用编解码电路,
芯片描述:
PT2262/2272最多可有12位(A0-A11)三态地址端管脚(悬空,接高电平,接低电平),任意组合可提供531441地址码,PT2262最多可有6位(D0-D5)数据端管脚,设定的地址码和数据码从17脚串行输出,可用于无线遥控发射电路。
编码芯片PT2262发出的编码信号由:地址码、数据码、同步码组成一个完整的码字,解码芯片PT2272接收到信号后,其地址码经过两次比较核对后,VT脚才输出高电平,与此同时相应的数据脚也输出高电平,如果发送端一直按住按键,编码芯片也会连续发射。当发射机没有按键按下时,PT2262不接通电源,其17脚为低电平,所以315MHz的高频发射电路不工作,当有按键按下时,PT2262得电工作,其第17脚输出经调制的串行数据信号,当17脚为高电平期间315MHz的高频发射电路起振并发射等幅高频信号,当17脚为低平期间315MHz的高频发射电路停止振荡,所以高频发射电路完全收控于PT2262的17脚输出的数字信号,从而对高频电路完成幅度键控(ASK调制)相当于调制度为100%的调幅。
编码格式
数据帧结构
同步码:由4T的高电平、124T的低电平和4T的高电平组成
地址码:由12位组成,每个地址位可以是高电平、低电平或悬空状态
数据码:由4位或8位组成,具体取决于应用需求
编码规则
逻辑“0”:由4T的高电平和12T的低电平组成
逻辑“1”:由12T的高电平和4T的低电平组成
逻辑“F”(悬空码):由4T的高电平和12T的低电平组成
发送过程
重复发送:通常,每次按键操作会重复发送相同的地址码和数据码多次,以确保信号的可靠接收
数据顺序:地址码和数据码都是从最低位开始发送的
RISC芯片433遥控解码和其他解码结合时的处理方法
- 以实际问题举类子,当要实现一个433遥控的人体感应灯时,芯片需要同时处理433信号和人体探头传来的信号,人体感应探头需要每9ms读取一次数据,而常见的433格式的编码如1527格式的编码的引导码为9ms,数据帧有三个字节占用30ms总共时长为39ms。
- 想要对433信号进行处理,就要不断读取引导码
- 引导码为9ms如果把引导码放在主循环和人体感应抬头一起读取,会导致探头漏掉数据,所以把引导码检测放在中断当中进行读取
- 进入中断的时间要设置的合理,设置的时间太长,会导致9ms他、引导码检测的数据太少造成误报,设置的时间太短又会导致进中断过于频繁影响主程序的运行
- 实际测试下来256ms进入一次中断误进入的次数很少
代码示例
不影响主循环中每9ms检测一次的人体探头检测
中断函数{
if(count<600)//30ms 检测的时间
{
SHUT=0; //0为使能433接受芯片
if(b_IRKeyPress==0)//没有接受到引导码
{
if(IR_IN==0)//检测433引导码
{
if(lu8_GCCount<30)lu8_GCCount++;//进来一次计数加一
}
else
{
lu8_GCCount=0;//没有一只为0的话就清零
}
if(lu8_GCCount>7)//要略小于引导码的值
{
lu8_GCCount=0;
b_IRKeyPress = 1;//引导码检测标志
}
while(IR_IN==0)//检测到引导码的值后延迟一会,让引导码走完等到数据码出现
{
asm("clrwdt");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
lu8_GCCount++;
if(lu8_GCCount>250)
{
lu8_GCCount=0;
b_IRKeyPress=0;
break;
}
}
}
}
if(b_IRKeyPress)
{
b_IRKeyPress = 0;
lu8_GCCount=0;
for(lu8_i=0; lu8_i<3; lu8_i++){ //三个字节
for(lu8_j=0; lu8_j<8; lu8_j++){ //一个字节
lu8_DCCount = 0;
while(IR_IN){//高电平
lu8_DCCount++;
// asm("nop");//根据芯片的指令周期调整
// asm("nop");
asm("clrwdt");
// asm("nop");
// asm("nop");
// asm("nop");
// asm("nop");
// asm("nop");
if(lu8_DCCount > 200){//大于最大的数据码中的时间退出
b_IRErr = 1;
break;
}
}
if(b_IRErr==0){//没有错误
lu8_DCCount = 0;
while(IR_IN==0){//低电平
lu8_DCCount++;
// asm("nop");
// asm("nop");
asm("clrwdt");
// asm("nop");
// asm("nop");
// asm("nop");
// asm("nop");
// asm("nop");
if(lu8_DCCount >100){//大于最大的数据码中的时间退出
b_IRErr = 1;
break;
}
}
}
//当前位解码为0
if(lu8_DCCount > 9){
g_u8_IRValue[lu8_i] = (unsigned char)(g_u8_IRValue[lu8_i]<<1);
g_u8_IRValue[lu8_i] &= 0xfe; }
//当前位解码为1
else{
g_u8_IRValue[lu8_i] = (unsigned char)(g_u8_IRValue[lu8_i]<<1);
g_u8_IRValue[lu8_i] |= 0x01;
}
}
if(b_IRErr){
break;
}
}
b_IRKeyPress = 0;
if(b_IRErr==0){
b_IRDECODE = 1;
read_adress1 = g_u8_IRValue[0]; //保存接收到的数据
}
b_IRErr = 0;
}
//------------------------------------------
//count=0;
}
else if(count<640) //200ms休眠的时间
{
SHUT=1;//置1关闭433接收芯片
}
else
{
SHUT=0;
count=0;
}
}
发射代码
//===================发送编码===============
void fn_send_1()
{
OUT1 = 1;
delay_ms(1);
OUT1 = 0;
delay_10us(20);
}
void fn_send_0()
{
OUT1 = 1;
delay_10us(40);
OUT1 = 0;
delay_10us(80);
}
void fn_send_0_8()
{
fn_send_0();
fn_send_0();
fn_send_0();
fn_send_0();
fn_send_0();
fn_send_0();
fn_send_0();
fn_send_0();
}
void fn_send_data()
{
volatile unsigned char i;
volatile unsigned char tmp;
// fn_send_0();
// fn_send_0();
// fn_send_0();
// fn_send_0();
// fn_send_0();
// fn_send_0();
// fn_send_0();
// fn_send_0(); //前导码,滤除干扰
// 引导码2ms高,2ms低
OUT1 = 1;
delay_ms(2);
OUT1 = 0;
delay_ms(2);
tmp = send_data[0];
for (i = 0; i < 8; i++)
{
if (tmp & 0x80)
{
fn_send_1();
}
else
{
fn_send_0();
}
tmp = tmp << 1;
}
tmp = send_data[1];
for (i = 0; i < 8; i++)
{
if (tmp & 0x80)
{
fn_send_1();
}
else
{
fn_send_0();
}
tmp = tmp << 1;
}
tmp = send_data[2];
for (i = 0; i < 8; i++)
{
if (tmp & 0x80)
{
fn_send_1();
}
else
{
fn_send_0();
}
tmp = tmp << 1;
}
}
433低功耗处理
433发射端
433发射端低功耗很简单,只需要检测到有按键按下再发射信号就可以了,但是要做到接受端也低电平,常见的1527编码的数据帧比较长,如果想要接收端的功耗进一步降低,需要对发射端的编码调整
433接收端
- 由于433接受芯片正常工作时的功耗比较大,常常是6ma左右,
- 要实现低功耗就需要间隔的打开和关闭接收芯片的使能端口,要确保每次都能采集到引导码,必须要确保433接收的时间大于一个引导码+数据码+引导码的时间
要想把功耗做低有下面几种方法
1.降低数据码的时间
2.减少引导码的时间
3.发射端按下一次多发几次数据
睡眠的时间为遥控器发出数据的总时间减去感应时间
- 图示这种情况情况说明睡眠时间的极限值,如果睡眠时间超过:数据总时间-检测时间,就有可能检测不到引导码。
- 我们把休眠的时间设置为433信号的时间减去-感应时间。
- 上文已经说明了感应的时间为两个引导码+一个数据码时间
那么:
- 信号的时间-休眠时间=感应时间=两个引导码+一个数据码。
- 在图里面就是前面是引导码,后面是引导码加数据码,这是极限情况,这样能检测到其他情况也能检测到,到最开始发的信号刚好检测不到时,最后面的那个引导码也刚好到达下一个检测时间
所以在调试程序时我们要让休眠的时间占比变多,我们就可以减少检测时间,检测时间为引导码加数据码,和增加总发射时间:让433遥控板按一次多发几次数据,尽可能多发一点数据,但是不能太久,时间太长又会影响到下一次的按下,我们这边发射的时间设置为200ms,如果可以接受按键迟钝一点那么可以把时间进一步加长。
低功耗代码编写
其他代码和上文的代码一致,只需要把接受数据信号和引导码的时间调小,也可以少发几个字节的数据。