娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

歷史上的今天

今天是:2025年06月14日(星期六)

2020年06月14日 | STM32基于固件庫學習筆記(6)使用DMA實現USART1發送數據

發布者:電子設計探索者 來源: eefocus關鍵字:STM32  固件庫  DMA  USART1  發送數據 手機看文章 掃描二維碼
隨時隨地手機看文章

DMA簡介

直接存儲器存取(DMA)用來提供在外設和存儲器之間或者存儲器和存儲器之間的高速數據傳輸。無須CPU干預,數據可以通過DMA快速地移動,這就節省了CPU的資源來做其他操作。換而言之就是當外設有數據發送給mcu,此時可以使用DMA接收到用戶定義空間(不占用cpu),接收完成在產生中斷發給mcu(才占用CPU)反正一樣。


當CPU和DMA同時訪問相同的目標(RAM或外設)時,DMA請求會暫停CPU訪問系統總線達若干個周期,總線仲裁器執行循環調度,以保證CPU至少可以得到一半的系統總線(存儲器或外設)帶寬。


兩個DMA控制器有12個通道(DMA1有7個通道,DMA2有5個通道),每個通道專門用來管理來自于一個或多個外設對寄存器訪問。

在這里插入圖片描述

DMA 主要特性

● 12個獨立的可配置的通道(請求):DMA1有7個通道,DMA2有5個通道

● 每個通道都直接連接專用的硬件DMA請求,每個通道都同樣支持軟件觸發。這些功能通過

軟件來配置。

● 在同一個DMA模塊上,多個請求間的優先權可以通過軟件編程設置(共有四級:很高、高、

中等和低),優先權設置相等時由硬件決定(請求0優先于請求1,依此類推) 。

● 獨立數據源和目標數據區的傳輸寬度(字節、半字、全字),模擬打包和拆包的過程。源和目標地址必須按數據傳輸寬度對齊。

● 支持循環的緩沖器管理

● 每個通道都有3個事件標志(DMA半傳輸、DMA傳輸完成和DMA傳輸出錯),這3個事件標志

邏輯或成為一個單獨的中斷請求。

● 存儲器和存儲器間的傳輸

● 外設和存儲器、存儲器和外設之間的傳輸

● 閃存、SRAM、外設的SRAM、APB1、APB2和AHB外設均可作為訪問的源和目標。

● 可編程的數據傳輸數目:最大為65535


處理的方式

每次DMA傳送由3個操作組成:

● 從外設數據寄存器或者從當前外設/存儲器地址寄存器指示的存儲器地址取數據,第一次傳

輸時的開始地址是DMA_CPARx或DMA_CMARx寄存器指定的外設基地址或存儲器單元。

● 存數據到外設數據寄存器或者當前外設/存儲器地址寄存器指示的存儲器地址,第一次傳輸

時的開始地址是DMA_CPARx或DMA_CMARx寄存器指定的外設基地址或存儲器單元。

● 執行一次DMA_CNDTRx寄存器的遞減操作,該寄存器包含未完成的操作數目。

在這里插入圖片描述在這里插入圖片描述

DMA 的配置步驟

1. 使能DMA時鐘

(是必不可少的)


RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMAx,ENABLE); //使能 DMA 時鐘


2. 初始化DMA通道參數

(具體某個通道,根據上面的圖可以知道)

DMA 通道配置參數種類比較繁多,在"stm32f10x_dma.h""stm32f10x_dma.c"都封裝好了的;說白了就是配置DMA_InitTypeDef結構體的參數。


//初始化

void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx,DMA_InitTypeDef* DMA_InitStruct);

typedef struct//結構體

{

  uint32_t DMA_PeripheralBaseAddr;//設置DMA傳輸的外設基地址

  /*要進行串口DMA傳輸,那么外設基地址為串口接受收發送數據存儲器USART1->DR的地址*/

  uint32_t DMA_MemoryBaseAddr;//定義 DMA 內存基地址(我們定義存放DMA傳輸數據的內存地址)

  uint32_t DMA_DIR;//作為數據傳輸的目的地還是來源(傳輸方向)

  /* DMA_DIR_PeripheralDST 外設作為數據傳輸的目的地

     DMA_DIR_PeripheralSRC 外設作為數據傳輸的來源*/

  uint32_t DMA_BufferSize;//指定 DMA 通道的 DMA 緩存的大小,單位為數據單位

  uint32_t DMA_PeripheralInc;//設定外設地址寄存器遞增與否

  /*DMA_PeripheralInc_Enable 外設地址寄存器遞增

    DMA_PeripheralInc_Disable 外設地址寄存器不變*/

  uint32_t DMA_MemoryInc;//設定內存地址寄存器遞增與否

  /*DMA_PeripheralInc_Enable 內存地址寄存器遞增

    DMA_PeripheralInc_Disable 內存地址寄存器不變*/

  uint32_t DMA_PeripheralDataSize;// 設定了外設數據寬度

  /*DMA_PeripheralDataSize_Byte 數據寬度為 8 位

    DMA_PeripheralDataSize_HalfWord 數據寬度為 16 位

    DMA_PeripheralDataSize_Word 數據寬度為 32 位*/

  uint32_t DMA_MemoryDataSize;//定了外設數據寬度

  /*DMA_MemoryDataSize_Byte 數據寬度為 8 位

    DMA_MemoryDataSize_HalfWord 數據寬度為 16 位

    DMA_MemoryDataSize_Word 數據寬度為 32 位*/

  uint32_t DMA_Mode;//工作模式

  /*DMA_Mode_Circular 工作在循環緩存模式

    DMA_Mode_Normal 工作在正常緩存模式*/

  uint32_t DMA_Priority;//通道 x 的軟件優先級

  /*DMA_Priority_VeryHigh DMA 通道 x 擁有非常高優先級

    DMA_Priority_High DMA 通道 x 擁有高優先級

    DMA_Priority_Medium DMA 通道 x 擁有中優先級

    DMA_Priority_Low DMA 通道 x 擁有低優先級*/

  uint32_t DMA_M2M;//使能 DMA 通道的內存到內存傳輸

  /*DMA_M2M_Enable DMA 通道 x 設置為內存到內存傳輸

    DMA_M2M_Disable DMA 通道 x 沒有設置為內存到內存傳輸*/

}DMA_InitTypeDef;

//后面完整程序有更清楚配置說明


3 )使能串口DMA發送或接收


USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);//發送


4 ) 使能DMA 通道x,啟動傳輸。


DMA_Cmd(DMA_CHx, ENABLE);


注:配置好了1 2 3步驟,在使能MDA通道就可以成功發送或接收一次數據。反而言之決定“DMA_Cmd()”函數的位置就能決定發送數據的時間。

5)查詢 DMA 傳輸狀態

就比如在中斷的時候,我們要判斷相對應的標志位。


FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG);

/*

DMA_FLAG_GL1  通道 1 全局標志位

DMA_FLAG_TC1  通道 1 傳輸完成標志位

DMA_FLAG_HT1  通道 1 傳輸過半標志位

DMA_FLAG_TE1  通道 1 傳輸錯誤標志位

DMA_FLAG_GL2  通道 2 全局標志位

DMA_FLAG_TC2  通道 2 傳輸完成標志位

DMA_FLAG_HT2  通道 2 傳輸過半標志位

DMA_FLAG_TE2  通道 2 傳輸錯誤標志位

DMA_FLAG_GL3  通道 3 全局標志位

DMA_FLAG_TC3  通道 3 傳輸完成標志位

DMA_FLAG_HT3  通道 3 傳輸過半標志位

DMA_FLAG_TE3  通道 3 傳輸錯誤標志位

DMA_FLAG_GL4  通道 4 全局標志位

DMA_FLAG_TC4  通道 4 傳輸完成標志位

DMA_FLAG_HT4  通道 4 傳輸過半標志位

DMA_FLAG_TE4  通道 4 傳輸錯誤標志位

DMA_FLAG_GL5  通道 5 全局標志位

DMA_FLAG_TC5  通道 5 傳輸完成標志位

DMA_FLAG_HT5  通道 5 傳輸過半標志位

DMA_FLAG_TE5  通道 5 傳輸錯誤標志位

DMA_FLAG_GL6  通道 6 全局標志位

DMA_FLAG_TC6  通道 6 傳輸完成標志位

DMA_FLAG_HT6  通道 6 傳輸過半標志位

DMA_FLAG_TE6  通道 6 傳輸錯誤標志位

DMA_FLAG_GL7  通道 7 全局標志位

DMA_FLAG_TC7  通道 7 傳輸完成標志位

DMA_FLAG_HT7  通道 7 傳輸過半標志位

DMA_FLAG_TE7  通道 7 傳輸錯誤標志位

*/


獲取當前剩余數據量大小的函數:(有時候還是可以用到)

uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx);

實際功能效果圖

DMA實現USART1收發送數據程序

通過查資料,多次調試,最總完成了這次任務。

使用USART1中斷+MDA實現接收數據,PE4接的按鍵,按下一次通過MDA發送數據一次到USART1。


#include "stm32f10x.h" 

#include "stdio.h"

#include "string.h"

int fputc(int ch, FILE *f)

{

  while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);

  USART_SendData(USART1,(uint8_t)ch);

  return ch;

}


#define UART_RX_LEN 128

/*串口發送DMA緩存*/

uint8_t SendBuff[UART_RX_LEN]={"zxcvbnm,asdfghjkl"};

/*串口接收DMA緩存*/

uint8_t Uart_Rx[UART_RX_LEN] = {0};

uint8_t Data_Receive_Usart=0;

void delay_ms(u16 time)

{    

   u16 i = 0;  

   while(time--)

   {

      i = 12000;  

      while(i--);    

   }

}


//串口初始化

void Usart_Init(void)

  GPIO_InitTypeDef GPIO_ITDef1;

  GPIO_InitTypeDef GPIO_ITDef;

  USART_InitTypeDef  USART_ITDef;

//掛載時鐘(復用PA) 串口時鐘使能,GPIO 時鐘使能,復用時鐘使能

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA,ENABLE);

//PA9 TXD初始化

  GPIO_ITDef.GPIO_Pin = GPIO_Pin_9;//PA9 TXD

  GPIO_ITDef.GPIO_Mode = GPIO_Mode_AF_PP;////復用推挽輸出

  GPIO_ITDef.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA,&GPIO_ITDef);

//PA10 TXD初始化

  GPIO_ITDef1.GPIO_Pin = GPIO_Pin_10;//PA10 RXD

  GPIO_ITDef1.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空輸入

  GPIO_Init(GPIOA,&GPIO_ITDef1);

  

//USART初始化

  USART_ITDef.USART_BaudRate = 115200;//波特率

  USART_ITDef.USART_WordLength = USART_WordLength_8b;//發送數據長度

  USART_ITDef.USART_StopBits = USART_StopBits_1; //一個停止位   

  USART_ITDef.USART_Parity = USART_Parity_No; //無奇偶校驗位     

  USART_ITDef.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬件數據流控制

  USART_ITDef.USART_Mode = USART_Mode_Tx| USART_Mode_Rx ;//發送模式 

  USART_Init(USART1,&USART_ITDef);

  /*中斷配置*/

  USART_ITConfig(USART1,USART_IT_TC,DISABLE);

  USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);

  USART_ITConfig(USART1,USART_IT_IDLE,ENABLE);

  

   NVIC_InitTypeDef NVIC_InitStructure;

  //配置UART1中斷  

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);

  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;              //通道設置為串口1中斷  

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;      //中斷占先等級0  

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;             //中斷響應優先級0  

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                //打開中斷  

  NVIC_Init(&NVIC_InitStructure);

 

  USART_Cmd(USART1, ENABLE);//使能串口

}

void MDA_USART1_Init(void)

{   

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能 DMA 時鐘

  DMA_Cmd(DMA1_Channel4,DISABLE);

  DMA_DeInit(DMA1_Channel4); //將 DMA 的通道 1 寄存器重設為缺省值

  DMA_InitTypeDef DMA_InitStructure;

  

  DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART1->DR);  //DMA外設基地址

  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff;  //DMA內存基地址

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  //數據傳輸方向,從內存讀取發送到外設

  DMA_InitStructure.DMA_BufferSize = UART_RX_LEN;  //DMA通道的DMA緩存的大小

  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外設地址寄存器不變

  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //內存地址寄存器遞增

  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  //數據寬度為8位

  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //數據寬度為8位

  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  //工作在正常模式

  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; //DMA通道 x擁有中優先級 

  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMA通道x沒有設置為內存到內存傳輸

  DMA_Init(DMA1_Channel4, &DMA_InitStructure);  //根據DMA_InitStruct中指定的參數初始化DMA的通道USART1_Tx_DMA_Channel所標識的寄存器

  

  /*DMA1通道5配置接收*/

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);

  DMA_DeInit(DMA1_Channel5);

  DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART1->DR);

  //串口的發送和接收stm32都存在同一寄存器的;51和cc2530是發送和接收用單獨的寄存器存數據;我們要其他內設使用DMA,就得清楚當前設備在stm32存數據的寄存器。(stm32數據手冊都有介紹)

  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Uart_Rx;

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

  DMA_InitStructure.DMA_BufferSize = UART_RX_LEN;

  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_Normal;

  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;

  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

  DMA_Init(DMA1_Channel5,&DMA_InitStructure);

 //主要通過按鍵來發送數據,所以這里沒有使能通道4(一旦使能就將發送一次數據)

/*使能接收通道5*/

  DMA_Cmd(DMA1_Channel5,ENABLE); 

//采用DMA方式發送

  USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE); //采用DMA方式接收

  USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);

    //啟動串口  

  USART_Cmd(USART1, ENABLE);

}

/*

 * 啟動DMA數據發送功能

 *size表示需要發送的DMA中數據的個數

*/

void uart_dma_send_enabl(uint16_t size)

{

    DMA1_Channel4->CNDTR = (uint16_t)size; 

    DMA_Cmd(DMA1_Channel4, ENABLE);       

}

void USART1_IRQHandler(void)                               

{   

    memset(SendBuff,0,UART_RX_LEN);//清空發送數組

    uint32_t temp = 0;

    uint16_t i = 0;

    if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)

    {

        

[1] [2]
關鍵字:STM32  固件庫  DMA  USART1  發送數據 引用地址:STM32基于固件庫學習筆記(6)使用DMA實現USART1發送數據

上一篇:STM32基于固件庫學習筆記(13)ADC讀取電壓值
下一篇:STM32F4學習筆記之GPIO(使用固件庫)

推薦閱讀

蘋果公司CEO蒂姆·庫克(Tim Cook)日前在接受采訪時,被問及蘋果將如何利用手中巨額現金,庫克稱蘋果未來數年將在美國投資300億美元,用于建設新園區,并招聘約2萬名員工。?蘋果今年年初曾表示,計劃撤回海外巨額資金,這將為美國帶來約380億美元的稅收。按照新稅法規定的15.5%的企業應繳稅率,380億美元的稅收意味著蘋果將從海外撤回2450億美元的資金。
群聯(Phison) 表示固態硬盤的傳輸速度在2020年有望達到6.5GB/s(6500MB/s)。目前影馳、十銓、技嘉、海盜船、博帝、Essencore/Klevv等廠商已經推出了采用群聯PS5016-E16主控的PCIe 4.0固態硬盤,連續讀取速度大約有5GB/s,而相比而言目前最新的NVMe固態硬盤的連續讀取性能在3.5GB/s左右。 群聯PS5016-E16作為全新旗艦型號,采用雙核心CoXProcessor處...
1.要對MSP430要有本質的理解:對于MSP430的C程序編程,對于模塊的初始化、數據的讀寫、信號輸入輸出都是對寄存器的操作。2.要正確設置系統時鐘。MSP430最大的特點是低耗,能實現低功耗的主要原因是引入了時鐘系統的概念。正確設置系統時鐘,才能正確把握定時器、UART、LCD顯示的正確使用。3.要具有模塊化的編程思想。要用軟件工程的方法,采用VC++的工程管...
據外媒報道,功率電子器件技術領導者Eggtronic宣布,推出混合無線交流電源專利技術E2WATT,可同時作為交流電源和高速無線傳輸系統中的發射器,從而確保能量效率和能量傳輸距離,但其成本低于傳統無線技術。(圖片來源:eetimes)傳統Qi無線設備的傳輸距離通常為5mm,最大傳輸功率通常最高為30W。E2WATT技術可在超過其6倍的距離(可達40mm)內,提供高達300...

史海拾趣

小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 霍林郭勒市| 奎屯市| 沁阳市| 盐津县| 新蔡县| 大安市| 同德县| 平舆县| 桃江县| 青岛市| 武汉市| 余姚市| 佛冈县| 临潭县| 卢氏县| 永川市| 正镶白旗| 胶州市| 乐平市| 武穴市| 新龙县| 乌恰县| 台东县| 怀安县| 黎城县| 富蕴县| 新源县| 罗定市| 海门市| 正镶白旗| 青龙| 内江市| 新泰市| 潜山县| 龙游县| 宽城| 株洲县| 高碑店市| 牟定县| 榕江县| 苏州市|