前言:由于自己平时使用的串口检测功能比较多,而且作为硬件工程师,桌面上面使用的线缆比较多,为了方便调试。使用了STC8系列的单片机和一个E32(忆百特公司)生产的无线串口模块制作了一个无线的TTL模块。
我这个模块是基于STC8的库程序进行修改的,基本的设计思路是:USB-CDC转UART2(P1.0,P1.1)串口功能,通过核心板S-TXD2,S-RXD2接口进行收发、USB-CDC从电脑接收的数据通过S-TXD2,S-RXD2接口发送S-TXD2,S-RXD2接口收取的数据通过USB-CDC发送给电脑
本身库文件有一些局限性:串口的数据位只支持8位,停止位只支持1位;校验位可支持:无校验、奇校验、偶校验、1校验和0校验;支持自定义波特率
硬件设计图如下:
二:E32模块介绍:
E32模块是基于SX1278射频芯片的贴片型无线串口模块(TTL电平),透明传输方式,发射功率100MW,工作在410-441MHZ频段,采用LORA扩频技术。SX1278支持LORA扩频技术,通讯距离远,抗干扰能力强的优势,同时有极强的保密性。模块具有数据加密和压缩功能,模块在空中传输的数据,具有随机性,通过严密的加解密算法,使得数据截获失去意义。而数据压缩功能有概率减小传输时间,减少受干扰的概率,提高可考性和传输效率。
软件代码如下:
串口2的初始化 //======================================================================== // 函数: void UART1_TxByte(u8 dat) // 描述: 发送一个字节. // 参数: 无. // 返回: 无. // 版本: V1.0, 2022-12-13 //======================================================================== void UART2_TxByte(u8 dat) { B_TX2_Busy = 1; S2BUF = dat; while(B_TX2_Busy); } //======================================================================== // 函数: SetTimer2Baudraye(u16 dat) // 描述: 设置Timer2做波特率发生器。 // 参数: dat: Timer2的重装值. // 返回: none. // 版本: VER1.0 // 日期: 2014-11-28 // 备注: //======================================================================== void SetTimer2Baudraye(u16 dat) // 使用Timer2做波特率. { AUXR &= ~(1<<4); //Timer stop AUXR &= ~(1<<3); //Timer2 set As Timer AUXR |= (1<<2); //Timer2 set as 1T mode T2H = dat / 256; T2L = dat % 256; IE2 &= ~(1<<2); //禁止中断 AUXR |= (1<<4); //Timer run enable } //======================================================================== // 函数: void UART2_config(u8 brt) // 描述: UART2初始化函数。 // 参数: brt: 选择波特率, 2: 使用Timer2做波特率, 其它值: 无效. // 返回: none. // 版本: VER1.0 // 日期: 2014-11-28 // 备注: //======================================================================== void UART2_config(u8 brt) // 选择波特率, 2: 使用Timer2做波特率, 其它值: 无效. { /*********** 波特率固定使用定时器2 *****************/ if(brt == 2) { SetTimer2Baudraye(65536UL - (MAIN_Fosc / 4) / Baudrate2); S2CON &= ~(1<<7); // 8位数据, 1位起始位, 1位停止位, 无校验 IE2 |= 1; //允许中断 S2CON |= (1<<4); //允许接收 P_SW2 &= ~0x01; P_SW2 |= 0; //UART2 switch to: 0: P1.0 P1.1, 1: P4.6 P4.7 B_TX2_Busy = 0; TX2_Cnt = 0; RX2_Cnt = 0; } } //======================================================================== // 函数: void UART2_int (void) interrupt UART2_VECTOR // 描述: UART2中断函数。 // 参数: nine. // 返回: none. // 版本: VER1.0 // 日期: 2014-11-28 // 备注: //======================================================================== void UART2_int (void) interrupt 8 { if((S2CON & 1) != 0) { S2CON &= ~1; //Clear Rx flag RX2_Time_Point = 5 ; RX2_Buffer[RX2_Cnt] = S2BUF; if(++RX2_Cnt >= UART2_BUF_LENGTH) RX2_Cnt = 0; E32_LEDADD0 = ~ E32_LEDADD0 ; } if((S2CON & 2) != 0) { S2CON &= ~2; //Clear Tx flag B_TX2_Busy = 0; E32_LEDADD1 = ~ E32_LEDADD1 ; } } /*主程序*/ void main() { sys_init(); //系统初始化 usb_init(); //USB CDC 接口配置 Timer1_init(); //定时器1初始化 UART4_config(2); //串口4初始化 UART2_config(2); //串口2初始化 IE2 |= 0x80; //IE2相关的中断位操作使能后,需要重新设置EUSB EA = 1; PrintString2("STC8H8K64U UART2 Test Programme!\r\n"); //UART2发送一个字符串 E32_M0 = 0 ; //配置E32模块的M0,M1为低电平,进入工作模式 E32_M1 = 0 ; SystemType = 0 ; //默认模块为从机模式,当接收到USB接收缓冲器内有数据时候,立即进入工作模式 // if(DeviceState != DEVSTATE_CONFIGURED) //等待USB完成配置 // HostLED = 0 ; // else // SlaveLED = 0 ; // E32_LEDADD0 = 0 ; while (1) { delay_ms(1); KeyResetScan(); //长按P3.2口按键触发软件复位,进入USB下载模式,不需要此功能可删除本行代码 if(DeviceState != DEVSTATE_CONFIGURED) //等待USB完成配置 //// HostLED = 0 ; //// else //// SlaveLED = 0 ; continue; /***************************主机调用函数部分*********************************/ if (bUsbOutReady) { SystemType = 1 ; //配置模块模式立即为主机模式 HostLED = 0 ; //主机指示灯工作 SlaveLED = 1 ; //从机指示灯熄灭 usb_OUT_done(); //接收应答(固定格式) /*通过串口2将USB需要发送的数据发送到无线模块*/ for(SendPoint = 0 ; SendPoint <OutNumber ;SendPoint++ ) { UART2_TxByte(UsbOutBuffer[SendPoint] ); } } /*主机机机函数处理部分*/ if(SystemType == 1) { if(Rx2_Pack_Flag) //收到数据, 发送空闲 { Rx2_Pack_Flag = 0 ; USB_SendData(RX2_Buffer,RX2_Cnt); //将串口2接收的数据,全部上传到USB串口内,调用底层发送函数 RX2_Cnt = 0 ; } } /*从机函数处理部分*/ /*使用串口2 将输出发送到 外部的 TTL信号上面*/ if( SystemType == 0) { /*串口2接收到的数据,通过串口4发送出去*/ if(Rx2_Pack_Flag) //收到数据, 发送空闲 { Rx2_Pack_Flag = 0 ; for(TX4_Cnt = 0 ; TX4_Cnt < RX2_Cnt ;TX4_Cnt++ ) { UART4_TxByte(RX2_Buffer[TX4_Cnt] ); //从机模块,将串口2接收到数据,通过串口4全部发出去 } RX2_Cnt = 0 ; } /*串口4接收到的数据,通过串口2发送E32模块*/ if(Rx4_Pack_Flag) //收到数据, 发送空闲 { Rx4_Pack_Flag = 0 ; for(TX2_Cnt = 0 ; TX2_Cnt < RX4_Cnt ;TX2_Cnt++ ) { UART2_TxByte(RX4_Buffer[TX2_Cnt] ); //从机模块,将串口4接收到数据,通过串口2全部发出去 } RX4_Cnt = 0 ; } } } }
实物图片如下: