環形隊列+DMA空閑中斷+接收串口數據

環形隊列+DMA空閑中斷+接收串口數據

  • 一.序言
  • 二.實驗原理
  • 三.實戰是檢驗真理的唯一標準
    • 3.1 usart1.c
    • 3.2 串口中斷
  • 三.隊列代碼
    • 4.1 fifo.c
    • 4.2 fifo.h
  • 五.結語

一.序言

本次實驗利用環形隊列+DMA空閑中斷+串口。。通過這個實驗可以非常深入的理解隊列,DMA,串口的知識。如果你能自己實現掌握這個實驗,那么你應該基本掌握了隊列,DMA,串口的知識。

二.實驗原理

本次使用的是用環形隊列當緩沖器區接收串口數據。我們可以先區了解DMA的空閑中斷。本次實驗就是使用DMA空閑中斷。這里就簡單介紹一下,當串口接收到一幀數據后就會產生中斷,那么如何判斷數據是一幀呢?這里的判斷機制就是,如果收到數據后,大概接收一個字節的時間,都沒有接收到數據的話,就判斷已經接收的數據是一幀。接收一幀數據后,串口就會產生空閑中斷。同時DMA會把串口DR移位寄存器的值搬運到環形隊列緩沖區。我們只需要在環形隊列緩沖器拿數據即可。

三.實戰是檢驗真理的唯一標準

僅僅通過理論,只能說你知道有這個東西,但是你可能并不會。下面我通過代碼講解也幫助深入理解理論。

3.1 usart1.c


void Usart1_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;DMA_InitTypeDef DMA_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//USART1_TX   GPIOA.9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	GPIO_Init(GPIOA, &GPIO_InitStructure);//3?ê??ˉGPIOA.9//USART1_RX	  GPIOA.103?ê??ˉGPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);////Usart1 NVIC ????NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=5 ;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			NVIC_Init(&NVIC_InitStructure);	//?ù?Y???¨μ?2?êy3?ê??ˉVIC??′??÷USART_InitStructure.USART_BaudRate = 115200USART_InitStructure.USART_WordLength = USART_WordLength_8bUSART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_Parity = USART_Parity_No;USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	USART_Init(USART1, &USART_InitStructure); //使能空閑中斷USART_ITConfig(USART1, USART_IT_IDLE , ENABLE);//使能發送完成中斷--通過串口發送數據USART_ITConfig(USART1, USART_IT_TC , ENABLE);USART_DMACmd(USART1, USART_DMAReq_Tx|USART_DMAReq_Rx, ENABLE);USART_Cmd(USART1, ENABLE);                    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);		DMA_DeInit(DMA1_Channel5);//外設地址--串口1 的DR寄存器DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART1->DR);DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Uart1_Rx_Buffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = BSP_UART1_RX_SIZE; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//串口1的接收引腳為DAM1的通道5DMA_Init(DMA1_Channel5, &DMA_InitStructure)DMA_Cmd (DMA1_Channel5,ENABLE); //初始化環形隊列Fifo_Init(&Uart1_Rx_Fifo,Uart1_Rx_Buffer,BSP_UART1_RX_SIZE);

3.2 串口中斷

void USART1_IRQHandler(void)
{ //加上volatile 關鍵字只是為了防止警告volatile uint32_t temp = 0;BaseType_t xHigherPriorityTaskWoken = pdFALSE;if(USART_GetITStatus(USART1,USART_IT_IDLE)!= RESET)//???D?D??{//根據數據量數據入隊列//DMA_GetCurrDataCounter(DMA1_Channel5); 通道5還剩下多少個數據應該傳輸。//初始化的時候設置的通道5傳輸多少數據。Uart1_Rx_Fifo.in = BSP_UART1_RX_SIZE - DMA_GetCurrDataCounter(DMA1_Channel5);//先讀SR 再讀DR 只是為了消除空閑中斷標志位。手冊上有說明temp = USART1->SR; temp = USART1->DR;USART_ClearITPendingBit(USART1,USART_IT_IDLE);}

三.隊列代碼

代碼可能看起來簡單,但是不是那么容易理解。得自己慢慢體會,才能真正掌握,
而不是一昧的copy,不然出了問題也解決不了,自己代碼水平也不能提高。

4.1 fifo.c

#include "sys.h"
#include "app_fifo.h"//初始化
void Fifo_Init(FIFO_Type* fifo, uint8_t* buffer, uint16_t size)
{fifo->buffer = buffer;fifo->in = 0 ;fifo->out = 0;fifo->size = size;
}
//從隊列中拿數據
uint16_t Fifo_Get(FIFO_Type* fifo, uint8_t* buffer, uint16_t len)
{uint16_t lenght;uint16_t in = fifo->in;	uint16_t i;lenght = (in + fifo->size - fifo->out)%fifo->size;if(lenght > len)lenght = len;for(i = 0; i < lenght; i++){buffer[i] = fifo->buffer[(fifo->out + i)%fifo->size];}fifo->out = (fifo->out + lenght)%fifo->size;return lenght;
}

4.2 fifo.h

#ifndef	FIFO_H
#define	FIFO_H
#include "stm32f10x.h"
typedef struct {uint8_t* buffer;	uint16_t in;			uint16_t out;			uint16_t size;		
}FIFO_Type;void Fifo_Init(FIFO_Type* fifo, uint8_t* buffer, uint16_t size);uint16_t Fifo_Get(FIFO_Type* fifo, uint8_t* buffer, uint16_t len);#endif	

五.結語

代碼放出來的就是以上這些,都放上去也比較麻煩,同時也沒什么意義。寫這篇博客是想讓大家有大致的思路以及參考代碼,從而根據自己的項目或者需求區進行改動。最后,如果真的需要全部代碼的可以私信博主!最好點點關注!!!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/40835.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/40835.shtml
英文地址,請注明出處:http://en.pswp.cn/news/40835.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用低版本vcpkg時,bootstrap-vcpkg.bat無法生成vcpkg.exe的可能原因

緣由 需要使用vcpkg中低版本的第三方庫&#xff0c;下載vcpkg后&#xff0c;回退至指定版本&#xff0c;運行bootstrap-vcpkg.bat生成vcpkg.exe時&#xff0c;命令行窗口總是一閃而過&#xff0c;但是vcpkg.exe卻沒有生成。 添加pause&#xff0c;查看錯誤 編輯bootstrap-vc…

docker的網絡模式

docker0網絡 docker容器的 虛擬網關loopback &#xff1a;回環網卡、TCP/IP網卡是否生效virtual bridge&#xff1a;linux 自身繼承了一個虛擬化功能&#xff08;kvm架構&#xff09;&#xff0c;是原生架構的一個虛擬化平臺&#xff0c;安裝了一個虛擬化平臺之后就會系統就會自…

ftp設置空閑連接超時時間和數據連接超時時間

在FTP協議中&#xff0c;可以通過配置服務器端的空閑連接超時時間來設置連接的過期時間。具體步驟如下&#xff1a; 登錄FTP服務器&#xff0c;進入服務器的配置文件目錄。通常配置文件位于/etc或/etc/vsftpd目錄下。打開FTP服務器的配置文件&#xff0c;例如vsftpd.conf。在配…

區間預測 | MATLAB實現QRBiLSTM雙向長短期記憶神經網絡分位數回歸時間序列區間預測

區間預測 | MATLAB實現QRBiLSTM雙向長短期記憶神經網絡分位數回歸時間序列區間預測 目錄 區間預測 | MATLAB實現QRBiLSTM雙向長短期記憶神經網絡分位數回歸時間序列區間預測效果一覽基本介紹模型描述程序設計參考資料 效果一覽 基本介紹 區間預測 | MATLAB實現QRBiLSTM雙向長短…

Codeforces 461B 樹形 DP

題意 傳送門 Codeforces 461B Appleman and Tree 題解 d p v , k dp_{v,k} dpv,k? 代表以節點 v v v 為根的子樹中&#xff0c;包含了 v v v 的聯通分量是否存在一個黑色節點 &#xff0c;同時其余聯通分量僅包含一個黑色節點情況下&#xff0c;劃分方案的數量。DFS 求解&…

微服務觀測性提升專項梳理

文章目錄 項目背景&#xff1a;項目目標&#xff1a;專項人員關鍵問題及風險APM 進展 項目背景&#xff1a; 隨著微服務架構的普及&#xff0c;構建和管理大規模的分布式系統變得越來越復雜。為了確保這些系統的可靠性和性能&#xff0c;以及快速排除故障&#xff0c;對微服務…

Git 合并分支時允許合并不相關的歷史

git fetch git fetch 是 Git 的一個命令&#xff0c;用于從遠程倉庫中獲取最新的提交和數據&#xff0c;同時更新本地倉庫的遠程分支指針。 使用 git fetch 命令可以獲取遠程倉庫的最新提交&#xff0c;但并不會自動合并或修改本地分支。它會將遠程倉庫的提交和引用&#xff…

Linux如何查看文件進程占用-lsof

lsof命令是什么&#xff1f; 可以列出被進程所打開的文件的信息。被打開的文件可以是 1.普通的文件&#xff0c;2.目錄 3.網絡文件系統的文件&#xff0c;4.字符設備文件 5.(函數)共享庫 6.管道&#xff0c;命名管道 7.符號鏈接 8.底層的socket字流&#xff0c;網絡socket…

Rust語法: 枚舉,泛型,trait

這是我學習Rust的筆記&#xff0c;本文適合于有一定高級語言基礎的開發者看不適合剛入門編程的人&#xff0c;對于一些概念像枚舉&#xff0c;泛型等&#xff0c;不會再做解釋&#xff0c;只寫在Rust中怎么用。 文章目錄 枚舉枚舉的定義與賦值枚舉綁定方法和函數match匹配枚舉…

代碼隨想錄算法訓練營二刷第一天| 704. 二分查找,27. 移除元素

代碼隨想錄算法訓練營二刷第一天| 704. 二分查找&#xff0c;27. 移除元素 文章目錄 代碼隨想錄算法訓練營二刷第一天| 704. 二分查找&#xff0c;27. 移除元素一、704. 二分查找二、35.搜索插入位置三、34. 在排序數組中查找元素的第一個和最后一個位置四、69.x 的平方根五、3…

【回溯】總結

1、 組合和子集問題 組合問題需要滿足一定要求才算作一個答案&#xff0c;比如數量要求&#xff08;k個數&#xff09;&#xff0c;累加和要求&#xff08;target&#xff09;。 子集問題是只要構成一個新的子集就算作一個答案。 進階&#xff1a;去重邏輯。 一般都是要對同…

Linux 5種網絡IO模型

Linux IO模型 網絡IO的本質是socket的讀取&#xff0c;socket在linux系統被抽象為流&#xff0c;IO可以理解為對流的操作。剛才說了&#xff0c;對于一次IO訪問&#xff08;以read舉例&#xff09;&#xff0c;數據會先被拷貝到操作系統內核的緩沖區中&#xff0c;然后才會從操…

LL庫實現SPI MDA發送方式驅動WS2812

1&#xff0c;首先打卡STM32CubeMX&#xff0c;配置一下工程&#xff0c;這里使用的芯片是STM32F030F4P6。 時鐘 SPI外設 SPI DMA 下載接口&#xff0c;這個不配置待會下程序后第二次就不好下載調試了。 工程配置&#xff0c;沒啥說的 選擇生成所有文件 將驅動都改為LL庫 然后直…

OpenCV之特征點匹配

特征點選取 特征點探測方法有goodFeaturesToTrack(),cornerHarris()和SURF()。一般使用goodFeaturesToTrack()就能獲得很好的特征點。goodFeaturesToTrack()定義&#xff1a; void goodFeaturesToTrack( InputArray image, OutputArray corners,int maxCorners, double qualit…

jmeter errstr :“unsupported field type for multipart.FileHeader“

在使用jmeter測試接口的時候&#xff0c;提示errstr :"unsupported field type for multipart.FileHeader"如圖所示 這是因為我們 在HTTP信息頭管理加content-type參數有問題 直接在HTTP請求中&#xff0c;勾選&#xff1a; use multipart/form-data for POST【中文…

22、touchGFX學習Model-View-Presenter設計模式

touchGFX采用MVP架構&#xff0c;如下所示&#xff1a; 本文界面如下所示&#xff1a; 本文將實現兩個操作&#xff1a; 1、觸摸屏點擊開關按鍵實現打印開關顯示信息&#xff0c;模擬開關燈效果 2、板載案按鍵控制觸摸屏LED燈的顯示和隱藏 一、觸摸屏點擊開關按鍵實現打印開…

Go語言之依賴管理

go module go module是Go1.11版本之后官方推出的版本管理工具&#xff0c;并且從Go1.13版本開始&#xff0c;go module將是Go語言默認的依賴管理工具。 GO111MODULE 要啟用go module支持首先要設置環境變量GO111MODULE 通過它可以開啟或關閉模塊支持&#xff0c;它有三個可選…

docker搭建LNMP

docker安裝 略 下載鏡像 nginx:最新版php-fpm:根據自己需求而定mysql:根據自己需求定 以下是我搭建LNMP使用的鏡像版本 rootVM-12-16-ubuntu:/docker/lnmp/php/etc# docker images REPOSITORY TAG IMAGE ID CREATED SIZE mysql 8.0…

Linux的基本權限(文件,目錄)

文章目錄 前言一、Linux權限的概念二、Linux權限管理 1.文件訪問者分類2.文件類型和訪問類型3.文件訪問權限的相關設置方法三、目錄的權限四、權限的總結 前言 Linux下一切皆文件&#xff0c;指令的本質就是可執行文件&#xff0c;直接安裝到了系統的某種路徑下 一、Linux權限的…