發布日期:2022-05-25 點擊率:42
2、串口透傳系統通信機制
3、串口透傳系統業務流程
串口透傳系統設計需求:
1、將LoRa終端定義成兩種角色:Master(主機)和Slave(從機)
2、一個模塊發送任意字節長度(小于128Byte)數據,另一模塊都可以接收到
3、PC機上通過串口調試助手實現接收和發送
4、終端在LCD屏幕上顯示終端類型及收發數據包個數
串口透傳系統通信機制:
串口透傳業務流程-初始化:
串口透傳業務流程-主程序:
串口透傳業務流程-LCD任務:
串口透傳業務流程-串口接收任務:
串口透傳業務流程-無線任務:
LoRa串口透傳系統功能開發
內容概要:
1、串口功能開發
2、LCD功能開發
3、無線收發功能開發
串口功能接口:(這里介紹了相關函數和相關代碼,里面使用到的一些變量在下面串口數據結構中會有說明)
?//啟動串口1,使能串口空閑中斷 。設置為空閑中斷模式可以在整包之后才進行數據的收發,然后產生中斷,避免重復單個數據的收發(減小開銷)
__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);//注意:使能空閑中斷后,不管有沒有接收數據,會先觸發一次中斷,發送一次數據
HAL_UART_Receive_DMA(&huart1,a_Usart1_RxBuffer,RXLENGHT); //打開DMA接收,串口空閑中斷模式配合DMA進行數據的接收
(以上兩行代碼功能:將uart1接收到的數據通過DMA傳遞給a_Usart1_RxBuffer,然后產生串口空閑中斷,在中斷中做進一步處理)
void USART1_IRQHandler(void)
{
uint32_t temp;
//判斷是否產生空閑中斷
if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE) != RESET )
{
//清除中斷標志
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
temp = huart1.Instance->ISR; //讀取寄存器的值
temp = huart1.Instance->RDR; //讀取寄存器的值
HAL_UART_DMAStop(&huart1); //停用DMA 關鍵點1:以上兩行代碼用于清除DMA的接收中斷(只需要讀取一次ISR和RDR寄存器的值)
temp = hdma_usart1_rx.Instance->CNDTR;
UsartType1.Usart_rx_len = RXLENGHT - temp;
HAL_UART_RxCpltCallback(&huart1); //調用回調函數,在回調函數中具體實現數據的接收 關鍵點2
}
HAL_UART_IRQHandler(&huart1);
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
uint8_t Old_len = 0;
if(UartHandle->Instance == USART1)//判斷是否為USART1中斷
{
Old_len = strlen(UsartType1.usartDMA_rxBuf);//讀取發送緩沖區UsartType1.usartDMA_rxBuf的長度(如果為0則表示沒有數據)
if(0 != Old_len)
{
memcpy(&UsartType1.usartDMA_rxBuf[Old_len],a_Usart1_RxBuffer,UsartType1.Usart_rx_len);
Old_len=0;
}
else
memcpy(UsartType1.usartDMA_rxBuf,a_Usart1_RxBuffer,UsartType1.Usart_rx_len);
// UsartxSendData_DMA(&huart1,a_Usart2_RxBuffer,UsartType2.Usart_rx_len);
memset(a_Usart1_RxBuffer,0,UsartType1.Usart_rx_len);//清空DMA中接收緩沖區a_Usart1_RxBuffer的數據
HAL_UART_Receive_DMA(&huart1,a_Usart1_RxBuffer,RXLENGHT);//繼續打開DMA接收
UsartType1.receive_flag =1; //接收標識位,置1表示發送緩沖區中有新的數據,提醒相關函數將數據發送出去
}
}
//
//
//函數名稱:UartDmaGet
//
//函數描述:串口數據獲取
//
//函數參數: 無
//
//返回值: 無
//
//創建者:
//
void UartDmaGet(void) //串口接收任務處理函數
{
if(UsartType1.receive_flag == 1)//如果發送緩沖區中有新的數據,則將其發送給sx1278
{
//串口接收到的數據原封發給SX1278,sx1278通過無線將數據發送出去
Radio->SetTxPacket(UsartType1.usartDMA_rxBuf, UsartType1.Usart_rx_len);
memset(UsartType1.usartDMA_rxBuf,0,UsartType1.Usart_rx_len);
UsartType1.receive_flag = 0; //接收數據標志清零
}
}
串口數據結構:
上述代碼中使用到的相關變量的定義如下:
#define RXLENGHT 128
#define RECEIVELEN 2048
#define USART_DMA_SENDING 1//發送未完成
#define USART_DMA_SENDOVER 0//發送完成
typedef struct
{
uint8_t receive_flag ;//空閑接收標記
uint8_t dmaSend_flag ;//發送完成標記
uint16_t Usart_rx_len;//接收長度
uint8_t usartDMA_rxBuf[RECEIVELEN];//無線發送緩存
}USART_RECEIVETYPE;
extern USART_RECEIVETYPE UsartType1;
extern USART_RECEIVETYPE UsartType2;
//
////局部變量
//extern uint8_t g_Usart1_RxBuffer[RXLENGHT];
//extern uint8_t g_Usart2_RxBuffer[RXLENGHT];
////全局變量
extern uint8_t a_Usart1_RxBuffer[RXLENGHT]; //DMA接收緩存
//extern uint8_t a_Usart2_RxBuffer[RXLENGHT];
LCD功能開發:略
無線收發功能開發:(略)
//
//
//函數名稱: RxDataPacketNum
//
//函數描述: 接收數據包計數
//
//函數參數: 無
//
//返回值: 無
//
//創建者:
//
void RxDataPacketNum(void)
{
if(EnableMaster == true)
Master_RxNumber++;
else
Slave_RxNumber++;
}
//
//
//函數名稱: TxDataPacketNum
//
//函數描述: 發送數據包計數
//
//函數參數: 無
//
//返回值: 無
//
//創建者:
//
void TxDataPacketNum(void)
{
if(EnableMaster == true)
Master_TxNumber++;
else
Slave_TxNumber++;
}
最后給出main.c文件的全部代碼:
#include "main.h"
#include "stm32f0xx_hal.h"
#include "adc.h"
#include "dma.h"
#include "spi.h"
#include "usart.h"
#include "gpio.h"
#include
---------------------
作者:許新天
來源:CSDN
原文:https://blog.csdn.net/weixin_39148042/article/details/81739617
下一篇: PLC、DCS、FCS三大控
上一篇: 物聯網之LoRa開發與應