这里有个小小的例子,来演示DMA模块与系统程序并行工作。 用串口以低波特率发送一个10K的数据,花费近10s时间,此时按照以往方法,CPU要不断等待数据发送、送数据;或者送数据、进中断、送数据,处理起来比较消耗时间。9 Q) i6 H. i: @ d2 }$ Y 使用了DMA功能以后,用户程序中只需配置好DMA,开启传输后,再也不需要操心,10K数据完成后会有标志位或中断产生,期间可以做任何想做的事,非常方便。 这个是相应的代码例子,基于STM32F103VBT6: b& u$ @4 n3 x: b" F n' V' y : W: [" L3 E" h% z /****************************************************************************** * 本文件实现串口发送功能(通过重构putchar函数,调用printf;或者USART_SendData()7 B. X5 P8 y0 S6 X5 m" p) H% M * 这里是一个用串口实现大量数据传输的例子,使用了DMA模块进行内存到USART的传输 * 每当USART的发送缓冲区空时,USART模块产生一个DMA事件, * 此时DMA模块响应该事件,自动从预先定义好的发送缓冲区中拿出下一个字节送给USART- P9 _$ t% N. S2 h' j5 V* O2 e * 整个过程无需用户程序干预,用户只需启动DMA传输传输即可% f8 J1 e, M/ F- T$ G * 在仿真器调试时,可以在数据传输过程中暂停运行,此时DMA模块并没有停止 * 串口依然发送,表明DMA传输是一个独立的过程。+ N3 i6 Z3 }. Z: C$ _ * 同时开启接收中断,在串口中断中将数据存入缓冲区,在main主循环中处理9 ^- m# q* R0 g$ l' Q5 ?& M * 作者:jjldc(九九)& c& `0 b- W$ u' _ * 代码硬件基于万利199元的EK-STM32F开发板,CPU=STM32F103VBT6 *******************************************************************************/ /* Includes ------------------------------------------------------------------*/: u# e; p/ \0 \: j1 F0 a% v) x #include "stm32f10x_lib.h" #include "stdio.h"/ `9 b4 ]1 a# L9 n 6 ]; M) s; k) _" y6 z9 t /* Private typedef -----------------------------------------------------------*/+ T+ i7 f$ R3 ^% W+ l, ] /* Private define ------------------------------------------------------------*/ #define USART1_DR_Base 0x400138041 V% e) X4 z; e1 J ^" H- s2 l /* Private macro -------------------------------------------------------------*/* o3 x, E" W( b /* Private variables ---------------------------------------------------------*/ #define SENDBUFF_SIZE 10240 vu8 SendBuff[SENDBUFF_SIZE];( E# P5 |4 ]& u! N1 n: o4 g vu8 RecvBuff[10];& K6 N4 a- n) V% g: y. @& u vu8 recv_ptr; ! V+ T" e( H; b7 Z6 d7 C /* Private function prototypes -----------------------------------------------*/ void RCC_Configuration(void); void GPIO_Configuration(void);9 E4 O. o- C0 o0 @, w, e void NVIC_Configuration(void);# {1 K+ A8 S9 b6 w' N% ~# X void DMA_Configuration(void); void USART1_Configuration(void);; f* A6 r" _# k7 b; k4 H* y int fputc(int ch, FILE *f); void Delay(void);! B0 F( r1 [8 o# k* E) s- A3 Y $ I+ M- P" H/ e /* Private functions ---------------------------------------------------------*/8 K/ S4 W+ v% |5 s( m /******************************************************************************** [ r4 q7 n! N ^8 e& A * Function Name : main * Description : Main program.8 X6 y d2 m4 n \ * Input : None, Q+ S/ A6 l/ y/ |% Q * Output : None5 V/ i- v, A. p8 j1 { * Return : None *******************************************************************************/! p' f( S0 }/ M" a7 I: m8 M u int main(void)) m7 e. S' r! [. l' ^ { u16 i; #ifdef DEBUG debug();3 |$ g! ~- c& a# L* K #endif, |* M6 b: F8 B7 x# R+ j recv_ptr = 0; : J( ^ [$ |9 ? E, L RCC_Configuration(); GPIO_Configuration();# N2 o8 R' n6 t9 X D: \( ^* a NVIC_Configuration(); DMA_Configuration();1 G/ B) {- f) ~& E! u% j* x USART1_Configuration();- D, u( x6 y _: c printf("\r\nSystem Start...\r\n"); printf("Initialling SendBuff... \r\n"); for(i=0;i {9 p0 t6 b7 J, S7 e# s4 t/ }: c SendBuff = i&0xff; }6 @ _0 H- P/ s% I printf("Initial success!\r\nWaiting for transmission...\r\n"); //发送去数据已经准备好,按下按键即开始传输5 P2 o4 p! z' x5 _' ]1 Q5 X5 V! M( Q while(GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_3)); printf("Start DMA transmission!\r\n"); //这里是开始DMA传输前的一些准备工作,将USART1模块设置成DMA方式工作 USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); //开始一次DMA传输!1 j' t% D+ H9 Z DMA_Cmd(DMA1_Channel4, ENABLE);# R# r- g3 K, N8 g9 ?. x M. F: A( C //等待DMA传输完成,此时我们来做另外一些事,点灯 //实际应用中,传输数据期间,可以执行另外的任务1 j5 |7 L+ I3 L t P4 f! @ while(DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET); Z* V( [; }+ M' e- q! d3 l# U {. `0 { z4 u6 J0 ~" \* K+ q LED_1_REV; //LED翻转# m5 \7 t; u$ d Delay(); //浪费时间! _' h/ I$ e' ^/ P. b } //DMA传输结束后,自动关闭了DMA通道,而无需手动关闭 //下面的语句被注释 //DMA_Cmd(DMA1_Channel4, DISABLE);6 u; e) L# D4 q - A, }. w! H1 k printf("\r\nDMA transmission successful!\r\n"); o7 Z# C5 m- T! Z+ o3 y! f 1 P- C$ L( G; c4 ]- c" {- `$ F2 @ & p y: z. _' E# S /* Infinite loop */9 w, F* f# ?' V# g4 g9 t while (1) {4 w) E+ q8 |0 E% E8 F }, T. m. @+ M, z% R6 O } " u/ n4 O( `: T+ C6 n /*******************************************************************************$ X9 m8 `% x6 z" Q' e* g * Function Name : 重定义系统putchar函数int fputc(int ch, FILE *f)# T4 R$ p2 |. k * Description : 串口发一个字节, C$ }, C1 S- o/ F# c' ^# b * Input : int ch, FILE *f- _6 A; k/ Y4 D. K$ E+ N* e, k * Output : * Return : int ch- J) i$ ~# b. |# F: g. J * 这个是使用printf的关键! g' ~7 J- D; v& f *******************************************************************************/5 C5 E5 s6 n# r; r4 d; h int fputc(int ch, FILE *f); B: i( j& E( H: T0 n { //USART_SendData(USART1, (u8) ch);; {. b* A7 {+ _ USART1->DR = (u8) ch;3 R8 e; W" r4 F+ h /* Loop until the end of transmission */% x# }, h1 n) l9 w* V. l( A$ T while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) { } : L/ L0 O6 x7 N) n return ch;9 o9 r, y) {7 Y; Z- W; S6 g }: S+ _) O3 q( n; ?, a /*******************************************************************************/ U' A" n- ]& S2 K * Function Name : Delay * Description : 延时函数 * Input : None( x6 B _9 W8 R: M1 b( e' Q- V * Output : None * Return : None( F" W0 c0 E0 _ *******************************************************************************/ void Delay(void)( J* J5 d$ N! W$ f& A1 I2 Q) ^ {, S, p6 A9 f4 t u32 i;' W$ `' Q! f @0 r _ for(i=0;i外设 //每次传输位:8bit+ i) q1 E1 `! {9 U //传输大小DMA_BufferSize=SENDBUFF_SIZE$ m7 T2 O s& t1 T. M //地址自增模式:外设地址不增,内存地址自增1 //DMA模式:一次传输,非循环 //优先级:中 DMA_DeInit(DMA1_Channel4);- @3 N5 w/ A! a5 f( \0 r# c9 W2 N DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base; DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff;0 \5 M8 Y! k2 [. V1 W DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;+ Z1 J$ s. t" s" M DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;9 j, i7 j( o' o( h; F DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;1 |& |8 N3 X1 G2 A9 v) v DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;* t h$ @- x' _2 R9 @# L DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;& |7 X6 G) G* j5 \- Y) [ DMA_Init(DMA1_Channel4, &DMA_InitStructure);1 i, T; _7 v7 _+ w& _ } |
RE:STM32笔记(四)DMA、USART的演示
回复:STM32笔记(四)DMA、USART的演示
ä¾å.rar
2014-10-22 16:32 上传
点击文件名下载附件
174.52 KB, 下载次数: 346
RE:STM32笔记(四)DMA、USART的演示
回复:STM32笔记(四)DMA、USART的演示
回复:STM32笔记(四)DMA、USART的演示
RE:STM32笔记(四)DMA、USART的演示
RE:STM32笔记(四)DMA、USART的演示
回复:STM32笔记(四)DMA、USART的演示
回复:STM32笔记(四)DMA、USART的演示
RE:STM32笔记(四)DMA、USART的演示
回复:STM32笔记(四)DMA、USART的演示
RE:STM32笔记(四)DMA、USART的演示
回复:STM32笔记(四)DMA、USART的演示
回复:STM32笔记(四)DMA、USART的演示
( r0 h' J0 |# m0 Z% z% Z
! C7 q6 w* V! S" B4 I) e8 R
haodongxi 好东西启封箱