触摸按键电路原理图(干货触摸按键信号用无线传输速成)
触摸按键电路原理图(干货触摸按键信号用无线传输速成)● 睡眠电流 9.5uA● 接收工作电流 24mA● 最大输出功率12dBm● 接收灵敏度-95dBm● 发射工作电流 40mA@12dBm
前言:最近帮人做了个小设备,使用了无线模块、触摸芯片,主要功能就是把触摸按键的信号无线传到控制继电器输出,MCU是STM8系列的芯片,其中使用过程中调试无线模块LC12S觉得挺好用的,就写了这篇文章。
模块介绍:
LC12S 采用 2.4G SOC 技术,特点是免开发,视距可达100米,模块收发一体无需切换,串口透明传输,提供通信协议,可迅速调试成功。用户只要了解串口通信,无需复杂的无线通讯知识,就能完成RF遥控产品的开发。模块没有数据包大小限制,延时短,半双工通讯,抗干扰能力强。
● 2.4GHz ISM 频段,使用无须申请
● 最大输出功率12dBm
● 接收灵敏度-95dBm
● 发射工作电流 40mA@12dBm
● 接收工作电流 24mA
● 睡眠电流 9.5uA
● 标准 TTL 电平 UART 串口
● 工作频率可设置,多个模块频分复用,互不干扰
● 通讯协议转换及射频收发切换自动完成,用户无须干预,简单易用
● 通讯速率 0.6kbps -38.4kbps,用户可通过 AT 指令配置
引脚 |
功能 |
描述 |
VCC |
电源正 |
2.8~3.6V,典型 3.3V |
RXT |
模块数据输出(TTL 电平) |
串口通信数据接收 |
TXD |
模块数据输入(TTL 电平) |
串口通信数据发送 |
SET |
设置位 |
配置参数使能(低电平配置,高电平或悬空为数传) |
CS |
休眠 |
低电平时模块工作,高电平或悬空模块休眠 |
GND |
电源地 |
接地 |
引脚功能描述VCC电源正2.8~3.6V,典型 3.3VRXT模块数据输出(TTL 电平)串口通信数据接收TXD模块数据输入(TTL 电平)串口通信数据发送SET设置位配置参数使能(低电平配置,高电平或悬空为数传)CS休眠低电平时模块工作,高电平或悬空模块休眠GND电源地接地
引脚功能描述VCC电源正2.8~3.6V,典型 3.3VRXT模块数据输出(TTL 电平)串口通信数据接收TXD模块数据输入(TTL 电平)串口通信数据发送SET设置位配置参数使能(低电平配置,高电平或悬空为数传)CS休眠低电平时模块工作,高电平或悬空模块休眠GND电源地接地
基本配置:设置模式:
一旦进入设置状态,SET 引脚配置必须是低电平,CS 引脚必须接低电平,模块串口参数会自动变为:数据位 8,波特率 9600,校验位 N,停止位 1。您的主控也要与此相同。
数传模式:
上电后,当 CS引脚接低电,进入数据传输模式,SET 脚是设置参数标志位,这个时候我们可以进行悬空或者拉高处理,让模块进入此模式。
设置模式数据的协议格式:在官方的手册里面有关于协议内容的说明,其中有一些数据是保留位,默认发0x00就可以。
如图所示,我们可以看到数据长度是18个byte,其中包括设备ID(Self ID)、组网ID(Net ID )、发射功率(RF Power)、通讯波特率设置(Baud 1Byte)、无线通讯通道设置(RF CHN)、设置时的通讯数据长度(Lenght 1Byte)、累加校验位(CheckSum);其中设置时的通讯数据长度是固定的18byte所以此处默认为0x12。
其他部分的设置参数,在手册中各有体现,其中组网ID需要按照自己定义的ID区间进行设置,因为这个唯一性会影响到你的模块组网情况。
其余的设置我设置参数我就不进行截图表示了,大家可以看一下相应的手册。
测试设置发送数据:
0xaa 0x5a 模块 ID 组网 ID(ID 必须相同) 0x00 RF 发射功率 0x00 串口速率 0x00 RF 信道选择 0x00 0x00 0x12(字节长度) 0x00 和校验字节 注意:和校验字节=所有参数累加的字节
发送: AA 5A 22 33 11 22 00 01 00 04 00 64 00 00 00 12 00 07
--->
参考后面的数据表格,以上配置参数设置无线模块为:RF 发射功率:10dbm 串口速率:9600bps RF 信道:100 模块 ID:0x2233 组网 ID:0x1122 和校验字节:07
接收: 设置完成后模块会返回相应数据 AA 5B 47 00 11 22 00 01 00 04 00 64 00 00 00 12 00 FA
<---
串口调试助手的信息:
实际设备连接情况:
设置模式接线示意图:
透传模式接线示意图:
代码实现:因为模式使用比较简单,初始化好设备串口外设,再把CS引脚和SET配置一下,就可以开始使用了,如果你只是简单测试,那你可能只需要使用默认设置,只是进行数据的透传,那你可以直接忽略这部分设置的代码部分,直接看nrf_send_normal_data()函数。
设置模式下的代码:
定义一个设置协议的结构体:
typedefstruct__attribute__((__packed__)){
u16head;//
u16self_id;//
u16net_id;//
u8nc1;//
u8rf_power;//
u8nc2;//
u8rf_baud;//
u8nc3;//
u8rf_chn;//
u16nc4;//
u8nc5;//
u8length;//
u8nc6;//
}SetSend;
拉低SET引脚,进入设置模式:
u8SetNrf(void)//
{
GPIO_ResetBits(SET_PORT SET_PIN);
GPIO_ResetBits(CS_PORT CS_PIN);
u8*p1=malloc(18);
memset(p1 0x00 18);
SetSend*p=(SetSend*)p1;
p->head=0xaa5a;
p->self_id=0x2233;
p->net_id=0x1122;
p->rf_power=0x00;
p->rf_baud=0x04;
p->rf_chn=0x64;
p->length=0x12;
p1[sizeof(SetSend)]=CheckSum((u8*)p sizeof(SetSend));
USART_Transmit_String(sizeof(SetSend) 1 p1);
#ifDEBUG_DPRINT
u8*str=malloc(20);
hex_str((u8*)p sizeof(SetSend) 1 str);
USART_Transmit_String(20 str);
//printf("--->:%s\r\n" str);
free(str);
#endif
free(p1);
return1;
}
数据透传的函数,这个时候SET引脚拉高,这个函数部分是我自己写的一个简单的3byte的sta状态发送。大家可以按照自己的实际使用情况进行修改。
voidnrf_send_normal_data(u16sta)
{
GPIO_SetBits(SET_PORT SET_PIN);
u8*p1=malloc(3);
memset(p1 0x00 3);
memset(p1 0xAA 1);
memcpy(p1 1 &sta 2);
USART_Transmit_String(3 p1);
free(p1);
}
芯片初始化之后需要等待几十ms才能正常工作,所以需要稍微等待一下。
串口接收解析部分,这部分代码就仁者见仁智者见智了,大家可以用很多种方法实现,我只是贴了一下我写的代码部分,仅供参考。其中NRF_RestTime()函数是在定时器中计时,用来区分不同的数据帧。
u8USART_RX_BUF[USART_MAX_RECV_LEN];
u16USART_RX_STA=0;
u8NRF_RecvdData(void)
{
u8ret=0;
if((USART_RX_STA&(1<<15))!=0)
ret=1;
returnret;
}
u16NRF_RcvLen(void)
{
return(USART_RX_STA&0x7FFF);
}
u8*NRF_RcvBuff(void)
{
returnUSART_RX_BUF;
}
voidNRF_ClsRecvd(void)
{
USART_RX_STA=0;
}
typedefstruct__attribute__((__packed__))
{
u32stat:1;
u32timOut:1;
u32cunt:15;
u32des:15;
}TboxTimTypeDef;
TboxTimTypeDefgNRFTimeManage;
#defineTON(1)
#defineTOFF(0)
voidTimerManageInit(TboxTimTypeDef*t u8stat u16destim)
{
t->des=destim;
t->stat=stat;
t->cunt=0;
t->timOut=0;
}
voidNRF_RestTime(void)
{
if(gNRFTimeManage.stat==TON)
{
(gNRFTimeManage.cunt<gNRFTimeManage.des)?(gNRFTimeManage.cunt ):\
(TimerManageInit(&gNRFTimeManage TOFF 0) USART_RX_STA|=1<<15);
}
}
voidNRF_Irq(void)
{
u8res;
if(USART_GetITStatus(USART1 USART_IT_RXNE)!=RESET)
{
res=USART_ReceiveData8(USART1);
#if0
USART_SendData8(USART1 res);
#endif
if((USART_RX_STA&~(1<<15))<USART_MAX_RECV_LEN)
{
TimerManageInit(&gNRFTimeManage TON 5);
USART_RX_BUF[USART_RX_STA ]=res;
}else
{
USART_RX_STA|=1<<15;
}
}
USART_ClearITPendingBit(USART1 USART_IT_RXNE);
}
voidParse_NRF(void)
{
if(NRF_RcvLen()>2)
{
u16len=NRF_RcvLen();
u8*p=NRF_RcvBuff();
u8pos=0;
u16*sta=(u16*)(p 1);
while(pos<len){
if(*p==0xAA)
{
relay_ctrl(*sta);
p =3;
pos =3;
}
else{
p ;
pos ;
}
}
USART_RX_STA=0;
}
}
设备展示
主机端:
从机端:
结语这就是我分享的LC12S模块的使用,如果大家有更好的想法和需求,也欢迎大家分享交流哈。