本文将分为以下几个部分,分别是
物联网应用中的无线技术有多种,可组成局域网或广域网。组成局域网的无线技术主要有2.4GHz的WiFi,蓝牙、Zigbee等,组成广域网的无线技术主要有2G/3G/4G等。
LoRa 是LPWAN通信技术中的一种,是美国Semtech公司采用和推广的一种基于扩频技术的超远距离无线传输方案。这一方案改变了以往关于传输距离与功耗的折衷考虑方式,为用户提供一种简单的能实现远距离、长电池寿命、大容量的系统,进而扩展传感网络。目前,LoRa 主要在全球免费频段运行,包括433、868、915MHz等。
本文是使用ATK-LORA-01作为开发模块,是一款体积小,微功率,低功耗,高性能远距离LORA无线串口模块。模块采用高效的ISM频段射频SX1278扩频芯片。
ATK-LORA-01 模块具有:体积小、灵敏度高、支持低功耗省电,特点包括:
1、工业频段:433Mhz 免申请频段
2、多种功率等级(最大 20dBm,最大 100mW)
3、多种串口波特率、空中速率、工作模式
4、支持空中唤醒功能,低接收功耗
5、双 512 环形 FIFO
6、频率 410-441Mhz,提供 32 个信道
7、接收灵敏度达-136dBm,传输距离 3000 米
8、自动分包传输,保证数据包的完整性
模块根据MD0的配置与AUX引脚的状态会进入不同的功能,如下所示
其中通信功能如下,包含4中工作模式:
配置设备发射功率
查询设备配置的发射功率范围
0:11dbm
1:14dbm
2:17dbm
3:20dbm(默认)
//lora发送命令
//cmd:发送的命令字符串(不需要添加回车了),当cmd<0XFF的时候,发送数字(比如发送0X1A),大于的时候发送字符串.
//ack:期待的应答结果,如果为空,则表示不需要等待应答
//waittime:等待时间(单位:10ms)
//返回值:0,发送成功(得到了期待的应答结果)
// 1,发送失败
sprintf((char*)sendbuf,"AT+TPOWER=%d",LoRa_CFG.power);//设置发射功率
lora_send_cmd(sendbuf,"OK",50);
u8 lora_send_cmd(u8 *cmd,u8 *ack,u16 waittime)
{
u8 res=0;
USART3_RX_STA=0;
if((u32)cmd<=0XFF)
{
while((USART3->SR&0X40)==0);//等待上一次数据发送完成
USART3->DR=(u32)cmd;
}else u3_printf("%s\r\n",cmd);//发送命令
if(ack&&waittime) //需要等待应答
{
while(--waittime) //等待倒计时
{
delay_ms(10);
if(USART3_RX_STA&0X8000)//接收到期待的应答结果
{
if(lora_check_cmd(ack))break;//得到有效数据
USART3_RX_STA=0;
}
}
if(waittime==0)res=1;
}
return res;
}
//lora发送命令后,检测接收到的应答
//str:期待的应答结果
//返回值:0,没有得到期待的应答结果
//其他,期待应答结果的位置(str的位置)
u8* lora_check_cmd(u8 *str)
{
char *strx=0;
if(USART3_RX_STA&0X8000) //接收到一次数据了
{
USART3_RX_BUF[USART3_RX_STA&0X7FFF]=0;//添加结束符
strx=strstr((const char*)USART3_RX_BUF,(const char*)str);
}
return (u8*)strx;
}
Lora模块发送数据
u8 Dire_Date[]={0x11,0x22,0x33,0x44,0x55};//定向传输数据
u8 date[30]={0};//定向数组
//Lora模块发送数据
void LoRa_SendData(void)
{
static u8 num=0;
u16 addr;
u8 chn;
u16 i=0;
if(LoRa_CFG.mode_sta == LORA_STA_Tran)//透明传输
{
sprintf((char*)Tran_Data,"ATK-LORA-01 TEST %d",num);
u3_printf("%s\r\n",Tran_Data);
LCD_Fill(0,195,240,220,WHITE); //清除显示
Show_Str_Mid(10,195,Tran_Data,16,240);//显示发送的数据
num++;
if(num==255) num=0;
}else if(LoRa_CFG.mode_sta == LORA_STA_Dire)//定向传输
{
addr = (u16)obj_addr;//目标地址
chn = obj_chn;//目标信道
date[i++] =(addr>>8)&0xff;//高位地址
date[i++] = addr&0xff;//低位地址
date[i] = chn;//无线信道
for(i=0;i<Dire_DateLen;i++)//数据写到发送BUFF
{
date[3+i] = Dire_Date[i];
}
for(i=0;i<(Dire_DateLen+3);i++)
{
while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET);//循环发送,直到发送完毕
USART_SendData(USART3,date[i]);
}
//将十六进制的数据转化为字符串打印在lcd_buff数组
sprintf((char*)wlcd_buff,"%x %x %x %x %x %x %x %x",
date[0],date[1],date[2],date[3],date[4],date[5],date[6],date[7]);
LCD_Fill(0,200,240,230,WHITE);//清除显示
Show_Str_Mid(10,200,wlcd_buff,16,240);//显示发送的数据
Dire_Date[4]++;//Dire_Date[4]数据更新
}
}
Lora模块接收数据
//Lora模块接收数据
void LoRa_ReceData(void)
{
u16 i=0;
u16 len=0;
//有数据来了
if(USART3_RX_STA&0x8000)
{
len = USART3_RX_STA&0X7FFF;
USART3_RX_BUF[len]=0;//添加结束符
USART3_RX_STA=0;
for(i=0;i<len;i++)
{
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕
USART_SendData(USART1,USART3_RX_BUF[i]);
}
LCD_Fill(10,260,240,320,WHITE);
if(LoRa_CFG.mode_sta==LORA_STA_Tran)//透明传输
{
Show_Str_Mid(10,270,USART3_RX_BUF,16,240);//显示接收到的数据
}else if(LoRa_CFG.mode_sta==LORA_STA_Dire)//定向传输
{
//将十六进制的数据转化为字符串打印在lcd_buff数组
sprintf((char*)rlcd_buff,"%x %x %x %x %x",
USART3_RX_BUF[0],USART3_RX_BUF[1],USART3_RX_BUF[2],USART3_RX_BUF[3],USART3_RX_BUF[4]);
Show_Str_Mid(10,270,rlcd_buff,16,240);//显示接收到的数据
}
memset((char*)USART3_RX_BUF,0x00,len);//串口接收缓冲区清0
}
}