目录
-
(自己做的随手用的,欢迎大家批评指正,还有,不要一直发送数据,,会很烫,写个t++的缓冲程序)
1,LORA模块
随手拍的,这一款反正我淘宝没搜到,
M0 GPIOX PINX(随便设)
M1 GPIOX PINX(随便设)
原文用来设置格式的;
RXD A0
TXD A1
(串口通信,用的串口四)
为了防止我一会不想写了就不出串口代码,提前放出来;
void uart4_init(u32 pclk2,u32 bound)
{
float temp;
u16 mantissa;
u16 fraction;
temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV@OVER8=0
mantissa=temp; //得到整数部分
fraction=(temp-mantissa)*16; //得到小数部分@OVER8=0
mantissa<<=4;
mantissa+=fraction;
RCC->AHB1ENR|=1<<0; //使能PORTC口时钟
RCC->APB1ENR|=1<<19; //使能串口4时钟
GPIO_Set(GPIOA,PIN0|PIN1,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_50M,GPIO_PUPD_PU);
GPIO_AF_Set(GPIOA,0,8);
GPIO_AF_Set(GPIOA,1,8);
UART4->BRR=mantissa; //波特率设置
//UART4->CR1&=~(1<<15); //设置OVER8=0
UART4->CR1|=1<<3; //串口发送使能
//使能接收中断
UART4->CR1|=1<<2; //串口接收使能
UART4->CR1|=1<<5; //接收缓冲区非空中断使能
MY_NVIC_Init(3,3,UART4_IRQn,3);//组2,最低优先级
UART4->CR1|=1<<13; //串口使能
TIM7_Int_Init(100-1,8400-1); //10ms中断一次
TIM7->CR1&=~(1<<0); //关闭定时器7
UART4_RX_STA=0; //清零
}
//串口接收使能控制
//enable:0,关闭 1,打开
void uart4_rx(u8 enable)
{
UART4->CR1 &= ~(0x2000);//关闭串口
if(enable)
{
UART4->CR1|=(1<<3)|(1<<2);//发送和接收
}else
{
UART4->CR1&=~(1<<2);//关闭接收
UART4->CR1|=(1<<3);//打开发送
}
UART4->CR1 |= 0x2000;//使能串口
}
void UART4_IRQHandler(void)
{
u8 res;
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntEnter();
#endif
if(UART4->SR&(1<<5))//接收到数据
{
res=UART4->DR;
if((UART4_RX_STA&(1<<15))==0)//接收完的一批数据,还没有被处理,则不再接收其他数据
{
if(UART4_RX_STA<UART4_MAX_RECV_LEN) //还可以接收数据
{
if(!Lora_mode)//配置模式下(启动定时器超时)
{
TIM7->CNT=0; //计数器清空
if(UART4_RX_STA==0) //使能定时器7的中断
{
TIM7->CR1|=1<<0; //使能定时器7
}
}
UART4_RX_BUF[UART4_RX_STA++]=res; //记录接收到的值
}else
{
UART4_RX_STA|=1<<15; //强制标记接收完成
}
}
}
}
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntExit();
#endif
//串口3波特率和校验位配置
//bps:波特率(1200~115200)
//parity:校验位(无、偶、奇)
void uart4_set(u8 bps,u8 parity)
{
float temp;
u16 mantissa;
u16 fraction;
static u32 bound=0;
switch(bps)
{
case LORA_TTLBPS_1200: bound=1200; break;
case LORA_TTLBPS_2400: bound=2400; break;
case LORA_TTLBPS_4800: bound=4800; break;
case LORA_TTLBPS_9600: bound=9600; break;
case LORA_TTLBPS_19200: bound=19200; break;
case LORA_TTLBPS_38400: bound=38400; break;
case LORA_TTLBPS_57600: bound=57600; break;
case LORA_TTLBPS_115200: bound=115200; break;
}
UART4->CR1 &= ~(0x2000);//关闭串口
temp=(float)(42*1000000)/(bound*16);//得到USARTDIV,OVER8设置为0
mantissa=temp; //得到整数部分
fraction=(temp-mantissa)*16; //得到小数部分,OVER8设置为0
mantissa<<=4;
mantissa+=fraction;
UART4->BRR= mantissa ;// 波特率设置
UART4->CR1|=0X200C; //1位停止,无校验位.
if(parity==LORA_TTLPAR_8N1)//无校验
{
UART4->CR1&=~(1<<12);//8位数据位
UART4->CR1&=~(1<<10);//禁止校验控制
UART4->CR1&=~(1<<9);
}else if(parity==LORA_TTLPAR_8E1)//偶校验
{
UART4->CR1|=(1<<12);//9位数据位
UART4->CR1|=(1<<10);//校验控制使能
UART4->CR1&=~(1<<9);//偶校验
}else if(parity==LORA_TTLPAR_8O1)//奇校验
{
UART4->CR1|=(1<<12);//9位数据位
UART4->CR1|=(1<<10);//校验控制使能
UART4->CR1|=(1<<9);//奇校验
}
UART4->CR1 |= 0x2000;//使能串口
}
(新手注意,这个代码复制放usart.c文件).h懒得写了、
AUX 连接D6改成输入
VCC 5V;
GND GND;
2,代码
lora.c
#include "lora.h"
#include "lora_ui.h"
#include "lora_cfg.h"
#include "usart.h"
#include "string.h"
#include "led.h"
#include "delay.h"
#include "key.h"
#include "exti.h"
#include "adc.h"
//设备参数初始化(具体设备参数见lora_cfg.h定义)
_LoRa_CFG LoRa_CFG=
{
.addr = LORA_ADDR, //设备地址
.power = LORA_POWER, //发射功率
.chn = LORA_CHN, //信道
.wlrate = LORA_RATE, //空中速率
.wltime = LORA_WLTIME, //睡眠时间
.mode = LORA_MODE, //工作模式
.mode_sta = LORA_STA, //发送状态
.bps = LORA_TTLBPS , //波特率设置
.parity = LORA_TTLPAR //校验位设置
};
//设备工作模式(用于记录设备状态)
u8 Lora_mode=0;// 0:配置模式 1:接收模式 2:发送模式
//记录中断状态
static u8 Int_mode=0;//0:关闭 1:上升沿 2:下降沿
全局参数
//EXTI_InitTypeDef EXTI_InitStructure;
//NVIC_InitTypeDef NVIC_InitStructure;
void Aux_Int(u8 mode)
{
if(!mode)
{
EXTI->IMR &=~(1<<6);//关闭
NVIC->ICER[EXTI9_5_IRQn >> 0x05] =
(uint32_t)0x01 << (EXTI9_5_IRQn & (uint8_t)0x1F);
}else
{
if(mode==1)
{
EXTI->RTSR|=1<<6; //line6上事件上升降沿触发
}
else if(mode==2)
{
EXTI->FTSR|=1<<6; //line6上事件下降沿触发
}
EXTI->IMR |=(1<<6);//打开
NVIC->ISER[EXTI9_5_IRQn >> 0x05] =
(uint32_t)0x01 << (EXTI9_5_IRQn & (uint8_t)0x1F);
}
Int_mode = mode;//记录中断模式
}
//LORA_AUX中断
void EXTI9_5_IRQHandler(void)
{
if(EXTI->PR & (1<<6))
{
if(Int_mode==1)//上升沿(发送:开始发送数据 接收:数据开始输出)
{
if(Lora_mode==1)//接收模式
{
UART4_RX_STA=0;//数据计数清0
}
Int_mode=2;//设置下降沿
LED0=0;//DS0亮
}
else if(Int_mode==2)//下降沿(发送:数据已发送完 接收:数据输出结束)
{
if(Lora_mode==1)//接收模式
{
UART4_RX_STA|=1<<15;//数据计数标记完成
}else if(Lora_mode==2)//发送模式(串口数据发送完毕)
{
Lora_mode=1;//进入接收模式
}
Int_mode=1;//设置上升沿
LED0=1;//DS0灭
}
Aux_Int(Int_mode);//重新设置中断边沿
EXTI->PR=1<<6; //清除LINE4上的中断标志位
}
}
//LoRa模块初始化
//返回值:0,检测成功
// 1,检测失败
u8 LoRa_Init()
{
u8 retry=0;
u8 temp=1;
RCC->AHB1ENR|=1<<3; //使能PORTD口时钟 M0D4 M1D5
GPIO_Set(GPIOD,PIN4|PIN5,GPIO_MODE_OUT,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PD);
GPIO_Set(GPIOD,PIN6,GPIO_MODE_IN,0,GPIO_SPEED_100M,GPIO_PUPD_PD); //AUX
Ex_NVIC_Config(GPIO_D,6,RTIR); //上升沿触发
MY_NVIC_Init(0,2,EXTI9_5_IRQn,2); //抢占3,子优先级2,组2
EXTI->IMR &=~(1<<6);
NVIC->ICER[EXTI9_5_IRQn >> 0x05] =
(uint32_t)0x01 << (EXTI9_5_IRQn & (uint8_t)0x1F);
LORA_MD0 =0;
LORA_AUX =0;
// while(LORA_AUX)//确保LORA模块在空闲状态下(LORA_AUX=0)
// {
// uart_flag=2;
// printf("模块正忙,请稍等!!\r\n");
// delay_ms(500);
// delay_ms(100);
// }
uart_flag=2;
printf("模块成了!!\r\n");
uart4_init(42,9600);//初始化串口4
LORA_MD0=1;//进入AT模 需要写一个配置函数,但不在这里,往后面的配置处
delay_ms(40);
retry=3;
while(retry--)
{
// if(!lora_send_cmd("AT","OK",70)) 还需要改
{
temp=0;//检测成功
break;
}
}
if(retry==0) temp=1;//检测失败
return temp;
}
void MODE(u8 mad)
{
if(mad==0) //透明
{
LORA_MD0=0;
LORA_MD1=0;
}
if(mad==1) //唤醒
{
LORA_MD0=1;
LORA_MD1=0;
}
if(mad==2) //省电
{
LORA_MD0=0;
LORA_MD1=1;
}
if(mad==3) //休眠
{
LORA_MD0=1;
LORA_MD1=1;
}
}
Lora模块参数配置
void LoRa_Set(void)
{
u8 sendbuf[20];
u8 lora_addrh,lora_addrl=0;
uart4_set(LORA_TTLBPS_115200,LORA_TTLPAR_8N1);//进入配置模式前设置通信波特率和校验位(115200 8位数据 1位停止 无数据校验)
uart4_rx(1);//开启串口3接收
//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;
LoRa_CFG.chn=31; //信道31
LoRa_CFG.wlrate=LORA_RATE_2K4; //2.4g
LoRa_CFG.power=LORA_PW_14Bbm; //14dbm 1
MODE(0);
LoRa_CFG.mode=LORA_MODE_GEN;
LoRa_CFG.mode_sta=LORA_STA_Tran; //透明发送
LoRa_CFG.wltime=LORA_WLTIME_2S; //休眠2s
LoRa_CFG.bps=LORA_TTLBPS_9600; //9600
LoRa_CFG.parity=LORA_TTLPAR_8N1; //无奇偶校验
LORA_MD0=0;//退出配置,进入通信
delay_ms(40);
//while(LORA_AUX);//判断是否空闲(模块会重新配置参数)
UART4_RX_STA=0;
Lora_mode=1;//标记"接收模式"
uart4_set(LoRa_CFG.bps,LoRa_CFG.parity);//返回通信,更新通信串口配置(波特率、数据校验位)
Aux_Int(1);//设置LORA_AUX上升沿中断
}
u8 Dire_Date[]={0x11,0x22,0x33,0x44,0x55};//定向传输数据
u8 date[30]={0};//定向数组
u8 Tran_Data[30]={0xff};//透传数组
#define Dire_DateLen sizeof(Dire_Date)/sizeof(Dire_Date[0])
extern u32 obj_addr;//记录用户输入目标地址
extern u8 obj_chn;//记录用户输入目标信道
//u8 wlcd_buff[10]={0}; //LCD显示字符串缓冲区
Lora模块发送数据
void LoRa_SendData(void)
{
static u8 num=0;
u16 addr;
u8 chn;
u16 i=0;
if(LoRa_CFG.mode_sta == LORA_STA_Tran)//透明传输
{
Get_Adc_Average(5,20);
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数组
// printf((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]);
// printf("wlcd_buff");//显示发送的数据
Dire_Date[4]++;//Dire_Date[4]数据更新
}
}
void LoRa_ReceData(void)
{
u16 i=0;
u16 len=0;
//有数据来了
if(UART4_RX_STA&0x8000)
{
len = UART4_RX_STA&0X7FFF;
UART4_RX_BUF[len]=0;//添加结束符
UART4_RX_STA=0;
for(i=0;i<len;i++)
{
while((USART2->SR&0X40)==0);//循环发送,直到发送完毕
USART2->DR=UART4_RX_BUF[i];
}
if(LoRa_CFG.mode_sta==LORA_STA_Tran)//透明传输
{
// uart_flag=2;
// printf ("%d\r\n",*UART4_RX_BUF);//显示接收到的数据
}else if(LoRa_CFG.mode_sta==LORA_STA_Dire)//定向传输
{
printf("接收出错,恭喜你,又他妈白干了");
// //将十六进制的数据转化为字符串打印在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*)UART4_RX_BUF,0x00,len);//串口接收缓冲区清0
}
}
//发送和接收处理
void LoRa_Process(void)
{
u8 key=0;
u8 t=0;
// DATA:
// Process_ui();//界面显示
LoRa_Set();//LoRa配置(进入配置需设置串口波特率为115200,)
while(1)
{
key = KEY_Scan(0);
if(key==KEY1_PRES)
{
//if(!LORA_AUX&&(LoRa_CFG.mode!=LORA_MODE_SLEEP))//空闲且非省电模式
// {
//Lora_mode=2;//标记"发送状态"
LoRa_SendData();//发送数据
//}
}
t++;
if(t==20)
{
t=0;
LED1=~LED1;
}
delay_ms(10);
}
}
//主测试函数
void Lora_Test(void)
{
u8 t=0;
u8 key=0;
u8 netpro=0;
while(LoRa_Init())//初始化ATK-LORA-01模块
{
printf ("未检测到模块!!!");
delay_ms(300);
}
printf("检测到模块!!!");
delay_ms(500);
//Menu_ui();//菜单
while(1)
{
// if(netpro==0)//进入通信选项
// {
LoRa_Process();//开始数据测试
netpro=0;//索引返回第0
// Menu_ui();
// Show_Str(30+40,95+45+netpro*25+2,200,16,"________",16,1);//显示下划线,表示选中
// Show_Str(30+10,95+45+netpro*25,200,16,"→",16,0);//指向新条目
//Menu_cfg(netpro);//参数配置
printf("→");//指向新条目
}
t++;
if(t==30)
{
t=0;
LED1=~LED1;
}
delay_ms(10);
}
lora.h
#ifndef _LORA_H_
#define _LORA_H_
#include "sys.h"
#include "lora_cfg.h"
//
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F407开发板
//ATK-LORA-01模块功能驱动
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2016/4/1
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved
//********************************************************************************
//无
#define LORA_AUX PDin(6) //LORA模块状态引脚
#define LORA_MD0 PDout(4) //LORA模块控制引脚
#define LORA_MD1 PDout(5) //LORA模块控制引脚
extern _LoRa_CFG LoRa_CFG;
extern u8 Lora_mode;
u8 LoRa_Init();
void LoRa_Set(void);
void LoRa_SendData(void);
void LoRa_ReceData(void);
void LoRa_Process(void);
void Lora_Test(void);
#endif
(我申明啊,我魔改的,,原来要用上位机或者LCD屏触摸的,,我穷,没有,乱改,,不过能使,我代码注释了的,,可以删除,别用,后果自负,还有这是发送端,,接收端有人要留言我就再写,主要是因为本人懒)
3,数据处理
。。好吧,还是涉及接收,上代码
void LoRa_ReceData(void)
{
int vall=1003;
u16 i=0;
u16 len=0;
int que;
char one;
char two ;
char three;
int first;
int twice;
int thired;
int fouth;
//有数据来了
if(UART4_RX_STA&0x8000)
{
char sed[24];
char caw;
len = UART4_RX_STA&0X3fff;
UART4_RX_STA=0;
for(i=0;i<len;i++)
{
while((USART2->SR&0X80)==0);//循环发送,直到发送完毕
USART2->DR=UART4_RX_BUF[i];
}
if(LoRa_CFG.mode_sta==LORA_STA_Tran)//透明传输
{
uart_flag=2;
caw =UART4_RX_BUF[4];
que =caw;
one=UART4_RX_BUF[1];
two=UART4_RX_BUF[2];
three=UART4_RX_BUF[3];
first =atoi (&one);
twice =atoi (&two);
thired =atoi (&three );
fouth =atoi (&caw );
if(que==46)
{
vall=((first*100)+(twice*10)+(thired*1));
}
else
{
vall=((first*1000)+(twice*100)+(thired *10)+(fouth*1));
}
motorA_PWM_VALL=vall ;
printf("%d\r\n",vall );
printf ( "%d", first );
}else if(LoRa_CFG.mode_sta==LORA_STA_Dire)//定向传输
{
printf("接收出错,恭喜你,又他妈白干了");
}
memset((char*)UART4_RX_BUF,0x00,len);//串口接收缓冲区清0
}
}
其他一样,这里我用了强制转化
int atoi(const char *str);
细节上,发送端发送的是我的ADC测量值,不懂留言。
(我也不知道,一起等大神)