基于STM32的LoRa PINGPONG系统设计

您所在的位置:网站首页 pingpong收款流程图英文 基于STM32的LoRa PINGPONG系统设计

基于STM32的LoRa PINGPONG系统设计

2024-07-12 21:33| 来源: 网络整理| 查看: 265

基于STM32的LoRa PINGPONG系统设计

本次分享一种LoRa PINGPING系统的设计。 单片机:STM32F103C8T6 LORA模组:LLCC68

文章目录 基于STM32的LoRa PINGPONG系统设计1 设计需求2 通信机制3 软件流程3.1 主体流程3.2 Master流程3.3 Slaver流程 4 软件代码编写4.1 参数配置4.2 发送完成处理4.3 接收完成处理4.4 主函数 5 试验验证

1 设计需求 将LoRa终端定义成两种角色:Master和SlaveMaster主动发送PING数据,接收PANG数据Slave如果接收到PING数据,回应PANG数据printf打印终端类型及收发数据包个数 2 通信机制

在这里插入图片描述

3 软件流程 3.1 主体流程

请添加图片描述

3.2 Master流程

在这里插入图片描述

3.3 Slaver流程

在这里插入图片描述

4 软件代码编写 4.1 参数配置

LoRa参数配置,必须确保主机和从机的参数一致,否则额会通讯异常。

//--------------------------------------------- 测试默认配置 --------------------------------------------- #define LORA_FRE 470000000 // 收发频率 #define LORA_TX_OUTPUT_POWER 20 // 测试默认使用的发射功率,126x发射功率0~22dbm,127x发射功率2~20dbm #define LORA_BANDWIDTH 2 // [0: 125 kHz, 测试默认使用的带宽,LLCC68:[0: 125 kHz,1: 250 kHz,2: 500 kHz,3: Reserved] #define LORA_SPREADING_FACTOR 8 // 测试默认使用的扩频因子范围7~12 #define LORA_CODINGRATE 2 // 测试默认使用的纠错编码率[1: 4/5,2: 4/6,3: 4/7,4: 4/8] #define LORA_PREAMBLE_LENGTH 10 // 前导码长度 #define LORA_LLCC68_SYMBOL_TIMEOUT 0 // Symbols(LLCC68用到的是0,127x用到的是5) #define LORA_FIX_LENGTH_PAYLOAD_ON false // 是否为固定长度包(暂时只是LLCC68用到了) #define LORA_IQ_INVERSION_ON false // 这个应该是设置是否翻转中断电平的(暂时只是LLCC68用到了) #define LORA_RX_TIMEOUT_VALUE 5000 4.2 发送完成处理 static void LLCC68OnTxDone( void ) { #ifdef MASTER Radio.Rx( 0 ); //进入接收模式 //发送完成闪烁一下led提示 GPIO_ResetBits(GPIOB,GPIO_Pin_0); delay_ms(100); GPIO_SetBits(GPIOB,GPIO_Pin_0); Master_TxNumber++; #else //发送完成闪烁一下led提示 Radio.Rx( 0 ); //进入接收模式 GPIO_ResetBits(GPIOB,GPIO_Pin_0); delay_ms(100); GPIO_SetBits(GPIOB,GPIO_Pin_0); Slave_TxNumber++; #endif } 4.3 接收完成处理 static void LLCC68OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) { uint8_t Buffer[BUFFERSIZE]; #ifdef MASTER Radio.Standby(); Radio.Rx(0); if(size!=strlen((const char*)PongMsg)){ printf("recive size !=4 is error\r\n"); }else{ memcpy(&Buffer,payload,4); printf("MASTER recive:%s\r\n",Buffer); GPIO_ResetBits(GPIOB,GPIO_Pin_0); delay_ms(100); GPIO_SetBits(GPIOB,GPIO_Pin_0); //接收包数 Master_RxNumber++; printf("MASTER recive packet:%d\r\n",Master_RxNumber); Radio.Send(PingMsg,strlen((const char*)PingMsg)); } #else Radio.Standby(); Radio.Rx(0); if(size!=strlen((const char*)PingMsg)){ printf("recive size !=4 is error\r\n"); }else{ memcpy(&Buffer,payload,4); printf("Slave recive:%s\r\n",Buffer); //接收成功闪烁一下led提示 GPIO_ResetBits(GPIOB,GPIO_Pin_0); delay_ms(100); GPIO_SetBits(GPIOB,GPIO_Pin_0); //接收包数 Slave_RxNumber++; printf("Slave recive packet:%d\r\n",Slave_RxNumber); Radio.Send(PongMsg,strlen((const char*)PongMsg)); } #endif } 4.4 主函数 #include "stm32f10x.h" #include "delay.h" #include "HAL_uart.h" #include "stdio.h" #include "stm32f10x_it.h" #include "project_config.h" #include "radio.h" #include "string.h" /* wiring setting spi bus: LoRa modules STM32 NSS_PIN PA4 MOSI_PIN PA7 MISO_PIN PA6 SCK_PIN PA5 RESET_PIN PB1 DIO1_PIN PB11 DIO4_BUSY_PIN PA0 波特率:115200 UART: USB to TTL STM32 Tx PA_9 Rx PA_10 */ #define BUFFERSIZE 4 uint8_t PingMsg[] = "PING"; uint8_t PongMsg[] = "PONG"; uint16_t BufferSize = BUFFERSIZE; #ifdef MASTER uint8_t EnbleMaster = true; #else uint8_t EnbleMaster = false; #endif uint32_t Master_TxNumber = 0; uint32_t Master_RxNumber = 0; uint32_t Slave_TxNumber = 0; uint32_t Slave_RxNumber = 0; uint8_t OCP_Value = 0; static RadioEvents_t LLCC68RadioEvents; static void LLCC68OnTxDone( void ); static void LLCC68OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ); static void LLCC68OnTxTimeout( void ); static void LLCC68OnRxTimeout( void ); static void LLCC68OnRxError( void ); //硬件初始化 void SysInit(void){ GPIO_InitTypeDef GPIO_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); //NVIC(中断优先级管理)分组配置,注意:这个分组整个程序只能有一次,配置后不要修改,否则会出现很多问题 这里直接用4,0~15优先级 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //JTAG复用为GPIO需要使用 RCC_APB2Periph_AFIO 时钟 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); //关闭JTAG功能(需要打开 RCC_APB2Periph_AFIO 时钟) //led指示灯 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_SetBits(GPIOB,GPIO_Pin_0); //PB.0 输出高 HALUart1Init(); SysTick_Config(SystemCoreClock/1000); } int main(void){ SysInit(); //硬件初始化 //判断SPI是否连接成功 OCP_Value = Radio.Read(REG_OCP); printf("[%s()-%d]read OCP register value:0x%04X\r\n",__func__,__LINE__,OCP_Value); //初始化LoRa参数 LLCC68RadioEvents.TxDone = LLCC68OnTxDone; LLCC68RadioEvents.RxDone = LLCC68OnRxDone; LLCC68RadioEvents.TxTimeout = LLCC68OnTxTimeout; LLCC68RadioEvents.RxTimeout = LLCC68OnRxTimeout; LLCC68RadioEvents.RxError = LLCC68OnRxError; Radio.Init( &LLCC68RadioEvents ); Radio.SetChannel(LORA_FRE); //参数:lora模式,发射功率,fsk用的lora设置为0就可以,带宽,纠错编码率,前导码长度,固定长度数据包(一般是不固定的所以选false), //crc校验,0表示关闭跳频,跳频之间的符号数(关闭跳频这个参数没有意义),这个应该是表示是否要翻转中断电平的,超时时间 Radio.SetTxConfig( MODEM_LORA, LORA_TX_OUTPUT_POWER, 0, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, LORA_CODINGRATE, LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON, true, 0, 0, LORA_IQ_INVERSION_ON, 3000 ); Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, LORA_LLCC68_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0, true, 0, 0, LORA_IQ_INVERSION_ON, false ); printf("all setting\r\n"); printf("freq: %d\r\n Tx power: %d\r\n band width: %d\r\n FS: %d\r\n CODINGRATE: %d\r\n PREAMBLE_LENGTH: %d\r\n",LORA_FRE,LORA_TX_OUTPUT_POWER,LORA_BANDWIDTH,LORA_SPREADING_FACTOR,LORA_CODINGRATE,LORA_PREAMBLE_LENGTH); #ifdef MASTER Radio.Send(PingMsg,strlen((const char*)PingMsg)); printf("I am Master!\n"); #else Radio.Rx( 0 ); //进入接收模式 printf("I am Slave!\n"); #endif printf("SysInit OK,version:%s\r\n",SOFT_VERSION); while(1) { Radio.IrqProcess( ); // Process Radio IRQ delay_ms(1); } } static void LLCC68OnTxDone( void ) { #ifdef MASTER Radio.Rx( 0 ); //进入接收模式 //发送完成闪烁一下led提示 GPIO_ResetBits(GPIOB,GPIO_Pin_0); delay_ms(100); GPIO_SetBits(GPIOB,GPIO_Pin_0); Master_TxNumber++; #else //发送完成闪烁一下led提示 Radio.Rx( 0 ); //进入接收模式 GPIO_ResetBits(GPIOB,GPIO_Pin_0); delay_ms(100); GPIO_SetBits(GPIOB,GPIO_Pin_0); Slave_TxNumber++; #endif } static void LLCC68OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr ) { uint8_t Buffer[BUFFERSIZE]; #ifdef MASTER Radio.Standby(); Radio.Rx(0); if(size!=strlen((const char*)PongMsg)){ printf("recive size !=4 is error\r\n"); }else{ memcpy(&Buffer,payload,4); printf("MASTER recive:%s\r\n",Buffer); GPIO_ResetBits(GPIOB,GPIO_Pin_0); delay_ms(100); GPIO_SetBits(GPIOB,GPIO_Pin_0); //接收包数 Master_RxNumber++; printf("MASTER recive packet:%d\r\n",Master_RxNumber); Radio.Send(PingMsg,strlen((const char*)PingMsg)); } #else Radio.Standby(); Radio.Rx(0); if(size!=strlen((const char*)PingMsg)){ printf("recive size !=4 is error\r\n"); }else{ memcpy(&Buffer,payload,4); printf("Slave recive:%s\r\n",Buffer); //接收成功闪烁一下led提示 GPIO_ResetBits(GPIOB,GPIO_Pin_0); delay_ms(100); GPIO_SetBits(GPIOB,GPIO_Pin_0); //接收包数 Slave_RxNumber++; printf("Slave recive packet:%d\r\n",Slave_RxNumber); Radio.Send(PongMsg,strlen((const char*)PongMsg)); } #endif } static void LLCC68OnTxTimeout( void ) { printf("TxTimeout\r\n"); } static void LLCC68OnRxTimeout( void ) { Radio.Standby(); printf("RxTimeout retry recive\r\n"); Radio.Rx( LORA_RX_TIMEOUT_VALUE ); } static void LLCC68OnRxError( void ) { Radio.Standby(); printf("RxError retry recive\r\n"); Radio.Rx(LORA_RX_TIMEOUT_VALUE); } 5 试验验证

–验证流程: 将主机程序刷到主机中,将从机程序刷到从机中,通过宏定义进行区分。 观察主机和从机的打印情况。 主机: 从机: 在这里插入图片描述 完整代码: https://download.csdn.net/download/qq_39742246/88629477 已经过验证



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3