无线433发送接收数据测试程序原理,有杂波解决方案
无线433发送接收测试程序
433Mhz无线通信相关知识不做介绍,网上很多避坑:MCU的接收引脚Data脚,是否配置上拉要参考MCU内部上拉电阻的大小,使用时最好拿示波器测量高低电平对应的电压。
此测试程序的433编码规则如下:
引导码:4.5ms低电平
逻辑1:560us高+1690us低
逻辑0:560us高 +560us低 ----- 只计算低电平时间可以判断逻辑
引导码—用户码—用户反码—键码—键码反码 --=实际数据32位有效
(和NEC协议差不多 ---- 程序也适合给NEC使用)
在50us定时器的中断服务函数中采样(在软件定时器中采样会收到部分干扰),根据实际波形做软件滤波处理。采样逻辑:
因为高电平时间一样,在引脚为低电平时计数变量++,50*x为低电平时间,当跳转到高电平时,"根据低电平的时间判断是否为引导码,确定引导码后,跳到接收数据的步骤",继续对低电平计数,完成32位后判断用户码,确定键值
"本文分两部分写:接收解码和发送测试" 主要看注释部分
======================接收解码部分
1.低电平计数/滤波
接收解码扫描函数,每50us对433接收到的波形计数一次采样扫描程序
void Recevie433DecodeScan(void) //放在50us定时器中断服务函数中
{static unsigned char Su8FilterCnt = 0;static bit SbJumpFlag = 0; //高低电平跳变标志,记录上一次引脚的状态,来反应从高到低或从低到高if(bRfDecodeOk == 0) //解码不成功的时候需连续解码,解码成功后延时150ms再次解码{if(!PIN_DATA) //引脚输入低电平{Gu8RfRxLowCnt++; //计时低电平个数来算时间,只通过低电平时间判断逻辑1或逻辑0Su8FilterCnt = 0; //高电平滤波计算if(SbJumpFlag && Gu8RfRxLowCnt >= 2) //两个50us的低电平后才判断电平从高到低,忽略部分杂波{SbJumpFlag = 0; //高到低跳变// Su8FilterCnt = 0;}}else //引脚检测到高电平时,判断高高电平是否有效,高电平有效后,计算进入解码程序{if(!SbJumpFlag && Su8FilterCnt++ >= 2) //可滤波{SbJumpFlag = 1; //低到高跳变Rf433SoftDecode(); //对上后解码,一次一位Gu8RfRxLowCnt = 0;Su8FilterCnt = 0;} }}
}
2.接收步骤并判断用户类型
void Rf433SoftDecode(void)
{static uchar Su8RfRxBitCnt = 0; //接收数据位static ulong Su32RfRxData = 0; //数据缓冲区if(bRfRecStartFlag == 0) //第一步,检测引导码,获取到引导码后开始检测数据{if((Gu8RfRxLowCnt > RF_START_L_MIN)&&(Gu8RfRxLowCnt < RF_START_L_MAX)) //引导码判断4.5ms低电平{bRfRecStartFlag = 1; //下次循环跳过此if,开始接收数据 Su32RfRxData = 0; //数据缓存清零Su8RfRxBitCnt = 0; //数据长度清零Gu8RfRxUserCode = 0;Gu8RfRxKeyValue = 0;}}else if((bRfRecStartFlag == 1)&&(Su8RfRxBitCnt < RF_REC_BIT_LEN)) //用接收位数判断暂停 {if((Gu8RfRxLowCnt > RF_LOGIC0_L_MIN)&&(Gu8RfRxLowCnt < RF_LOGIC0_L_MAX))//逻辑0时长判断,低电平时间范围需稍微加宽{Su32RfRxData = Su32RfRxData<<1; //LSB,从低位开始传数据,数据0直接位移Su8RfRxBitCnt++; //总位数++ }else if((Gu8RfRxLowCnt > RF_LOGIC1_L_MIN)&&(Gu8RfRxLowCnt < RF_LOGIC1_L_MAX)){Su32RfRxData = Su32RfRxData<<1;Su32RfRxData |= 1; //最低位赋值为1Su8RfRxBitCnt++;}else //某一位的时长不符合协议要求,丢弃整个数据{bRfRecStartFlag = 0;Su8RfRxBitCnt = 0;}}if(Su8RfRxBitCnt == 32) //接受完32位后解析用户码{Su8RfRxBitCnt = 0; bRfRecStartFlag = 0; //下一次重新检测引导码Gu8RfRxUserCode = Su32RfRxData >> 24; //用户码的8位if(Gu8RfRxUserCode == RF_NEC_USER_CODE){Gu8RfRxKeyValue = Su32RfRxData >> 8; //按键值第二个8位,此处可以判断最低8位是否为其反码bRfRecCodeOk = 1; //接收到一个NEC/433按键码,上报}else if(Gu8RfRxUserCode == RF_433_USER_CODE)//另一种用户码{Gu8RfRxKeyValue = Su32RfRxData >> 8;bRfRecCodeOk = 1; }}
}
3.任务处理
void Rf433RecevieDecodeTask(void)
{static uchar Su8RfRxTimeCnt = 0; //接收时间计数uchar u8KeyValueHigh = 0;uchar u8KeyValueLow = 0;if(bRfRecCodeOk) //发送接收到的命令即可{bRfRecCodeOk = 0;switch(Gu8RfRxKeyValue) //键值判断部分{UserTask()}Gu8RfRxKeyValue = 0;}if(bRfDecodeOk) //150ms后再次接受遥控码,可减小时间{Su8RfRxTimeCnt++;if(Su8RfRxTimeCnt >= 150) {Su8RfRxTimeCnt = 0;bRfDecodeOk = 0; }}
}
///全局与宏
uchar Gu8RfRxLowCnt = 0; //低电平接收计时器
uchar Gu8RfRxHighCnt = 0; //高电平接收计时器
uchar Gu8RfRxUserCode = 0; //客户代码
uchar Gu8RfRxUserCode1 = 0; //客户代码
uchar Gu8RfRxKeyValue = 0; //按键值
bit bRfDecodeOk = 0; //解码是否成功标志位
bit bRfRecStartFlag = 0; //接收同步码成功标志位
bit bRfRecCodeOk = 0; //引导码低电平时间,4.5ms低电平
#define RF_START_L_MAX 100 //100*50us=5ms
#define RF_START_L_MIN 75 //75*50us=3.9ms
#define RF_START_H_MAX 100 //100*50us=5ms
#define RF_START_H_MIN 75 //75*50us=3.9ms
#define RF_REC_BIT_LEN 32//逻辑0:560us高+560us低
//逻辑1:560us高+1690us低
#define RF_LOGIC0_L_MAX 18 //18*50us=900us
#define RF_LOGIC0_L_MIN 5 //5*50us=250us
#define RF_LOGIC1_L_MAX 40 //40*50us=2000us
#define RF_LOGIC1_L_MIN 25 //25*50us=1300us
#define RF_NEC_USER_CODE 0x55 //用户码
#define RF_433_USER_CODE 0x5A
//======================发送测试程序,需要连接433接收模块测试
1.发送的主要程序是计算 高和低电平的总时间,再分时间设置引脚的高/低电平。
2.此程序每间隔300ms发送一次,,可自己更改软件定时器的时间。
//放50us定时器中断函数中扫描,此定时器中的任务不能太多
void Rf433EncodingSendScan(void)
{static unsigned char SbRfTxTimeCnt = 0; //发送高低电平计数器,最大计数250*50us=12.5msif(bRfTxBitEnble){SbRfTxTimeCnt++;if(SbRfTxTimeCnt <= GbRfTxLogicHighTime) //固定高电平600us{PIN_DATA = 1;}else if(SbRfTxTimeCnt < GbRfTxLogicAllTime) //低电平时间 + 高电平时间{PIN_DATA = 0;}else{SbRfTxTimeCnt = 0;bRfTxBitOkFlag = 1; //完成1 bit的发送}}
}
#define RF_START_H 10 //500us
#define RF_START_T 90 //总时间 4ms低电平 + 500us高电平 //逻辑0:560us高+560us低 1120us 22.4
//逻辑1:560us高+1690us低 2250us 45
#define RF_LOGIC_H 12 //12*50us =600us
#define RF_LOGIC0_T 23 //23*50us=1150us 高低电平各自总时间
#define RF_LOGIC1_T 43unsigned char GbRfTxLogicHighTime = 0;
unsigned char GbRfTxLogicAllTime = 0;unsigned char GbRfTxSendData = 0;
unsigned char GbRfTxSendData3 = 0x69; //按键码,自己设置bit bRfTxBitEnble = 0;
bit bRfTxBitOkFlag = 0;
bit bRfTxByteOkFlag = 0;bit bRfTxSendFlag = 1; //一直发送
发送字节和任务处理
void Rf433SendByteData(void)
{unsigned char i = 0;GbRfTxLogicHighTime = RF_LOGIC_H; //600us高电平bRfTxBitEnble = 1; while(i < 8) {if(GbRfTxSendData & 0x80) //逻辑1GbRfTxLogicAllTime = RF_LOGIC1_T; else //逻辑0GbRfTxLogicAllTime = RF_LOGIC0_T;if(bRfTxBitOkFlag){bRfTxBitOkFlag = 0;GbRfTxSendData <<= 1; //左移1位i++;}}bRfTxBitEnble = 0;bRfTxByteOkFlag = 1; //完成一个byte的发送
}//300ms执行1次
void Rf433EncodingSendTask(void)
{unsigned char SbSendStep = 0; //改成Su8SendStepunsigned char SbSendCodeNum = 0;if(bRfTxSendFlag) //默认为1,一直发{while(SbSendCodeNum < 3) //连发3次,可改{switch(SbSendStep){case 0: //发送引导码GbRfTxLogicHighTime = RF_START_H; //500usGbRfTxLogicAllTime = RF_START_T; //4.5msbRfTxBitEnble = 1; //使能发送函数if(bRfTxBitOkFlag) //引导码发送完成{SbSendStep = 1;bRfTxBitOkFlag = 0;bRfTxBitEnble = 0; //停止发送}break;case 1: //发送数据GbRfTxSendData = 0x5c;Rf433SendByteData(); //阻塞发送,只发一次 if(bRfTxByteOkFlag) //1字节发送完成标志{bRfTxByteOkFlag = 0;SbSendStep = 2;}break;case 2:GbRfTxSendData = 0xc5;Rf433SendByteData();if(bRfTxByteOkFlag){bRfTxByteOkFlag = 0;SbSendStep = 3;}break;case 3:GbRfTxSendData = GbRfTxSendData3; //键值Rf433SendByteData();if(bRfTxByteOkFlag){bRfTxByteOkFlag = 0;SbSendStep = 0;SbSendCodeNum++;}break;}}bRfTxSendFlag = 0;}else{bRfTxSendFlag = 1;bRfTxBitEnble = 0;bRfTxBitOkFlag = 0;bRfTxByteOkFlag = 0;GbRfTxLogicHighTime = 0;GbRfTxLogicAllTime = 0;}
}
无线433发送接收数据测试程序原理,有杂波解决方案相关推荐
- 使用c#实现tcp的连接和发送接收数据
最近有个小项目,需要调用装置的录波数据,使用tcp模式,在这里整理了下如何使用c#实现tcp连接并实现发送接收数据,分享出来. 我这里使用的tcpclient ,终端是tcpserver模式. 首先自 ...
- 安卓Socket连接实现连接实现发送接收数据,openwrt wifi转串口连接单片机实现控制...
安卓Socket连接实现连接实现发送接收数据,openwrt wifi转串口连接单片机实现控制 socket 连接采用流的方式进行发送接收数据,采用thread线程的方式. 什么是线程? 详细代码介 ...
- 求android 中串口的发送接收数据代码
RT,求高手帮忙! 就是 /dev/ttyS0 和/dev/ttyS1 两个设备的通信问题.. 同求~ 这个是不是需要串口驱动啊?最近正在搞这个串口通信的案子,头疼 同样也没有搞出来,老是报:不能扫描 ...
- Python3树莓派连接阿里云物联网设备发送接收数据
Python3连接阿里云物联网设备发送接收数据(树莓派) 阿里云物联网IOT 代码部分 库文件 Windows下安装环境 树莓派安装环境 可能遇到的错误 代码 效果展示 阿里云物联网IOT 首先,准备 ...
- 微信小程序连接蓝牙 并分包发送 接收数据完整版
微信小程序连接蓝牙并分包发送接收数据 初始化蓝牙 初始化蓝牙设备 搜索蓝牙设备 连接蓝牙设备 获取蓝牙设备所有service(支持读写的) 向蓝牙发送数据 断开蓝牙 停止搜索蓝牙 转16进制 Arra ...
- Android发送接收WiFi,安卓Socket连接实现连接实现发送接收数据,openwrt wifi转串口连接单片机实现控制,安卓openwrt...
安卓Socket连接实现连接实现发送接收数据,openwrt wifi转串口连接单片机实现控制,安卓openwrt 安卓Socket连接实现连接实现发送接收数据,openwrt wifi转串口连接单片 ...
- C#利用SerialPort类对串口发送接收数据
1.连接串口方法 SerialPort ser = new SerialPort();//也可以在工具箱中直接拖SerialPort控件 public void OpenCom() {try{//波特 ...
- c# 串口发送接收数据
/********************** 串口数据接收事件 *****************************/private void SerialPort_DataReceived( ...
- 51单片机模拟串口发送接收数据(不使用SBUF)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 51单片机.模拟串口.串口发送.串口接收.逻辑分析仪 前言 一.配置定时器 二.串口发送 三.串口接收 四.主函数 五.波形图 5.1 ...
最新文章
- GIS输出PDF为什么标注有问题
- Win10+Ubuntu16.04/Ubuntu18.04双系统安装教程
- Shiro 身份验证
- leetcode讲解--513. Find Bottom Left Tree Value
- 微信和简书输入框文本选择手柄小bug
- python编程用户登陆c_python编写登录接口(上)
- 牛客《机器学习》习题收集整理
- VirtuoZo数字摄影测量(二)——模型定向与核线影像生成
- 【通信仿真】基于matlab多域网络仿真【含Matlab源码 1794期】
- 史上最管用的C盘深度清理秘籍
- 如何用一般方式获取C币可用分
- POS收单地区代码表(2015年3月版)
- Spring Cloud H (五)服务网关 GateWay
- 文件上传图片放大缩小进行截图上传
- 编写简单的中文分词程序
- 由观影引发的几点人生思考
- 7.16 两行代码实现全选checkAll
- 拖延症究竟是个什么东西?
- 明德扬基于XILINX K7核心板325T/410T
- 第一部分 思科九年 一(7)