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

这篇具有很好参考价值的文章主要介绍了基于STM32的正点原子LORA模块通信网络。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

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

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

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

#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)
//	{
//	
//		
//	}
// 
//	
// 
//}






 
	

到了这里,关于基于STM32的正点原子LORA模块通信网络的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 正点原子stm32F407学习笔记5——串口通信实验

    上位机给开发板发送数据,开发板将收到的数据发回给上位机 串口设置的一般步骤可以总结为如下几个步骤: 串口时钟使能,GPIO 时钟使能。 设置引脚复用器映射:调用 GPIO_PinAFConfig 函数。 GPIO 初始化设置:要设置模式为复用功能。 串口参数初始化:设置波特率,字长,奇

    2024年02月06日
    浏览(48)
  • 正点原子STM32(基于HAL库)5

    STM32F103ZET6 自带了64K 字节的RAM,对一般应用来说,已经足够了,不过在一些对内存要求高的场合,比如做华丽效果的GUI,处理大量数据的应用等,STM32 自带的这些内存就可能不太够用了。好在嵌入式方案提供了扩展芯片RAM 的方法,本章将介绍我们开发板上使用的RAM 拓展方案

    2024年02月08日
    浏览(79)
  • 正点原子STM32(基于HAL库)1

    正点原子B站视频地址:https://www.bilibili.com/video/BV1bv4y1R7dp?p=1vd_source=cc0e43b449de7e8663ca1f89dd5fea7d STM32芯片分类 ST中文社区网:https://www.stmcu.org.cn/ ST官网:https://www.st.com/content/st_com/en.html 了解了STM32 的系列和命名以后,我们再进行STM32 选型就会比较容易了,这里我们只要遵循:由高

    2023年04月23日
    浏览(83)
  • LVGL与STM32的理解(基于正点原子资料)

            LVGL能让你在嵌入式平台(stm32)相对容易的搞出比较绚丽的UI交互效果。也就是在LVGL制定的游戏规则下去开发UI界面,活好事少。为此硬件设备需要做一些适配,以达到:LVGL能够使用STM32的硬件资源;同时,在STM32编程后,效果又能落地到LVGL。(以下截图来是正点原

    2024年01月23日
    浏览(46)
  • 基于STM32的智能灯光亮度调节器【正点原子】(一)

    第一章 PWM调节 第二章 ADC采样 第三章 光敏传感器 第四章 智能灯光亮度调节器(终) 目录 前言 一、PWM是什么? 二、如何产生一个PWM信号? 总结 本文实现的是一个智能灯光亮度调节器的设计,使用STM32F103ZE的单片机,可以手动调节灯光档位,也可以自动根据环境亮度进行切

    2024年02月09日
    浏览(56)
  • STM32使用LORA模块通信

    目录 一、简单了解 1、模块简介 2、硬件及功能  3、传输方式 二、模块上手 1、连接  2、编写代码 usart3.h usart3.c lora.h lora.c main.c 本文以正点原子ATK-LORA-01模块为例进行介绍。         ATK-LORA-01-V3.0(V3.0是版本号,下面均以ATK-LORA-01表示该产品)是ALIENTEK推出的一款体积小、微

    2024年02月02日
    浏览(36)
  • 【STM32】使用CubeMX快速创建FreeRTOS的基础工程,基于正点原子

    【STM32】HAL库 新建MDK工程 【STM32】HAL库 串口轮询发送 【STM32】HAL库 LED闪烁、流水灯 【STM32】HAL库 定时器中断 【STM32】HAL库 外部中断 使用STM32F103C8T6开发板,用STM32CubeMX配置FreeRTOS,可以适配正点原子FreeRTOS所有实验的基础工程 HAL的时基不能选择系统定时器 PA0和PA1输出模式,

    2024年02月19日
    浏览(52)
  • 基于STM32 RS485传感器数据采集(参考正点原子部分代码)

    目前工业上,传感器一般都选RS485,modbus通讯协议,这种通讯方式,有很强的鲁棒性,本篇文章基于原子哥的精英板进行开发。 1、初始化与电脑通信的串口(PA9 PA10) 2、采用串口中断将数据保存到数组buff中 3、用定时器来配置一帧字节是否结束(空闲时间指定时间) 5、从机

    2024年02月11日
    浏览(48)
  • 【正点原子STM32】RS485串行通信标准(串口基础协议 和 MODBUS协议、总线连接、通信电路、通信波形图、RS485相关HAL库驱动、RS485配置步骤、)

    一、RS485介绍 二、RS485相关HAL库驱动介绍 三、RS485配置步骤 四、编程实战 五、总结 串口、UART、TTL、RS232、RS422和RS485之间的关系可以如此理解: 串口 :是一个广义术语,通常指的是采用串行通信协议的接口,它可以包括多种具体的物理接口标准和逻辑电平标准。 UART (通用

    2024年04月13日
    浏览(69)
  • 2.基于正点原子STM32F103的定时器中断实验(HAL库实现)(cubeMX)

      基本上每一款MCU都会配备定时器这个外设,STM32 的每个通用定时器都是完全独立的,没有互相共享的任何资源。 同样,STM32F1系列的定时器功能也很强大,包括: TIM1和TIM8两个高级定时器; TIM2~TIM5是个通用寄存器; TIM7,TIM8,两个基本定时器。 由于本次实验适用于新手入门

    2023年04月26日
    浏览(162)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包