经过几天的努力和划水,终于在STM32F103的基础上使用ATK-LORA-01上的大部分功能,下一步就是进行LORA定位了,不过感觉还有一些自己觉得不完美的地方就是不能使用中断去选择AT模式还是通信模式,具体说就是通过按键中断,在AT模式和通信模式之间切换,遇到的技术难题是,在进入中断之后,运行中断完毕之后还会进入原来运行的地方,也就是说如果主程序在While循环中运行,中断之后,还是会进入while循环,除非在中断中找到条件使while循环跳出,但是在scanf函数重定义中有while循环,有那么一点点想法,但是现在又有其他的事情要去做,所以看看能不能下次解决这个问题!
在STM32F103的基础上使用ATK-LORA-01思绪图
代码部分
main函数中的代码不在展示,主要是各种初始化,以及LORA运行函数;
configure.h
#ifndef __CONFIGURE_H_
#define __CONFIGURE_H_
#include "stm32f1xx.h"
#include "stm32_types.h"
#include "stm32f1xx_hal.h"
#include "stdio.h"
#include "key.h"
#include "led.h"
#include "usart.h"
//*****************************************************这是一个无情的分割线************************************//
//********************************************************函数声明区*******************************************//
void LoRa_Configure_Init(void); //初始化函数
void LoRa_AT(void); //AT模式还是通信模式
void LoRa_Command(void); //AT配置模式
void LoRa_Query(void); //配置查询
void LoRa_ReQuery(void); //是否重新查询
void LoRa_Parameter(void); //配置模式
void LoRa_Manual(void); //手动配置
void LoRa_Auto(void); //自动配置
void LoRa_Reset(void); //模块复位
void LoRa_Communication(void); //通信模式
void LoRa_Send(void); //发送模式
void LoRa_Rsend(void); //查询是否重新发送
void LoRa_Receive(void); //接收模式
#endif
configure.c
这里为了思路更加清晰我分为四个部分,变量声明,主体函数,AT模式和通信模式
变量声明
//******************************************这是一个无情的分割线*******************************//
//********************************************变量声明区***************************************//
char Baud[8][10] = {"1200","2400","4800","9600","19200","38400","57600","115200"}; //波特率
#define LoRa_Baud_1200 0 //1200
#define LoRa_Baud_2400 1 //2400
#define LoRa_Band_4800 2 //4800
#define LoRa_Band_9600 3 //9600
#define LoRa_Band_19200 4 //19200
#define LoRa_Band_38400 5 //38400
#define LoRa_Band_57600 6 //57600
#define LoRa_Band_115200 7 //11200
char Test[3][10] = {"无校验","偶校验","奇校验"}; //检验位
#define LoRa_Test_wu 0 //无校验
#define LoRa_Test_ou 1 //偶校验
#define LoRa_Test_ji 2 //奇校验
char aRate[6][10] = {"0.3","1.2","2.4","4.8","9.6","19.2"}; //空中速率
#define LoRa_aRate_03 0 //0.3k
#define LoRa_aRate_12 1 //1.2k
#define LoRa_aRate_24 2 //2.4k
#define LoRa_aRate_48 3 //4.8k
#define LoRa_aRate_96 4 //9.6k
#define LoRa_aRate_192 5 //19.2k
char Sleep[2][5] = {"1","2"}; //休眠时间
#define LoRa_Sleep_1 0 //1s
#define LoRa_Sleep_2 1 //2s
char Mode[4][15] = {"一般模式","唤醒模式","省电模式","信号强度模式"}; //工作模式
#define LoRa_Mode_common 0 //一般模式
#define LoRa_Mode_rouse 1 //唤醒模式
#define LoRa_Mode_save 2 //省电模式
#define LoRa_Mode_signal 3 //信号强度模式
char eRate[4][10] = {"11","14","17","20"}; //发射功率
#define LoRa_eRate_11 0 //11dBm
#define LoRa_eRate_14 1 //14dBm
#define LoRa_eRate_17 2 //17dBm
#define LoRa_eRate_20 3 //20dBm
char State[2][12] = {"透明传输","定向传输"}; //工作状态
#define LoRa_state_tp 0 //透明传输
#define LoRa_state_dt 1 //定向传输
typedef struct
{
int baud;
int test;
int arate;
int sleep;
int addrh;
int addrl;
int channel;
int erate;
int mode;
int state;
}LORA;
LORA lora =
{
.baud = LoRa_Band_115200,
.test = LoRa_Test_wu,
.arate = LoRa_aRate_03,
.sleep = LoRa_Sleep_1,
.addrh = 0,
.addrl = 17,
.channel = 23,
.erate = 3,
.mode = 0,
.state = 0,
};
主体函数(初始化函数和选择AT模式还是通信模式)
//********************************************这是一个无情的分割线*****************************//
//***********************************************LoRa初始化函数*********************************//
int keyvalue; //按键值用来确定是AT模式还是通信模式
uint8_t LEDflag; //用来选择是AT模式还是通信模式,目的只选择一次
void LoRa_Configure_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
__GPIOA_CLK_ENABLE(); //使能GPIOA时钟
//GPIOC0/1初始化设置
GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5; //LED对应IO口PD4 PD5
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; //普通推挽输出模式
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; //高速
GPIO_InitStruct.Pull = GPIO_NOPULL; //上拉
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); //初始化GPIO
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
//LEDflag = 1;
//默认为AT模式
}
//在这里MD0为PA4 AUX为PA5
void LoRa_AT(void)
{
keyvalue = Key_read();
if(keyvalue == 1)
{
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
LEDflag = 1;
keyvalue = 0;
}
if(keyvalue == 2)
{
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
LEDflag = 2;
keyvalue = 0;
}
if((LEDflag==1)&&(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4) == 1)&&(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5) == 0))
{
printf("进入配置模式!!!\r\n\r\n");
LED_Open(1);
LED_Close(2);
LEDflag = 0;
LoRa_Command();
}
else if((LEDflag==2)&&(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4) == 0)&&(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5) == 0))
{
printf("进入通信模式!!!\r\n\r\n");
LED_Open(2);
LED_Close(1);
LEDflag = 0;
LoRa_Communication();
}
}
LoRa查询函数(配置查询,参数设置 和模块复位)
//********************************************这是一个无情的分割线*****************************//
//************************************************LoRa查询函数*********************************//
char loraquery[7][15] ={"AT+WLRATE?\r\n","AT+UART?\r\n","AT+WLTIME?\r\n","AT+TPOWER?\r\n","AT+CWMODE?\r\n","AT+TMODE?\r\n","AT+ADDR?\r\n"};
void LoRa_Command(void)
{
char order;
char oflag = 1;
printf("1、配置查询\r\n");
printf("2、参数设置\r\n");
printf("3、模块复位\r\n");
printf("4、退出AT模式\r\n\r\n");
//输入选择功能
while(oflag)
{
scanf("%c",&order);
if(order ==10 ||order ==13)
{
oflag = 1;
}
else
{
oflag = 0;
}
}
if(order != 10||order != 13)
{
getchar();
}
//三个选择功能
if(order == '1')
{
LoRa_Query();
order = '5';
}
else if(order == '2')
{
printf("进入参数设置\r\n\r\n");
LoRa_Parameter();
order = '5';
}
else if(order == '3')
{
printf("进入模块复位\r\n\r\n");
LoRa_Reset();
order = '5';
}
else if(order == '4')
{
printf("\r\n退出AT模式,请根据按键选择AT模式还是通信模式\r\n\r\n");
order = '5';
}
}
void LoRa_Query(void)
{
int i;
printf("进入配置查询......\r\n");
for(i=0;i<7;i++)
{
USART2_send(loraquery[i]);
USART2_receive();
//这里可以加入汉字说明,先省略
}
LoRa_ReQuery();
}
void LoRa_ReQuery(void)
{
char data[20];
printf("是否重新进入配置查询(yes/no)...\r\n");
scanf("%s",data);
if(strcmp(data,"YES")==0||strcmp(data,"yes")==0)
{
LoRa_Query();
}
else
{
printf("\r\n退出配置查询模式,请根据按键选择AT模式还是通信模式\r\n\r\n");
getchar();
}
}
//********************************************这是一个无情的分割线*****************************//
//************************************************LoRa配置函数*********************************//
void LoRa_Parameter(void)
{
char order2; //用来判断是手动模式还是自动模式
char oflag = 1;
printf("1、 手动配置\r\n");
printf("2、 自动配置\r\n\r\n");
printf("3、 退出配置配置\r\n\r\n");
//选择功能
while(oflag)
{
scanf("%c",&order2);
if(order2 ==10 ||order2 ==13)
{
oflag = 1;
}
else
{
oflag = 0;
}
}
if(order2 != 10||order2 != 13)
{
getchar();
}
//手动配置
if(order2 == '1')
{
LoRa_Manual();
order2 = 0;
}
//自动配置
if(order2 == '2')
{
LoRa_Auto();
order2 = 0;
}
//退出配置模式
if(order2 == '3')
{
order2 = 0;
}
}
//手动配置函数
void LoRa_Manual(void)
{
char data[20]; //用来存储指令
char order3 = '1'; //用来判断手动模式是否继续输入
printf("进入手动配置...\r\n");
while(order3 == '1')
{
printf("请输入AT指令...\r\n");
scanf("%s",data);
sprintf(data,"%s\r\n",data); //这里有个坑
USART2_send(data);
USART2_receive();
printf("是否继续输入(yes/no)...\r\n\r\n");
scanf("%s",data);
//printf("%s",data);//
if(strcmp(data,"YES")==0||strcmp(data,"yes")==0)
{
order3 = '1';
}
else
{
order3 = '0';
}
}
printf("\r\n退出手动配置,请根据按键选择是AT模式还是通信模式...\r\n\r\n");
getchar();
}
//自动配置函数
void LoRa_Auto(void)
{
int i;
char data[20];
char order4 = '1';
printf("进入自动配置...\r\n\r\n");
//*********波特率和校验位设置*****************//
while(order4 == '1') //有待优化 可以选择设置
{
printf("请输入波特率...(1200、2400、4800、9600、19200、38400、57600、115200)\r\n");
scanf("%s",data);
printf("%s\r\n\r\n",data);
for(i=0;i<8;i++)
{
if(strcmp(data,Baud[i])==0)
{
lora.baud = i;
break;
}
}
if(i<8)
{
}
else
{
goto CuoWu;
}
printf("请输入校验位(无校验/奇校验/偶校验)...\r\n");
scanf("%s",data);
printf("%s\r\n\r\n",data);
for(i=0;i<3;i++)
{
if(strcmp(data,Test[i])==0)
{
lora.test = i;
break;
}
}
if(i<3)
{
sprintf(data,"AT+UART=%d,%d\r\n",lora.baud,lora.test);
USART2_send(data);
USART2_receive();
order4 = '0';
printf("\r\n退出波特率和校验位配置,请根据按键选择是AT模式还是通信模式...\r\n\r\n");
}
else
{
CuoWu: printf("输入格式错误,是否重新输入....\r\n");
scanf("%s",data);
if(strcmp(data,"YES")==0||strcmp(data,"yes")==0)
{
order4 = '1';
}
else
{
order4 = '0';
printf("\r\n退出波特率和校验位配置,请根据按键选择是AT模式还是通信模式...\r\n\r\n");
}
}
}
//*********信道和空中速率设置*****************//
order4 = '1';
while(order4 == '1')
{
printf("请输入信道(0-31)...\r\n");
scanf("%d",&lora.channel);
printf("%d\r\n\r\n",lora.channel);
printf("请输入空中速率(0.3、1.2、2.4、4.8、9.6、19.2)K...\r\n");
scanf("%s",data);
printf("%s\r\n\r\n",data);
for(i=0;i<6;i++)
{
if(strcmp(data,aRate[i])==0)
{
lora.arate = i;
break;
}
}
if(i<6)
{
sprintf(data,"AT+WLRATE=%d,%d\r\n",lora.channel,lora.arate);
USART2_send(data);
USART2_receive();
order4 = '0';
printf("\r\n退出信道和空中速率配置,请根据按键选择是AT模式还是通信模式...\r\n\r\n");
}
else
{
printf("输入格式错误,是否重新输入....\r\n");
scanf("%s",data);
if(strcmp(data,"YES")==0||strcmp(data,"yes")==0)
{
order4 = '1';
}
else
{
order4 = '0';
printf("\r\n退出信道和空中速率配置,请根据按键选择是AT模式还是通信模式...\r\n\r\n");
}
}
}
// //**************休眠时间设置*****************//
order4 = '1';
while(order4 == '1')
{
printf("请输入休眠时间(1、2)s...\r\n");
scanf("%s",data);
printf("%s\r\n\r\n",data);
for(i=0;i<3;i++)
{
if(strcmp(data,Sleep[i])==0)
{
lora.sleep = i;
break;
}
}
if(i<3)
{
sprintf(data,"AT+WLTIME=%d\r\n",lora.sleep);
USART2_send(data);
USART2_receive();
order4 = '0';
printf("\r\n退出休眠时间配置,请根据按键选择是AT模式还是通信模式...\r\n\r\n");
}
else
{
printf("输入格式错误,是否重新输入....\r\n");
scanf("%s",data);
if(strcmp(data,"YES")==0||strcmp(data,"yes")==0)
{
order4 = '1';
}
else
{
order4 = '0';
printf("\r\n退出休眠时间配置,请根据按键选择是AT模式还是通信模式...\r\n\r\n");
}
}
}
//**************模块地址设置*****************//
printf("请输入模块地址(FF,00)...\r\n");
scanf("%s",data);
printf("%s\r\n\r\n",data);
sprintf(data,"AT+ADDR=%c%c,%c%c\r\n",data[0],data[1],data[3],data[4]);
USART2_send(data);
USART2_receive();
order4 = '1';
//
// //**************发射功率配置*****************//
while(order4 == '1')
{
printf("请输入发射功率(11,14,17,20)dbm...\r\n");
scanf("%s",data);
printf("%s\r\n\r\n",data);
for(i=0;i<4;i++)
{
if(strcmp(data,eRate[i])==0)
{
lora.erate = i;
break;
}
}
if(i<4)
{
sprintf(data,"AT+TPOWER=%d\r\n",lora.erate);
USART2_send(data);
USART2_receive();
order4 = '0';
printf("\r\n退出发射功率配置,请根据按键选择是AT模式还是通信模式...\r\n\r\n");
}
else
{
printf("输入格式错误,是否重新输入....\r\n");
scanf("%s",data);
if(strcmp(data,"YES")==0||strcmp(data,"yes")==0)
{
order4 = '1';
}
else
{
order4 = '0';
printf("\r\n退出发射功率配置,请根据按键选择是AT模式还是通信模式...\r\n\r\n");
}
}
}
// //*************工作模式设置*****************//
order4 = '1';
while(order4 == '1')
{
printf("请输入工作模式...(一般模式、唤醒模式、省电模式、信号强度模式)\r\n");
scanf("%s",data);
printf("%s\r\n\r\n",data);
for(i=0;i<4;i++)
{
if(strcmp(data,Mode[i])==0)
{
lora.mode = i;
break;
}
}
if(i<4)
{
sprintf(data,"AT+CWMODE=%d\r\n",lora.mode);
USART2_send(data);
USART2_receive();
order4 = '0';
}
else
{
printf("输入格式错误,是否重新输入....\r\n");
scanf("%s",data);
if(strcmp(data,"YES")==0||strcmp(data,"yes")==0)
{
order4 = '1';
}
else
{
order4 = '0';
printf("\r\n退出发射功率配置,请根据按键选择是AT模式还是通信模式...\r\n\r\n");
}
}
}
// //*************发送状态设置*****************//
order4 = '1';
while(order4 == '1')
{
printf("请输入发送状态...(透明传输、定向传输)\r\n");
scanf("%s",data);
printf("%s\r\n\r\n",data);
for(i=0;i<2;i++)
{
if(strcmp(data,State[i])==0)
{
lora.state = i;
break;
}
}
if(i<2)
{
sprintf(data,"AT+CWMODE=%d\r\n",lora.state);
USART2_send(data);
USART2_receive();
order4 = '0';
printf("\r\n退出发射功率配置,请根据按键选择是AT模式还是通信模式...\r\n\r\n");
}
else
{
printf("输入格式错误,是否重新输入....\r\n");
scanf("%s",data);
if(strcmp(data,"YES")==0||strcmp(data,"yes")==0)
{
order4 = '1';
}
else
{
order4 = '0';
printf("\r\n退出发射功率配置,请根据按键选择是AT模式还是通信模式...\r\n\r\n");
}
}
}
}
//********************************************这是一个无情的分割线*****************************//
//************************************************LoRa模块复位*********************************//
void LoRa_Reset(void)
{
char data[20];
sprintf(data,"AT+RESET\r\n");
USART2_send(data);
USART2_receive();
printf("模块复位完成!!!\r\n");
printf("\r\n退出模块复位配置,请根据按键选择是AT模式还是通信模式...\r\n\r\n");
}
LoRa通信模块(接收模式,发送模式)
void LoRa_Communication(void)
{
char order;
char oflag = 1;
printf("1、发送模式\r\n");
printf("2、接收模式\r\n");
printf("3、退出通信模式\r\n\r\n");
//输入选择功能
while(oflag)
{
scanf("%c",&order);
if(order ==10 ||order ==13)
{
oflag = 1;
}
else
{
oflag = 0;
}
}
if(order != 10||order != 13)
{
getchar();
}
//三个选择功能
if(order == '1')
{
LoRa_Send();
order = '5';
}
else if(order == '2')
{
LoRa_Receive();
order = '5';
}
else if(order == '3')
{
printf("\r\n退出通信模式,请根据按键选择AT模式还是通信模式\r\n\r\n");
order = '5';
}
}
//********************************************这是一个无情的分割线*****************************//
//************************************************LoRa发送模式*********************************//
void LoRa_Send(void)
{
char *p = NULL;
char data[100];
printf("进入发送模式...\r\n");
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
delay_ms(10);
sprintf(data,"AT+TMODE?\r\n");
USART2_send(data);
USART2_receive();
p = USART2_Receive();
printf("发送状态是: %s\r\n\r\n",State[p[18]-'0']);
while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4) != 0&&HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4) != 0)
{
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
}
if((p[18]-'0') == 0)
{
printf("请输入要发送的数据...\r\n\r\n");
scanf("%s",data);
}
else
{
printf("请输入要发送的数据(高位地址+低位地址+信道+用户数据)...\r\n");
scanf("%s",data);
}
delay_ms(10);
printf("%s\r\n",data);
sprintf(data,"%s\r\n",data);
USART2_send(data);
delay_ms(10);
USART2_receive();
getchar();
LoRa_Rsend();
}
void LoRa_Rsend(void)
{
char data[10];
printf("\r\n是否重新进入发送模式(yes/no)...\r\n");
scanf("%s",data);
if(strcmp(data,"YES")==0||strcmp(data,"yes")==0)
{
LoRa_Send();
}
else
{
printf("\r\n退出发送模式,请根据按键选择AT模式还是通信模式\r\n\r\n");
getchar();
}
}
//********************************************这是一个无情的分割线*****************************//
//************************************************LoRa接收*********************************//
void LoRa_Receive(void)
{
int rflag = 1;
printf("进入接收模式...\r\n");
printf("可以根据按键3退出接收模式\r\n\r\n");
while(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4) != 0&&HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4) != 0)
{
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
}
while(rflag == 1)
{
keyvalue = Key_read();
USART2_receive();
if(keyvalue == 3)
{
rflag = 0;
printf("\r\n退出接收模式,请根据按键选择AT模式还是通信模式\r\n\r\n");
}
}
}