3 - LoRa通讯实例

该实验旨在掌握LoRa通信技术,通过编程实现了两个LoRa终端之间的通信。实验中,当按下其中一个模块的按键时,会发送数据到另一个模块,控制其LED状态,并在OLED屏幕上显示。程序包括时钟树频率设置、引脚配置、SPI和LoRa库的移植、按键检测及数据接收等功能。实验结果显示两个设备能成功收发数据,实现双向通信。
摘要由CSDN通过智能技术生成

实验目的:掌握LoRa的通信

实验内容:实现两个LoRa终端的通信。

实验现象:
程序下载完成,屏幕无显示,按一个模块的USER按键,屏幕显示“transmitting”“1xx0 ”,
控制另外一个模块的K1-LED和K2-LED进行亮灭显示,同时OLED显示两个LED的状态,两个模块可以相互发送数据。

1.将时钟树频率设置成32MHz

2引脚配置

将引脚PB5,PB4,PA10,PA9,PA8,PA7,PA5,PA4,PA1,PA0,PC15设置成GPIO_Output模式,将PA6,PC14设置成GPIO_Input模式,并按下图进行,上下拉,速度设置。
其中PA0,PA1默认低电平。

在这里插入图片描述
在这里插入图片描述

3.生成工程代码

4.按之前实验添加OLED的相关头文件和代码

5.移植spi和LoRa的库文件

spi.h

#ifndef __SPI_H
#define __SPI_H

#include "main.h"

void delay_us(uint32_t time);
void spi_init(void);
void spi_send_byte(uint8_t byte);
uint8_t spi_recv_byte(void);

#endif  

spi.c

#include "spi.h"

#define CLK_L() 		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET)
#define CLK_H() 		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET)
#define MOSI_L() 		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET)
#define MOSI_H() 		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET)

#define MISO_READ() 	HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6)

//
void delay_us(uint32_t time)
{
	while(time--){
		__nop();
		__nop();
		__nop();
		__nop();
		__nop();
		__nop();
	}
}

//
void spi_init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();

  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5 | GPIO_PIN_7, GPIO_PIN_SET);
  
  /*Configure GPIO pins : PA5 PA7 */
  GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pin : PA6 */
  GPIO_InitStruct.Pin = GPIO_PIN_6;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}

//
void spi_send_byte (uint8_t send_data)
{
    uint8_t i;

    for (i = 0; i < 8; i++) {
        delay_us(1);
        CLK_L();
        if((send_data << i) & 0x80){
            delay_us(1);
            MOSI_H(); 
        } else {
            delay_us(1);
            MOSI_L(); 
        }

        delay_us(1);
        CLK_H();
    }

    delay_us(1);
    CLK_L();
    MOSI_L();
}

//
uint8_t spi_recv_byte (void)
{
    uint8_t i, temp;

    temp = 0;
    for (i = 0; i < 8; i++) {
        CLK_L();
        delay_us(1);
        temp = (temp << 1);
        CLK_H(); 
        delay_us(1);
        if (MISO_READ()) {
            temp++;
        } else { 
            temp = temp + 0;
        }

        delay_us(1);
    }

    CLK_L();
    delay_us(1);

    return temp;
}
zm4xx_gpio.h
#ifndef __ZX4XX_GPIO_H
#define __ZX4XX_GPIO_H
			  	 
#include "main.h"

void zm4xx_sel_pin_set(uint8_t value);
void zm4xx_rst_pin_set(uint8_t value);
void zm4xx_pin_init(void);    	

#endif  



zm4xx_gpio.c
#include "zm4xx_gpio.h"

//
void zm4xx_pin_init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();
	
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4 | GPIO_PIN_9, GPIO_PIN_SET);
	
  /*Configure GPIO pins : PA4 PA9 */
  GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_9;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

//
void zm4xx_rst_pin_set(uint8_t value)
{
	if(value){
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_SET);	
    
	}else{
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET);	
	}
}

//
void zm4xx_sel_pin_set(uint8_t value)
{
	if(value){
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
    
	}else{
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);	
	}
}

以下3个文件不需要修改,且内容过大

sx127x_lora.h
sx127x_regs_lora.h
sx127x_lora.c

6.移植之前写的按键文件

key.h
key.c
在实验2.6PWM输出实验中有完整key.h key.c文件
全部移植完成的内核文件
在这里插入图片描述
在这里插入图片描述

7.在main.c文件下依次添加如下代码

引入头文件

/* USER CODE BEGIN Includes */
#include "oled.h"
#include "stdio.h"
#include "string.h"

#include "sx127x_lora.h"
#include "key.h"
/* USER CODE END Includes */

定义LoRa相关宏

/* USER CODE BEGIN PTD */
#define FREQ			433000000L
radio_handle_t handle;
/* USER CODE END PTD */

申明函数

/* USER CODE BEGIN PM */
void LoRa_Init(void);
void Task_BrdInit(void);
void Task_Main(void);
/* USER CODE END PM */

自定义变量

/* USER CODE BEGIN PV */
uint8_t key_flag = 1;
uint8_t send_data[4];
char *data;
uint8_t rece_data[256] = {0};
/* USER CODE END PV */

OLED和LoRa初始化

  /* USER CODE BEGIN 2 */
    Task_BrdInit();
    LoRa_Init();
  /* USER CODE END 2 */

主控函数

  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    Task_Main();
  }
  /* USER CODE END 3 */

OLED初始化代码

/* USER CODE BEGIN 4 */
void Task_BrdInit(void)
{
    OLED_PowerControl(ENABLE);

    HAL_Delay(200);
    OLED_Init();
    OLED_Clear();

    OLED_ShowString(0, 0, (unsigned char *)"                ", 16);
    OLED_ShowString(0, 2, (unsigned char *)"                ", 16);

}

LoRa初始化代码

void LoRa_Init(void)
{
	spi_init();
  zm4xx_pin_init();
  
	handle = radio_zm4xx_inst_init(spi_recv_byte,spi_send_byte,zm4xx_rst_pin_set,zm4xx_sel_pin_set,HAL_Delay,delay_us);
	
	if(handle != NULL){
		if(RADIO_RET_OK == radio_freq_set(handle, FREQ)){
      HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_RESET); // LoRa ok
		}
		
		radio_mode_set(handle, RX_MODE);	//Receive Mode
	}
}

主控函数代码,轮询进行按键检测和数据接收

void Task_Main(void)
{
  uint8_t key_num;
  uint8_t i = 0;
  uint16_t data_size;
  int ret = RADIO_RET_OK;
  
  /*1.轮询按键检测*/
  key_num = USER_Scan();
  if(key_num == 1)
  {
    if(key_flag == 4)
    {
      key_flag = 1;
    }
    switch(key_flag)
    {
      case 1:
        data = "1100";
        OLED_ShowString(0, 0, (unsigned char *)"  transmitting  ", 16);
        OLED_ShowString(0, 2, (unsigned char *)"      1100      ", 16);
        break;
      case 2:
        data = "1010";
        OLED_ShowString(0, 0, (unsigned char *)"  transmitting  ", 16);
        OLED_ShowString(0, 2, (unsigned char *)"      1010      ", 16);          
        break;
      case 3:
        data = "1110";
        OLED_ShowString(0, 0, (unsigned char *)"  transmitting  ", 16);
        OLED_ShowString(0, 2, (unsigned char *)"      1110      ", 16);                   break;
      default:
        break;
    }
    key_flag ++;
    for(i=0; i<4; i++)
    {
      send_data[i] = data[i];
    }
    radio_buf_send(handle, send_data, 4);
    radio_mode_set(handle, RX_MODE);
  }
  
  /*2.轮询接收数据*/
  ret = radio_buf_recv(handle, rece_data, &data_size);
  if(ret == RADIO_RET_OK)
  {
    HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_15);
    if(data_size > 0)
    {
      if(*(rece_data)== '1')
      {
        if(*(rece_data + 1) == '1')
        {
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
          OLED_ShowString(0, 0, (unsigned char *)" NO.1   LED1 ON ", 16);          
        }
        else
        {
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
          OLED_ShowString(0, 0, (unsigned char *)" NO.1   LED1 OFF", 16);          
        }
        if(*(rece_data + 2) == '1')
        {
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
          OLED_ShowString(0, 2, (unsigned char *)" NO.2   LED1 ON ", 16);          
        }
        else
        {
          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
          OLED_ShowString(0, 2, (unsigned char *)" NO.2   LED1 OFF", 16);          
        }          
      }
    }
    radio_mode_set(handle, RX_MODE);    
  }
}

/* USER CODE END 4 */

8.编译并烧写代码

9.实验现象

两个设备之间可以进行数据收发
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

T-Y_yang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值