基本上和正点原子手册上一样,只是为了以后使用方便,去除了屏幕显示和定向传输部分的代码。
串口使用串口三
定时器使用TIM7,用PA4记录AUX上升沿和下降沿变化。
Lora简介
引脚配置及功能:
相关函数整理
去除了LCD显示的部分
头文件Lora.h
#ifndef __LORA_H
#define __LORA_H
#include "sys.h"
typedef struct
{
u16 addr;//设备地址
u8 chn;//信道
u8 power;//发射功率
u8 wlrate;//空中速率
u8 wltime;//休眠时间
u8 mode;//工作状态
u8 mode_sta;//发送状态
u8 bps;//串口波特率
u8 parity;//较验位
}_LoRa_CFG;
//空中速率(单位:Kbps)
#define LORA_RATE_0K3 0 //0.3
#define LORA_RATE_1K2 1 //1.2
#define LORA_RATE_2K4 2 //2.4
#define LORA_RATE_4K8 3 //4.8
#define LORA_RATE_9K6 4 //9.6
#define LORA_RATE_19K2 5 //19.2
//休眠时间
#define LORA_WLTIME_1S 0 //1秒
#define LORA_WLTIME_2S 1 //2秒
//工作模式
#define LORA_MODE_GEN 0 //一般模式
#define LORA_MODE_WK 1 //唤醒模式
#define LORA_MODE_SLEEP 2 //省电模式
//发射速率
#define LORA_PW_11dBm 0 //11dBm
#define LORA_PW_14Bbm 1 //14dBm
#define LORA_PW_17Bbm 2 //17dBm
#define LORA_PW_20Bbm 3 //20dBm
//·¢ËÍ״̬
#define LORA_STA_Tran 0 //透明传输
#define LORA_STA_Dire 1 //定向传输
//´®¿Ú²¨ÌØÂÊ(µ¥Î»:bps)
#define LORA_TTLBPS_1200 0 //1200
#define LORA_TTLBPS_2400 1 //2400
#define LORA_TTLBPS_4800 2 //4800
#define LORA_TTLBPS_9600 3 //9600
#define LORA_TTLBPS_19200 4 //19200
#define LORA_TTLBPS_38400 5 //38400
#define LORA_TTLBPS_57600 6 //57600
#define LORA_TTLBPS_115200 7 //115200
//串口数据较验
#define LORA_TTLPAR_8N1 0 //8位数据
#define LORA_TTLPAR_8E1 1 //8位数据+1位偶较验
#define LORA_TTLPAR_8O1 2 //8位数据+1位奇较验
//设备出场默认参数
#define LORA_ADDR 0 //设备地址
#define LORA_CHN 23 //通信信道
#define LORA_POWER LORA_PW_20Bbm //发射功率
#define LORA_RATE LORA_RATE_19K2 //空中速率
#define LORA_WLTIME LORA_WLTIME_1S //休眠时间
#define LORA_MODE LORA_MODE_GEN //工作模式
#define LORA_STA LORA_STA_Tran //发送状态
#define LORA_TTLBPS LORA_TTLBPS_9600 //波特率
#define LORA_TTLPAR LORA_TTLPAR_8N1 //校验位
#define LORA_AUX PAin(4) //LORA模块状态引脚
#define LORA_MD0 PAout(15) //LORA模块控制引脚
extern _LoRa_CFG LoRa_CFG;
extern u8 Lora_mode;
void EXTI4_IRQHandler(void);
void Aux_Int(u8 mode);
u8 LoRa_Init(void);
void LoRa_Set(void);
void LoRa_ReceData(void);
void LoRa_SendData(void);
#endif
初始化函数
相关I/O口初始化,以及串口3初始化
LORA_MD0=1;进入AT模式
LORA_AUX=0;表明模块空闲
//LoRa模块初始化
//返回值:0,检测成功,1检测失败
u8 LoRa_Init(void)
{
u8 retry=0;
u8 temp=1;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; //LORA_MD0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //LORA_AUX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource4);
EXTI_InitStructure.EXTI_Line=EXTI_Line4;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = DISABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;
NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
NVIC_Init(&NVIC_InitStructure);
LORA_MD0=0;
LORA_AUX=0;
while(LORA_AUX)
{
delay_ms(500);
delay_ms(100);
}
usart3_init(115200);
LORA_MD0=1;
delay_ms(40);
retry=3;
while(retry--)
{
if(!lora_send_cmd("AT","OK",70))
{
temp=0;
break;
}
}
if(retry==0) temp=1;
return temp;
}
参数配置
初始化后需要对LORA模块的参数进行配置,需要注意,配置参数时的波特率和校验位与实际通信是不一样的。
void LoRa_Set(void)
{
u8 sendbuf[20];
u8 lora_addrh,lora_addrl=0;
usart3_set(LORA_TTLBPS_115200,LORA_TTLPAR_8N1);
usart3_rx(1);
while(LORA_AUX);
LORA_MD0=1;
delay_ms(40);
Lora_mode=0;
lora_addrh = (LoRa_CFG.addr>>8)&0xff;
lora_addrl = LoRa_CFG.addr&0xff;
sprintf((char*)sendbuf,"AT+ADDR=%02x,%02x",lora_addrh,lora_addrl);
lora_send_cmd(sendbuf,"OK",50);
sprintf((char*)sendbuf,"AT+WLRATE=%d,%d",LoRa_CFG.chn,LoRa_CFG.wlrate);
lora_send_cmd(sendbuf,"OK",50);
sprintf((char*)sendbuf,"AT+TPOWER=%d",LoRa_CFG.power);//ÉèÖ÷¢É书ÂÊ
lora_send_cmd(sendbuf,"OK",50);
sprintf((char*)sendbuf,"AT+CWMODE=%d",LoRa_CFG.mode);
lora_send_cmd(sendbuf,"OK",50);
sprintf((char*)sendbuf,"AT+TMODE=%d",LoRa_CFG.mode_sta);//ÉèÖ÷¢ËÍ״̬
lora_send_cmd(sendbuf,"OK",50);
sprintf((char*)sendbuf,"AT+WLTIME=%d",LoRa_CFG.wltime);
lora_send_cmd(sendbuf,"OK",50);
sprintf((char*)sendbuf,"AT+UART=%d,%d",LoRa_CFG.bps,LoRa_CFG.parity);
lora_send_cmd(sendbuf,"OK",50);
LORA_MD0=0;//退出配置,进入通信
delay_ms(40);
while(LORA_AUX);//判断是否空闲
USART3_RX_STA=0;
Lora_mode=1;//标记“接收模式”
usart3_set(LoRa_CFG.bps,LoRa_CFG.parity);//返回通信,更新通信串口配置
Aux_Int(1);//设置LORA_AUX上升沿中断
}
发送数据
u8 Tran_Data[30]={0};
void LoRa_SendData(void)
{
printf((char*)Tran_Data,"Transparent");
u3_printf("%s\r\n",Tran_Data);
}
仅仅透明传输的话就会非常简单…
接收数据
void LoRa_ReceData(void)
{
u16 i=0;
u16 len=0,inter;
if(USART3_RX_STA&0x8000)
{
u16 i=0;
u16 len=0;
len = USART3_RX_STA&0X7FFF;
USART3_RX_BUF[len]=0;
USART3_RX_STA=0;
inter=atoi(USART3_RX_BUF);
if(inter==1)
{LED1=!LED1;}//这里是用来测试的,收到1时亮灯
memset((char*)USART3_RX_BUF,0x00,len);//串口接收换从区清0
}
}
AUX引脚的中断相关函数
//AUX中断配置
//mode:配置模式0:关闭 1:上升沿 2:下降沿
void Aux_Int(u8 mode)
{
if(!mode)
{
EXTI_InitStructure.EXTI_LineCmd = DISABLE;//关闭中断
NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
}else
{
if(mode==1)
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //上升沿
else if(mode==2)
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
}
Int_mode = mode;//记录中断模式
EXTI_Init(&EXTI_InitStructure);
NVIC_Init(&NVIC_InitStructure);
}
void EXTI4_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line4))
{
if(Int_mode==1)//上升沿(发送:开始发送数据,接收:数据开始输出)
{
if(Lora_mode==1)//接收模式
{
USART3_RX_STA=0;//数据计数清零
}
Int_mode=2;//设置下降沿触发
LED0=0;//DS0亮
}
else if(Int_mode==2)//下降沿
{
if(Lora_mode==1)//如果是接收模式
{
USART3_RX_STA|=1<<15;//数据计数标记完成
}else if(Lora_mode==2)//如果是发送模式
{
Lora_mode=1;//改为接收
}
Int_mode=1;//设置为上升沿触发
LED0=1;//DS0灭
}
Aux_Int(Int_mode);//重新设置中断边沿
EXTI_ClearITPendingBit(EXTI_Line4); //清除标志位
}
}
发送命令和检测命令
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;
}
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(ack&&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;
}