单片机编码 无线模块发送与接收 程序
模块型号,可在万能的某宝搜索【超再生无线模块】
接收距离:空旷200米[这是卖家说的,有待考验]
接收端在没有收到讯号,会生成间歇性尖状脉冲,data接LED负极,5V接LED正极,可看见闪烁
准备:
发送端接高电平5~12V,如果是315M的模块,天线长度应为23cm,
本实验使用的433M的模块,发送端天线长度17cm, 竖直向天
接收端天线长度25cm到30cm,竖直
测试环境:
复杂的室内环境,楼上角落到楼下大门外电梯间,15m,有效,
再远就接收不到了,可能需要提高收发端电压能改善。
接线:
发送端:模块发射端data接STC12C5A60S2的P1^1,P0.0接LED负极,LED正极接5V
接收端:数据data接STC12C4052AD的P3^4,P3^7接LED1负极 P1^7接LED2负极 LED正极都接5V
电平定义:
准备发送:高电平6ms,4ms低电平
逻辑0:高电平1ms,低电平1ms
逻辑1:高电平1ms,低电平2ms
现象:
发射端发射4个数字,0x93,0x94,0x95,0x96,
接收端判断4个数字,0x93,0x94,0x95,0x96,
如果匹配,
0x93 控制开LED1
0x94,控制关LED1
0x95,控制开LED2
0x96,控制关LED1
发送端循环发送,接收端可以看到2个灯分别受4个数据的控制
【模块的样子】
【发送端】
【接收端】
========================================================================
【演示】
1,发射端没有上电,接收端LED不会闪烁
2,发送端上电
3,接收端,收到匹配的字符,判断对应的字符,开启关闭对应的LED
发送端程序【公开】
/************************************ 程序名: 无线模块【发射端】程序 编写人: 春哥 编写时间: 2015年10月31日 硬件支持: STC12C5A60S2 外部晶体12MHz 接口说明: P0.0接口发射,发送时LED亮,发送结束LED熄灭 /***********************************/ #include <STC12C5A60S2.H> //单片机头文件 sbit OUT = P1 ^ 0; sbit LED = P0 ^ 0; void DELAY_MS (unsigned int a){ unsigned int i; while( a-- != 0){ for(i = 0; i < 600; i++); } } void ST (void){//开始码 OUT = 1; // DELAY_MS (6); OUT = 0; // DELAY_MS (4); } void BT (bit s){//数据位码 OUT = 1; DELAY_MS (1); OUT = 0; DELAY_MS (1); if(s){ DELAY_MS (1); } } void MT (unsigned char a){ //8位的数据发送 unsigned char i,n; for(i=0;i<8;i++){ n = a & 0x80; a = a << 1; if(n == 0x80){ BT(1); }else{ BT(0); } } } void END (void){//开始码 MT(0xFF); } void main (void){ while(1){ LED=0; // 开始发送 LDE灯亮 ST(); MT(0x93); MT(0x94); MT(0x95); MT(0x96); END(); LED=1; // 发送结束,LED熄灭 DELAY_MS (1000); } }
接收端程序【公开】
/************************************ 程序名: 无线模块【接收】程序 编写人: 春哥 编写时间: 2015年10月31日 硬件支持: STC12C4052AD 外部晶体12MHz 接口说明: P3.4接口 接无线data ***************************************/ #include <STC12C2052AD.H> //单片机头文件 sbit IN =P3^4; sbit LED1=P3^7; sbit LED2=P1^7; unsigned char Ir_Buf[4]; //用于保存4个8位的解码结果 void DELAY_MS (unsigned int a){ unsigned int i; while( a-- != 0){ for(i = 0; i < 600; i++); } } unsigned int Ir_Get_Low() { TL1=0; TH1=0; TR1=1; // 如果是0就循环,不能超过32.768ms while(!IN && (TH1&0x80)==0); TR1=0; return TH1*256+TL1; } unsigned int Ir_Get_High() { TL1=0; TH1=0; TR1=1; // 如果是1就循环,不能超过32.768ms while(IN && (TH1&0x80)==0); TR1=0; return TH1*256+TL1; } void main(void){ unsigned int temp; unsigned char i,j; TMOD=0x10; // 使用定时器1,设定16位的定时/计数器 while(1){ restart: while(!IN); // 检查发送准备就绪,去除杂波干扰 temp=Ir_Get_High(); //循环发送4个8位的 6毫秒高电平 标记判断 if(temp<5000 || temp>8000){ goto restart; } temp=Ir_Get_Low(); //循环发送4个8位的 4毫秒低电平 标记判断 if(temp<3000 || temp>6000){ goto restart; } // 只有上面的两个标记都通过了,说明发送端 准备好了 for(i=0;i<4;i++){ //接收4个字节 for(j=0;j<8;j++){ //每个字节8位 // 检验数据开始的高电平长度 temp=Ir_Get_High(); if(temp<500 || temp>1500){ goto restart;} // 检验低电平长度 temp=Ir_Get_Low(); if(temp<500 || temp>2500){ goto restart;} Ir_Buf[i]<<=1; // 第一位默认写零 if(temp>1500) { Ir_Buf[i]|=0x01; } // 比较是0还是1 或运算1 } } if(Ir_Buf[0]==0x93) LED1=0; // 如果接收到0x93,LED1亮1000MS DELAY_MS (1000); if(Ir_Buf[1]==0x94) LED1=1; // 如果接收到0x94,LED1灭500MS DELAY_MS (500); if(Ir_Buf[2]==0x95) LED2=0; // 如果接收到0x95,LED2亮1000MS DELAY_MS (1000); if(Ir_Buf[3]==0x96) LED2=1; // 如果接收到0x96,LED2灭500MS DELAY_MS (500); } }
要思考的问题:
怎么才能使我的电报不能有误码,即使被别人截获也无法读取
关于数据校验:
奇偶校验
源码校验
反码校验
CRC校验
MD5校验
求和校验
传输加密:
异或,
加
减
本文出自 “生命不息,折腾不止。” 博客,谢绝转载!
原文:http://990487026.blog.51cto.com/10133282/1708438