E70_433半双工无线模组,伪全双工方案

本文介绍了一种使用STM32微控制器通过E70_433半双工无线模组实现伪全双工通信的方案。通过外侧输入、输出模块,内侧的发帧和接收模块,以及中断处理,实现了在长时间尺度上的全双工效果。关键在于利用STM32的中断管理和数据缓冲区,确保数据的正确传输和及时响应。
摘要由CSDN通过智能技术生成

前言

要搞一个远程数据传输,性价比高的模块是433模块类型,一开始选用的是E70_433模组但是后来发现需要能够全双工,E62模块大概要贵50块钱,因此就继续尝试用E70模组,看看能不能降一点成本,因此就有了以下这个方案_φ_(..) 写作业
如果是全双工模块外侧输入数据可以直接接入串口:
A-(串口)-E62_433——(空中信道)
但是因为是半双工因此我需要加入一个mcu(stm32)控制串口
A-(串口)-stm32-(串口)-E70_433——(空中信道)
本文的设计内容为stm32里的转发程序

架构设计

传输模型
全双工意味着输入的时候可以输出,半双工意味着只能选择输入或者输入,因此如果半双工切换状态的速度够快,在长的时间尺度上就可以实现全双工的效果。

外侧输入模块

首先,外侧流入数据的速度必须低于433模块数据吞吐的速度因为433模组切换状态和发送都需要时间。
其次,通讯可能会锻炼,比如突然有强信号干扰,因此必须有一个合适大小的数据缓存区域,为了方便存储和读取,必须采用队列存储方式
最后,注意中断

外侧输出模块

首先,由于433速度大于外侧数据吞吐速度,因此必须有一个合适大小的数据缓存区域(需要略大于输入缓存区)
其次,为了加快通讯速度,必须采用中断发送而不是阻塞发送,因此需要使用队列存贮方式。
最后,注意中断

内侧发帧模块

两组433间的通讯认为是内侧通讯,这里主要执行的功能是读取外侧输入模块封存的数据帧和内侧接受模块封存的数据帧,拼接完成后组包对外发送。

内侧接受模块

两组433间的通讯认为是内侧通讯,这里主要执行的功能是接受另一侧433模块传来的数据包。当数据包正常时,将数据解包封存进入外侧发送模块,并且将外侧数据封存一帧以实现连续传输;当数据包不正常时(缺头,缺尾,缺身子,长度错误…等等)丢弃这一帧数据,立即回传一个重发信号包,以确保数据的稳定性

实现代码

通用宏定义

#define BUFF_LEN_B 5000
#define BUFF_LEN_O 6000
#define BUFF_LEN 200

#define FRAME_CLUB_MAX 49  //帧组最大数量

#define M_TRUE   0x5a      //未启用  
#define M_FALSE  0xa5      //未启用  

#define TRUE   1      	   
#define FALSE  0     			  

#define PPP_FLAG  0x7e      //ppp协议的帧头和帧尾部
#define PPP_START 0xFF      //ppp协议的帧的开始


#define E70_STATE_LISTEN 0x34     //433模块状态  接受数据包完成
#define E70_STATE_SEND   0x43     //433模块状态  发送数据包完成
#define E70_STATE_START  0x00     //433模块状态  准备建立通路

#define E70_STATE_OVERTIME  0x0E  //433模块状态  接受数据超时请求重发   新增:数据错误请求重发
#define E70_STATE_LISTEN_E  0x3E  //433模块状态  接受丢包反馈完成
#define E70_STATE_RESEND    0xE3  //433模块状态  重新发送数据包完成

#define PACK_MAX_DATA_LEN 100      //设定433模组间发送最大数据长度
#define PACK_HEAD_lEN      2      //设定包的头字节长度
#define PACK_LEN_lEN       2      //设定包的长度字节长度
#define PACK_NUMBER_lEN    2      //设定包的序号字节长度
#define PACK_FUNCTION_lEN  1      //设定包的类别字节长度
#define PACK_END_lEN       2      //设定包的结尾长度

#define PACK_OUTDATA_LEN (PACK_HEAD_lEN +\
														PACK_LEN_lEN+\
														PACK_NUMBER_lEN+\
														PACK_FUNCTION_lEN+\
														PACK_END_lEN)     
//设定433模组间除数据外的长度

#define PACK_MAX_LEN 		(PACK_OUTDATA_LEN + PACK_MAX_DATA_LEN)   
//设定433模组最大的数据长度

#define PACK_HEAD_DATA      0x1234 	//设定433模组包头
#define PACK_END_DATA       0x4321 	//设定433模组包头
#define PACK_FUNCTION_WIFI    0x01  //设定433模组包功能:wifi方面启动发包 wifi start (未启用)
#define PACK_FUNCTION_DATA    0x02  //设定433模组包功能:数值 data
#define PACK_FUNCTION_NULL    0x03  //设定433模组包功能:空   null									 (未启用)
#define PACK_FUNCTION_4G      0x04  //设定433模组包功能:4g方面启动发包 4g start		 (未启用)
#define PACK_FUNCTION_RESEND  0x05  //设定433模组包功能:接受方重新发送上一包数据

#define LOSE_HEAD_COUNT       0x02	//设定包头丢失最大计数
#define LOSE_HEAD_MODE_FINE   0x00	//设定包头丢失模式:无异常
#define LOSE_HEAD_MODE_WAIT   0x01	//设定包头丢失模式:等待判断
#define LOSE_HEAD_MODE_GET    0x02	//设定包头丢失模式:获取包尾
#define LOSE_HEAD_MODE_OUT    0x03	//设定包头丢失模式:获取超时

#define LOSE_TAIL_MODE_FINE   0x00	//设定包尾丢失模式:无异常
#define LOSE_TAIL_MODE_WAIT   0x01	//设定包尾丢失模式:等待判断
#define LOSE_TAIL_MODE_GET    0x02	//设定包尾丢失模式:获取包尾
#define LOSE_TAIL_MODE_OUT    0x03	//设定包尾丢失模式:获取超时

#define E70_TIME_OUT  500 			 	  // (单位是ms)
#define EC20_TIME_OUT 200 				  // (单位是ms)
 
#define LOSE_HEAD_TIME_OUT 100 			// (单位是ms) 
#define LOSE_TAIL_TIME_OUT 100 			// (单位是ms) 
#define LOSE_PACK_TIME_OUT 200 			// (单位是ms) 19200 帧间隔应该近似62.5m

struct _LOSE_HEAD_
{
	__IO u32 Time;					//包头丢失超时时间
	__IO uint8_t Count;    	//帧头丢失计数
	__IO uint8_t EndCount;  //帧尾获取计数
	__IO uint8_t Mode;      //帧头丢失种类  //0.正常,1.等待判断,2.获取包尾,3.超时判别
};
struct _LOSE_TAIL_
{
	__IO u32 Time;					//帧尾丢失超时时间
	__IO uint8_t Count;    	//帧头丢失计数
	__IO uint8_t EndCount;  //帧尾获取计数
	__IO uint8_t Mode;      //帧尾丢失种类  //0.正常,1.等待判断,2.获取包尾,3.超时判别
};

#define LOSE_HEAD _LOSE_HEAD_
#define LOSE_TAIL _LOSE_TAIL_

#define OUTSIDE USART2
#define INSIDE  USART1

#define OUTSIDE_TX_BUFF USART2_TX_BUFF
#define OUTSIDE_RX_BUFF USART2_RX_BUFF
#define INSIDE_TX_BUFF  USART1_TX_BUFF
#define INSIDE_RX_BUFF  USART1_RX_BUFF

#define OUTSIDE_TX_LEN  USART2_TX_LEN
#define OUTSIDE_RX_LEN  USART2_RX_LEN
#define INSIDE_TX_LEN   USART1_TX_LEN
#define INSIDE_RX_LEN  	USART1_RX_LEN

#define OUTSIDE_TX_QUEUE_LEN  USART2_TX_QUEUE_LEN
#define OUTSIDE_TX_END_LEN 	USART2_TX_END_LEN

#define g_sysOutTime  g_sysMTime

// 433 模块数据包接受完成后就是等待数据发送,数据发送完成后就是等待接受数据包,来回通讯
// 433 (send) ->- 433 (start)  to 433 (send)   --- 433 (listen)  start mode
// 433 (send) -<- 433 (send)   to 433 (listen) --- 433 (send)
// 433 (send) ->- 433 (send)   to 433 (send)   --- 433 (listen)
// or
// 433 (send) ->- 433 (send)   to 433 (send)   --- 433 (overtime)  
// 433 (send) -<- 433 (send)   to 433 (lis_e)  --- 433 (send)    
// 433 (re_s) ->- 433 (send)   to 433 (re_s)   --- 433 (listen)  resend lost pack
// or
// 433 (re_s) ->- 433 (send)   to 433 (re_s)   --- 433 (overtime)
// 433 (re_s) -<- 433 (send)   to 433 (listen) --- 433 (send)    jump lost pack

代码解析

以上建一个.h文件丢入,然后#include就可以了
其中OUTSIDE是对外侧连接的串口
其中INSIDE是对内侧连接的串口
其余有问题请留言_(´ཀ`」∠)_加班

通用工具函数


//在字符串1里找字符串2,返回字符串2结束在字符串1的位置,找不到时反馈0
uint16_t CompareString(uint8_t* Str1 ,uint8_t * Str2 ,uint16_t Str1_len,uint16_t Str2_len)
{
	uint16_t outLen   = 0;
	uint16_t startLen = 0;
	uint16_t i        = 0;
	if(Str1_len<Str2_len||Str2_len==0||Str1_len==0) //校验异常
		return 0;
	startLen=Str1_len-Str2_len;
	for(i=0;i<=startLen;i++)
	{
		if(*(Str1+i)==*Str2) //找到起始字符
		{
			for(outLen=0;outLen<Str2_len;outLen++)
			{
				if(*(Str1+i+outLen)!=*(Str2+outLen))
				{
//					printf("[test] i=%d, outLen=%d,*(Str1+i+outLen)=%x,*(Str2+outLen)=%x\r\n",
//					i,outLen,*(Str1+i+outLen),*(Str2+outLen));
					break;
				}
			}
			if(outLen==Str2_len)
				return outLen+i; //待验证
		}
	}
	return 0;
}
//在字符串1里找字符串2,返回字符串2结束在字符串1的位置,找不到时反馈0
uint16_t GetPackLen(uint8_t* Str1,uint16_t len)
{
	uint16_t outPackLen   = 0;
	uint16_t i            = 0;
	uint8_t  temp         = 0;
	if(len==0)
		return 0;                          //return
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值