stm32寄存器版學習筆記08 DMA

来源:http://www.cnblogs.com/kuotian/archive/2016/07/13/5668707.html
-Advertisement-
Play Games

DMA(Direct Memory Access),直接存儲器訪問。DMA傳輸方式無需CPU直接控制傳輸,通過硬體為RAM與I/O設備開闢一條直接傳送數據的通路,使CPU效率大大提高。stm32f103有2個DMA控制器,DMA1有7個通道,DMA2有5個通道,專門用來管理來自外設對存儲器的訪問請求 ...


  DMA(Direct Memory Access),直接存儲器訪問。DMA傳輸方式無需CPU直接控制傳輸,通過硬體為RAM與I/O設備開闢一條直接傳送數據的通路,使CPU效率大大提高。stm32f103有2個DMA控制器,DMA1有7個通道,DMA2有5個通道,專門用來管理來自外設對存儲器的訪問請求,還有一個仲裁器來協調各個DMA請求的優先權。

 

1.DMA各通道請求

  從外設產生的DMA請求通過邏輯"或"輸入到DMA控制器,這就意味著同時只能有一個請求有效。

  例如,串口1發送的DMA,就要用到DMA1的通道4。

 

2.DMA1通道4(串口1發送)配置步驟

①設置外設地址

  設置外設地址通過DMA1_CPAR4來設置,在這個寄存器裡面寫入&USART1_DR的值。該地址將作為DMA傳輸的目標地址。

  DMA通道x外設地址寄存器(DMA_CPARx)(x = 1…7)

  Eg:DMA_CHx->CPAR=cpar; //DMA1 外設地址 

     DMA_CHx->CPAR=&USART1_DR;

②設置存儲器地址

  設置存儲器地址通過DMA1_CMAR4來設置,假設要把數組SendBuf作為存儲器,在該寄存器寫入&SendBuf的值。該地址將作為DMA傳輸的源地址

  Eg:DMA_CHx->CMAR=(u32)cmar; //DMA1,存儲器地址

 

③設置傳輸數據量

  寫入此次要傳輸的數據量,也就是SendBuf的大小。該寄存器在DMA啟動後自減,每次新的DMA傳輸都重新向該寄存器寫入要傳輸的數據量。

  DMA通道x傳輸數量寄存器(DMA_CNDTRx)(x = 1…7)

 

  Eg:DMA_CHx->CNDTR=cndtr;     //DMA1,傳輸數據量

 

④設置通道4的配置信息

  若有多個通道,則要設置優先順序,編號越小優先順序越高。

  DMA通道x配置寄存器(DMA_CCRx)(x = 1…7)

 

⑤使能DMA1通道4,啟動傳輸

  DMAx_CCRx 最低位開啟DMA傳輸。註意要設置USART1的使能DMA傳輸位,通過USART1->CR3的第七位設置,這樣就可以啟動一次USART1的DMA傳輸了。

 

3.DMA中斷狀態顯示及清除

  DMA中斷狀態寄存器(DMA_ISR)

 

  DMA中斷標誌清除寄存器(DMA_IFCR)

  Eg:if(DMA1->ISR&(1<<13))//等待通道4傳輸完成
     {
       DMA1->IFCR|=1<<13;//清除通道4傳輸完成標誌
       break;
     }

 

4.DMA1通道4(串口1發送)應用

 1 u16 DMA1_MEM_LEN;//保存DMA每次數據傳送的長度             
 2 //DMA1的各通道配置
 3 //這裡的傳輸形式是固定的,這點要根據不同的情況來修改
 4 //從存儲器->外設模式/8位數據寬度/存儲器增量模式
 5 //DMA_CHx:DMA通道CHx
 6 //cpar:外設地址
 7 //cmar:存儲器地址
 8 //cndtr:數據傳輸量  
 9 void MYDMA_Config(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
10 {
11     RCC->AHBENR|=1<<0;            //開啟DMA1時鐘
12     delay_ms(5);                //等待DMA時鐘穩定
13     DMA_CHx->CPAR=cpar;          //DMA1 外設地址 
14     DMA_CHx->CMAR=(u32)cmar;     //DMA1,存儲器地址
15     DMA1_MEM_LEN=cndtr;          //保存DMA傳輸數據量
16     DMA_CHx->CNDTR=cndtr;        //DMA1,傳輸數據量
17     DMA_CHx->CCR=0X00000000;    //複位
18     DMA_CHx->CCR|=1<<4;          //從存儲器讀
19     DMA_CHx->CCR|=0<<5;          //普通模式
20     DMA_CHx->CCR|=0<<6;         //外設地址非增量模式
21     DMA_CHx->CCR|=1<<7;          //存儲器增量模式
22     DMA_CHx->CCR|=0<<8;          //外設數據寬度為8位
23     DMA_CHx->CCR|=0<<10;         //存儲器數據寬度8位
24     DMA_CHx->CCR|=1<<12;         //中等優先順序
25     DMA_CHx->CCR|=0<<14;         //非存儲器到存儲器模式              
26 } 
27 //開啟一次DMA傳輸
28 void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx)
29 {
30     DMA_CHx->CCR&=~(1<<0);       //關閉DMA傳輸 
31     DMA_CHx->CNDTR=DMA1_MEM_LEN; //DMA1,傳輸數據量 
32     DMA_CHx->CCR|=1<<0;          //開啟DMA傳輸
33 }      
DMA.c
 1 const u8 TEXT_TO_SEND[]={"STM32 DMA USART1"};
 2 #define TEXT_LENTH  sizeof(TEXT_TO_SEND)-1            //TEXT_TO_SEND字元串長度(不包含結束符)
 3 u8 SendBuff[(TEXT_LENTH+2)*100];
 4 
 5 int main(void)
 6 {    
 7     u16 i;
 8     u8 t=0; 
 9     float pro=0;            //進度 
10      Stm32_Clock_Init(9);    //系統時鐘設置
11     uart_init(72,9600);         //串口初始化為9600
12     delay_init(72);                //延時初始化 
13     LED_Init();                  //初始化與LED連接的硬體介面
14     LCD_Init();                   //初始化LCD 
15     KEY_Init();                //按鍵初始化             
16      MYDMA_Config(DMA1_Channel4,(u32)&USART1->DR,(u32)SendBuff,(TEXT_LENTH+2)*100);//DMA1通道4,外設為串口1,存儲器為SendBuff,長(TEXT_LENTH+2)*100.
17      POINT_COLOR=RED;//設置字體為紅色 
18     //顯示提示信息       
19     for(i=0;i<(TEXT_LENTH+2)*100;i++)//填充ASCII字元集數據
20     {
21         if(t>=TEXT_LENTH)//加入換行符
22         { 
23             SendBuff[i++]=0x0d; 
24             SendBuff[i]=0x0a; 
25             t=0;
26         }else SendBuff[i]=TEXT_TO_SEND[t++];//複製TEXT_TO_SEND語句    
27     }         
28     POINT_COLOR=BLUE;//設置字體為藍色      
29     i=0;
30     while(1)
31     {
32         t=KEY_Scan(0);
33         if(t==KEY0_PRES)//KEY0按下
34         {
35             LCD_ShowString(60,150,200,16,16,"Start Transimit....");
36             LCD_ShowString(60,170,200,16,16,"   %");//顯示百分號
37             printf("\r\nDMA DATA:\r\n ");         
38             USART1->CR3=1<<7;           //使能串口1的DMA發送       
39             MYDMA_Enable(DMA1_Channel4);//開始一次DMA傳輸!      
40             //等待DMA傳輸完成,此時我們來做另外一些事,點燈
41             //實際應用中,傳輸數據期間,可以執行另外的任務
42             while(1)
43             {
44                 if(DMA1->ISR&(1<<13))//等待通道4傳輸完成
45                 {
46                     DMA1->IFCR|=1<<13;//清除通道4傳輸完成標誌
47                     break; 
48                 }
49                 pro=DMA1_Channel4->CNDTR;//得到當前還剩餘多少個數據
50                 pro=1-pro/((TEXT_LENTH+2)*100);//得到百分比      
51                 pro*=100;      //擴大100倍
52                 LCD_ShowNum(60,170,pro,3,16);      
53             }                
54             LCD_ShowNum(60,170,100,3,16);//顯示100%      
55             LCD_ShowString(60,150,200,16,16,"Transimit Finished!");//提示傳送完成
56         }
57         i++;
58         delay_ms(10);
59         if(i==20)
60         {
61             LED0=!LED0;//提示系統正在運行    
62             i=0;
63         }           
64     }
65 }
main.c

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 關於文件狀態 一般倉庫中的文件可能存在於這4種狀態: 1)Untracked files → 文件未被跟蹤(A) 2)Untracked but not Change → 已跟蹤,但是未修改(B) 3)Changes but not updated → 已跟蹤,文件被修改,但並沒有添加到暫存區(C) ...
  • 問題癥狀: Android Studio 1.2 (Build 141.1890965) 新建工程,自動build完成後,Layout Editor無法預覽Layout文件,報錯內容: Rendering Problems The following classes could not be fou ...
  • 主要練習一下RelativeLayout和LinearLayout ...
  • 預設情況下,有以下控制項已經支持UIMenuController UITextField UITextView UIWedView 以UITable為例,說明點擊後彈出複製剪切粘貼等為例 使用的整體思路:(系統自帶的文字) 1、新建一個UILabel的類,如果想以後storyboard和Xib都可以用 ...
  • 最近在做的新聞客戶端用到了ViewPager,Android Studio如今集成的很好了,自動創建很多不必要寫的代碼。 在使用過程中碰到了一個很奇怪的事:ViewPager中載入的數據重覆 具體的看圖就明白了: 可以看到載入出來的數據,1、2頁面出現了重覆,而3恢復正常 在困擾許久之後博主在sta ...
  • 我們知道在iOS開發時,控制項UITextField有個placeholder屬性,UITextField和UITextView使用方法基本類似,有兩個小區別:1.UITextField單行輸入,而UITextView可以多行輸入。2.UITextField有placeholder屬性,而UIText ...
  • cocoapods簡介: cocoapods簡介: cocoapods 是iOS的類庫管理工具,可以讓開發者很方便集成各種第三方庫,而不用去網站上一個個下載,再一個個文件夾的拖進項目中,還得添加相關的系統依賴庫。只需要安裝好cocoapods,然後編寫好Podfile,最好在終端輸入一行命令,就可以 ...
  • 在生產環境下麵對紛繁的業務處理場景,我們知道要處理很多邏輯代碼,其中有個叫枚舉(也稱窮舉),當處理這類事務時,會產生大量的迴圈執行,而迴圈是最耗CPU的,大量的迭代計算,可直接拉低計算速度,怎麼處理這類問題呢? 對於事務的不定項的選擇幾率,都會有一定的規律,比如說事件的概率發生,根據概率論的知識,我 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...