基于STM32的正点原子LORA模块通信网络

LoRa是semtech公司开发的一种低功耗局域网无线标准,其名称“LoRa”是远距离无线电(Long Range Radio),它最大特点就是在同样的功耗条件下比其他无线方式传播的距离更远,实现了低功耗和远距离的统一,它在同样的功耗下比传统的无线射频通信距离扩大3-5倍。 距离往往可达10公里左右。
笔者在做基于无线通信的火灾网络报警系统时,了解到LORA这一优越的通信方式,想着可以直接拿市面上的来用。没想到在网上购买到了正点原子的实物和代码后发现。正点原子的代码是和其开发板高度绑定的,没有现成的自发自收的LORA代码。
正点原子的LORA模块
于是想着所谓LORA通信也只是串口通信的一种,而且正点原子的LORA模块已经将其与射频芯片等封装好,并且提供了对应的上位机软件。
所以我要做的只是把STM32的串口部分完成即可。
自发自收:2个STM32最小系统板 ,2个LORA模块,2个LORA模块的上位机软件,1个串口通信的上位机软件 2个OLED显示屏(用于显示接收的数据)
通过串口通信上位机将信息由串口1发送给STM32芯片,芯片(可对其处理后)转发给串口3。串口3连着的LORA模块收到信息后发出。这里可以选择透明传输或者定向传输。透明传输是发送给所有其他的LORA模块,而定向传输是发送给指定的LORA模块,其他的LORA模块收到后不作理会。为了区分LORA模块,在使用之前需要对每个LORA模块做 模块基本参数配置。如下图中间所示。
LORA模块对应的上位机界面
传输模式
这里重点讲解一下定向传输:
先将2个LORA模块都配置为定向传输模式,分配其相应的地址,信道等数据。将2个LORA模块的数据都存储到STM32中,最好是外接一个EEPROM,将数据记录在EEPROM中,每次启动STM32,只要将原来的数据从EERPOM中读取一遍就可以了。
如果需要外扩成网络状,如成百上千个网络节点,则需要在EEPROM中记录其相邻的LORA模块节点的数据,如地址。

程序思路:
1.打开串口通信软件界面,将数据通过数据包的形式发送给STM32最小系统板的串口1。数据包应当采取的格式为:目的地址+数据
2.串口1收到后,先根据EEPROM中的网络节点联系表,查出如果要传出给目的地址,则需要传输的下一地址。然后加上自身的地址,以便于数据返回给自身。
数据包的格式应当为:下一地址高位+下一地址低位+信道+目的地址高位+目的地址低位+源地址高位+源地址低位+数据
3.串口3发送此数据包

4.下一地址的LORA模块收到后,将数据通过串口3发给其STM32最小系统板。STM32芯片先比对目的地址与自身地址是否相同,若相同对其进行处理,通过串口3发回给源地址。并将目的地址与源地址进行调换。若不匹配,则重复上述步骤直到发给目的地址。

5.原LORA模块收到后,将数据包去掉目的地址,源地址,信道等数据,发送给串口1。于是串口1就会收到此数据。

串口通信软件
温馨提示:这里数据包内部数据设计应当包含2个方面。
1.需要设定问答标志位。如果不设定,那么目的地址收到数据后就可能发给自身的串口1了,而不是发回给串口3。
2.数据的格式应当采取:命令+数据或者 命令
如命令号01 表示删除 ,命令号02表示修改某数据
则 命令号02+数据03 表示 将对应数据改为03

基于LORA的通信网络还应该开发一个上位机软件,此上位机软件应当实现增删改查以下信息。
此节点可以通信的网络节点,参考计算机网络。应当有上级节点,同级节点,下级节点,每个节点的级别。并且有地址类似于子网的概念。每个节点有对应的下属地址范围,下级极点不能超过此地址范围。这样的话,每次转发地址,只需要先查看是否在自身地址范围内,如果在的话,看是哪个下级节点。如果没有则查看同级节点,都没有的话,就转发给上级节点。
如果增删改查需要双方都进行修改,应当先以数据包的形式发送给那个节点,通过逻辑判断是否可行,如果可行,那个节点先修改自身。再将可以修改的信息发给源节点。如果不行的话,也应当指明原因。就像访问网页失败,只要返回个404,访问者就会知道无法找到此网页。

附件是我完成的基于LORA模块的无线火灾网络报警系统。可以实现网络中任意2个节点的通信。不过由于工作原因,关于上一自然段提到的软件一直没有时间去弄。不过完成简单的自收自发是没有问题的。有需要的可以私信我,我看到后会尽快回复。

#ifndef  __AT24C02_H
#define  __AT24C02_H
#include "stm32f10x.h"
 
 
#define AT24C02_I2Cx I2C1    //AT24C02???iic??
#define AT24C02_ADDR  0xA0   //????
 
extern void AT24C02_Init(void); //???
extern uint8_t AT24C02_ReadOneByte(uint8_t ReadAddr);	//??????????
extern void AT24C02_WriteOneByte(uint8_t WriteAddr,uint8_t DataToWrite);	//??????????
extern void AT24C02_Write(uint8_t WriteAddr,uint8_t *Buffer,uint16_t Num);	//????????????????
extern void AT24C02_Read(uint8_t ReadAddr,uint8_t *Buffer,uint16_t Num);   	//????????????????

extern void AT24C02_WriteTwoByte(uint8_t WriteAddr, uint16_t DataToWrite);
extern uint16_t AT24C02_ReadTwoByte(uint8_t ReadAddr);
 
#endif
#ifndef __NODE_H
#define __NODE_H


struct NODE {
	unsigned int father_ip;    //´æ´¢Æ丸½ÚµãµÄIPµØÖ·   E2PROM µØÖ· 0X00 0X01
	unsigned int father_range[2];  //¸¸½ÚµãµÄµØÖ··¶Î§               0X10 0X11  0X12 0X13
	unsigned int mate_ip[2];       //ͬʽڵãµÄµØÖ·                 0X20 0X21  0X22 0X23
	unsigned int mate_range[2][2];    //ͬʽڵãµÄµØÖ··¶Î§             0X30 0X31  0X32 0X33   0x34 0x35 0x36 0x37
	unsigned int ip;               //×Ô¼ºµÄµØÖ·                     0X40 0X41
	unsigned int range[2];         //×Ô¼ºµÄµØÖ··¶Î§                 0X50 0X51  0X52 0X53
	unsigned int not_use_ip;       //×Ô¼ºµØÖ··¶Î§ÖÐδÆôÓõijõʼµØÖ· 0X60 0X61
	unsigned int depth;				//×Ô¼ºµÄÉî¶È                          0X70 0X71
	unsigned int block_no;    //ÎïÀíµØÖ·Â¥¶°ºÅ   15                 0X80 0X81
	unsigned int house_no;    //ÎïÀíµØÖ·ÃÅÅƺŠ  Èç102 203          0X90 0X91
	unsigned int son_ip[4];        //×Ó½ÚµãµÄµØÖ·                   0XA0 0XA1   0XA2 0XA3    0XA4 0xA5 0xA6 0XA7  0xA8 0XA9
	unsigned int son_range[4][2];   //×Ó½ÚµãµÄµØÖ··¶Î§	            0xB0 0XB1   0xB2 0XB3
	                                  //                              0xB4 0Xb5   0xb6 0xb7
	                                 //                               0xB8 0Xb9   0xBA 0XBB
	                                  //                              0XBC 0XBD   0XBE 0XBF
	//µ±Ö÷»úÏò×ӽڵ㴫ÊäÊý¾ÝµÄʱºò£¬ÓÅÏÈÑ¡ÔñÆä×ÔÉíÖ±½Ó°üº¬µÄ£¬Æä´ÎÑ¡Ôñ°üº¬Í¬Ê½ڵã¼ä½Ó´«´ïµÄ
};

#define Node_packet_length 12    //´®¿Ú3µÄÊý¾Ý°ü³¤¶È×Ϊ10¸ö£¬¼ÓÉÏÏÂÒ»¸öµØÖ·2¸öÔòΪ12¸ö

extern struct NODE mynode;

extern uint8_t NODE_Packet[Node_packet_length];

extern uint32_t  search(unsigned char command);

extern uint16_t execute(unsigned char command);

extern unsigned char IS_Current_addr(uint16_t addr);

extern uint16_t  Next_addr(uint16_t addr);

extern void Serial1_3_RxPacket_to_NODE_TXPacket(uint8_t packet[]);

extern uint8_t* deal_center(uint8_t packet[]);

extern void NODE_init();

extern uint8_t* deal_all_data();

extern uint8_t NODE_Packet[Node_packet_length];

extern uint8_t all_data_packet[20][4];

#endif
#ifndef __SERIAL_H
#define __SERIAL_H

#include <stdio.h>

extern uint8_t Serial_TxPacket[];
extern uint8_t Serial_RxPacket[];

void Serial_Init(void);
void Serial_SendByte(uint8_t Byte);
void Serial_SendArray(uint8_t *Array, uint16_t Length);
void Serial_SendString(char *String);
void Serial_SendNumber(uint32_t Number, uint8_t Length);

void Serial_SendPacket(void);
uint8_t Serial_GetRxFlag(void);
void Clear_Serial_RxPacket();
void Serial_RxPacket_to_Serial3_TxPacket();
void Serial_RxPacket_to_Serial_TxPacket();

#endif

#ifndef __I2C_H 
#define __I2C_H
#include "stm32f10x.h"
 
#define IIC_NO_ACK  1
#define IIC_ACK     0
 
#define SCL_CLR()   GPIOB->BRR = GPIO_Pin_12
#define SCL_SET()   GPIOB->BSRR = GPIO_Pin_12
#define SDA_CLR()   GPIOB->BRR  = GPIO_Pin_13
#define SDA_SET()   GPIOB->BSRR  = GPIO_Pin_13
#define SCL_READ()  GPIOB->IDR  & GPIO_Pin_12
#define SDA_READ()  GPIOB->IDR  & GPIO_Pin_13
 
/*SCL???*/
#define AT24C02_SCL_PIN  GPIO_Pin_4
#define AT24C02_SCL_PORT GPIOC
#define AR24C02_SCL_CLK  RCC_APB2Periph_GPIOC
 
/*SDA???*/
#define AT24C02_SCL_PIN  GPIO_Pin_4
#define AT24C02_SCL_PORT GPIOC
#define AR24C02_SCL_CLK  RCC_APB2Periph_GPIOC
 
void I2C_Configuration(void);
extern void I2C_Start(void); //??????
extern void I2C_Stop(void);  //??????
extern void I2C_Send_Byte(uint8_t sebyte); // I2C??????? 
extern uint8_t I2C_Recieve_Byte(void);   // I2C???????
#endif
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Serial.h"
#include "Serial3.h"
#include "Key.h"
#include "NODE.h"
#include "i2c.h"
#include "at24c02.h"



//ÔÚOLEDÉÏÏÔʾÊÕ·¢µÄÊý¾Ý°ü£¬µÚÒ»¸ö²ÎÊýΪ´ýÏÔʾµÄÊý¾Ý°ü£¬µÚ¶þ¸ö²ÎÊýΪÏÔʾµÄÆðʼÐУ¬¿ÉÒÔÑ¡Ôñ1»òÕß3
//rowΪ1ʱºò£¬aΪT±íʾ´®¿Ú1µÄ·¢ËÍÊý¾Ý°ü£¬aΪR±íʾ´®¿Ú1µÄ½ÓÊÕÊý¾Ý°ü¡£rowΪ3±íʾ´®¿Ú3µÄÊÕ·¢Êý¾Ý°ü
void OLED_show_Packet(uint8_t* array,uint8_t row,char a)
{
      OLED_ShowChar(row, 1, a);  
	    OLED_ShowHexNum(row, 3, array[0], 2);
			OLED_ShowHexNum(row, 5, array[1], 2);
			OLED_ShowHexNum(row, 8, array[2], 2);
			OLED_ShowHexNum(row, 10, array[3], 2);
			OLED_ShowHexNum(row++, 13, array[4], 2);
			OLED_ShowHexNum(row, 1, array[5], 2);
			if(!(array[6]==0x00 && array[7]==0x00))
   		{		OLED_ShowHexNum(row, 4, array[6], 2);
	      	OLED_ShowHexNum(row, 6, array[7], 2);
				  if(!(array[8]==0x00 && array[9]==0x00)) 
					{	 OLED_ShowHexNum(row, 9, array[8], 2);
	           OLED_ShowHexNum(row, 11, array[9], 2);
					}
			}	
}

int main(void)
{
	OLED_Init();

	Serial_Init();
	Serial3_Init();
	
	
	
	NODE_init();
	
	

//´®¿Ú1 µÄ½ÓÊÕ±ê־Ϊ'A'£¬·¢ËÍΪ'B' ´®¿ÚÈýµÄ½ÓÊÕ±ê־Ϊ'Y',·¢ËÍΪ'Z'
	
	
//	while (1)
//	{
//		if (Serial_GetRxFlag() == 1)    //Èç¹û´®¿Ú1½ÓÊܵ½ÁËÊý¾Ý£¬ÔòÈô®¿Ú3·¢³öÈ¥
//		{	
//			OLED_Clear();
//		  OLED_show_Packet(Serial_RxPacket,1,'R');      
//			Serial_RxPacket_to_Serial3_TxPacket();
//		  Serial3_SendPacket();
//			OLED_show_Packet(Serial3_TxPacket,3,'T');
//		}
//			if (Serial3_GetRxFlag() == 1)  //Èç¹û´®¿Ú3½ÓÊÕµ½ÁËÊý¾Ý£¬ÔòÈô®¿Ú1·¢³öÈ¥ 
//		{
//			OLED_Clear();
//		  OLED_show_Packet(Serial3_RxPacket,3,'R');
//			Serial3_RxPacket_to_Serial_TxPacket();
//			Serial_SendPacket();
//			OLED_show_Packet(Serial_TxPacket,1,'T');
//		}
//	}
//}


	while (1)
	{
	//	AT24C02_WriteTwoByte(0x40, 0x0002);
		uint16_t addr;
		
		if (Serial_GetRxFlag() == 1)    //Èç¹û´®¿Ú1½ÓÊܵ½ÁËÊý¾Ý
		{	
				OLED_Clear();
				OLED_show_Packet(Serial_RxPacket,1,'R');
				if(Serial_RxPacket[0]==Serial_RxPacket[2] && Serial_RxPacket[1]==Serial_RxPacket[3])
				{
					//Èç¹ûÄ¿µÄµØÖ·ÓëÔ´µØÖ·Ò»Ö£¬ÄǾÍÊÇ×Ô·¢×ÔÊÕ£¬ÐèÒªÊDzéѯÅäÖã¬Êý¾Ý½Ï¶à²»ÄÜ×ß´¦ÀíÖÐÐÄ
					//´¦ÀíºóÈô®¿Ú1·¢³öÊý¾Ý
					deal_all_data();
					for(int i=0;i<20;i++)
					  Serial_SendArray(all_data_packet[i],4);
					  
				}
				//
				else{
					//×ß´¦ÀíÖÐÐÄ£¬²¢ÇÒÈô®¿Ú3·¢³öÊý¾Ý
						deal_center(Serial_RxPacket);
						Serial3_SendPacket(NODE_Packet);
						OLED_show_Packet(Serial3_TxPacket,3,'T');
				}			
				
			
		}
		
			if (Serial3_GetRxFlag() == 1)  //Èç¹û´®¿Ú3½ÓÊÕµ½ÁËÊý¾Ý 
		{
			OLED_Clear();
		  OLED_show_Packet(Serial3_RxPacket,3,'R');
		
				addr=Serial3_RxPacket[0]<<8;
			  addr+=Serial3_RxPacket[1];
			
				//Åжϴ®¿Ú3ÊÕµ½µÄÊý¾ÝÊÇ·ñ¾­¹ý´¦ÀíÖÐÐÄ£¬ÒÔ¼°ÊÇÈô®¿Ú3·¢³öÈ¥»¹ÊÇÈô®¿Ú1·¢³öÈ¥
				if(IS_Current_addr(addr) && (Serial3_RxPacket[4]==0x10 ||  Serial3_RxPacket[4]==0x11) )
				{
					Serial3_RxPacket_to_Serial_TxPacket();
					Serial_SendPacket();
					OLED_show_Packet(Serial_TxPacket,1,'T');
				}else{
//					OLED_ShowHexNum(1, 1, mynode.ip , 2);
					deal_center(Serial3_RxPacket);
					Serial3_SendPacket(NODE_Packet);
					OLED_show_Packet(Serial3_TxPacket,3,'T');
				}
			
		}
	}
}



//#include "i2c.h"
//#include "at24c02.h"
// 
//uint8_t data[11],str[12]="hello world";
// 
//int main()
//{
//	uint8_t rece_data;
//	OLED_Init();

//	I2C_Configuration();
//	
//	//AT24C02_WriteOneByte(0x00,0xFE);
//	
//	//rece_data=AT24C02_ReadOneByte(0x00);
//	  
//	NODE_init();
//ÐèÒªÅäÖÃ×ÔÉíµØÖ·£¬×ÔÉíµØÖ··¶Î§
//µÚÒ»¸öÅäÖø¸½ÚµãµØÖ·¼°Æ䷶Χ£¬ÁíÒ»¸öÅäÖÃ×Ó½ÚµãµØÖ·¼°Æ䷶Χ
//µØַΪ1 ·¶Î§Îª1-1024 
	//×Ó½ÚµãµØַΪ2  ·¶Î§Îª2-255
	
//	OLED_ShowHexNum(1, 1, mynode.father_ip, 4);
//  AT24C02_WriteTwoByte(0x00, 0x0001);
//	AT24C02_WriteTwoByte(0x50, 0x0002);
//	AT24C02_WriteTwoByte(0x52, 0x00FF);
	AT24C02_WriteTwoByte(0xA0, 0x0002);
	AT24C02_WriteTwoByte(0xB0, 0x0002);
	AT24C02_WriteTwoByte(0xB2, 0x00FF);
//	//uint16_t data=AT24C02_ReadTwoByte(0x00);
//	AT24C02_WriteTwoByte(0x00, 0x0001);
//	AT24C02_WriteTwoByte(0x12, 0x0400);
	
//	OLED_ShowHexNum(1, 1, mynode.father_range[1], 4);
//	
//	while(1)
//	{
//	
//		
//	}
// 
//	
// 
//}






 
	

  • 7
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
您好!关于STM32HAL库与LoRa通信模块的问题,我可以为您提供一些基本信息。 STM32HAL库是STMicroelectronics提供的一种针对STM32微控制器的硬件抽象层(Hardware Abstraction Layer)。它提供了一系列的函数和驱动程序,方便开发人员在不同的STM32系列芯片之间进行移植和开发。 至于LoRa通信模块LoRa是一种低功耗远距离无线通信技术,适用于物联网(IoT)应用。LoRa通信模块基于LoRa技术,通过无线电波进行通信,具有长距离传输、低功耗和大容量等特点。 在使用STM32HAL库与LoRa通信模块时,您可以通过以下步骤进行操作: 1. 硬件连接:将LoRa通信模块STM32微控制器连接。通常情况下,您需要将模块的SPI接口、GPIO引脚等与STM32微控制器的对应引脚相连。 2. 初始化STM32HAL库:在代码中使用STM32HAL库的相应函数进行初始化。这些函数包括GPIO初始化、SPI初始化等。 3. 配置LoRa通信模块:使用STM32HAL库的相关函数配置LoRa通信模块的参数,例如频率、发射功率、扩频因子等。 4. 发送和接收数据:使用STM32HAL库的函数进行LoRa通信模块的数据发送和接收操作。您可以通过SPI接口与模块进行数据交互。 需要注意的是,具体的操作细节和代码实现可能会根据您所使用的具体STM32微控制器型号和LoRa通信模块型号而有所差异。因此,建议您参考STM32HAL库和LoRa通信模块的相关文档和示例代码,以获得更详细的信息。 希望这些信息对您有所帮助!如果您还有其他问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值