stm32f407使用无线串口E32型号LORA

目录

  1. LORA   E32模块

  2. 代码(自己对着之前第一次做无线通信的正点原子程序改的,自己找没找到这款,就想着发出来,大家借鉴着使用)

  3. 数据处理(这里是做了一个简陋的无人机PWM输出遥控器


    (自己做的随手用的,欢迎大家批评指正,还有,不要一直发送数据,,会很烫,写个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测量值,不懂留言。

(我也不知道,一起等大神)

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值