你的浏览器版本过低,可能导致网站不能正常访问!为了你能正常使用网站功能,请使用这些浏览器。
原帖由私奔于2009-01-04 14:30发表: & E) j8 A- Q p. o% B 这里有个小小的例子,来演示DMA模块与系统程序并行工作。$ _) r2 l' U3 w 用串口以低波特率发送一个10K的数据,花费近10s时间,此时按照以往方法,CPU要不断等待数据发送、送数据;或者送数据、进中断、送数据,处理起来比较消耗时间。$ z0 ^1 H W' A* `7 v: B$ D9 l 使用了DMA功能以后,用户程序中只需配置好DMA,开启传输后,再也不需要操心,10K数据完成后会有标志位或中断产生,期间可以做任何想做的事,非常方便。6 Z/ H& l% H0 f1 }1 K9 T 这个是相应的代码例子,基于STM32F103VBT6: C/ Y( U& Q- z) v1 J 4 h1 K5 v& {4 _9 o) G5 s* jsdf / F! z# I5 c* b0 m0 z' v/****************************************************************************** $ I; d: c6 r6 X! }( U* 本文件实现串口发送功能(通过重构putchar函数,调用printf;或者USART_SendData() : L) ~! o1 }3 l% W* 这里是一个用串口实现大量数据传输的例子,使用了DMA模块进行内存到USART的传输 7 a7 }9 j- m5 V3 u- d! U; x3 @6 X" U* 每当USART的发送缓冲区空时,USART模块产生一个DMA事件,1 Y' @/ m; c1 ]& V! ? * 此时DMA模块响应该事件,自动从预先定义好的发送缓冲区中拿出下一个字节送给USART ( s5 w2 y. G* f9 Z% P* 整个过程无需用户程序干预,用户只需启动DMA传输传输即可 ( r& F' I J |; X T( O* 在仿真器调试时,可以在数据传输过程中暂停运行,此时DMA模块并没有停止 : ?( j3 \7 O' H. V/ S' H) W* 串口依然发送,表明DMA传输是一个独立的过程。 # K/ I- G+ Q p# ^* 同时开启接收中断,在串口中断中将数据存入缓冲区,在main主循环中处理8 V* Q8 e( \0 k, Q. b# m$ k * 作者:jjldc(九九)1 h) _" [2 Q$ }# k8 M5 M; S * 代码硬件基于万利199元的EK-STM32F开发板,CPU=STM32F103VBT6 & L4 \) K' Q/ [. Y- z& h*******************************************************************************/ . ` C' b6 }7 ]) h % ~1 n, ^& C4 m' g/* Includes ------------------------------------------------------------------*/3 U' o- j& I1 H- O4 y6 o/ o; b #include "stm32f10x_lib.h" & X4 T9 s; c3 S#include "stdio.h": x& v# M8 q1 g! [8 B. y2 u$ F) l* _ * R2 E E- M9 J! \+ F* p* |/* Private typedef -----------------------------------------------------------*/* B" B1 w5 H6 ?; W) p /* Private define ------------------------------------------------------------*/6 Z' e$ z! j: _- D6 \' l1 k #define USART1_DR_Base 0x40013804 " z% L, J4 d: A. g0 A1 d& p; @3 d, U3 ]4 z% S( z& B! z /* Private macro -------------------------------------------------------------*/+ R7 F2 z, d h /* Private variables ---------------------------------------------------------*/ @' V$ ^+ B6 f1 H7 p #define SENDBUFF_SIZE 10240: v) l) L& V6 N vu8 SendBuff[SENDBUFF_SIZE]; Z+ [6 \' g5 \" `! b3 Rvu8 RecvBuff[10]; 6 S. w3 i* i& Y* K! C% q& Svu8 recv_ptr; 3 W/ U) q# \/ S: P, m , o; R" E8 W3 E/* Private function prototypes -----------------------------------------------*/: l8 `, o1 s0 ^. o void RCC_Configuration(void);5 v% C, O4 X+ S. ] }5 f( r void GPIO_Configuration(void);8 K3 e' Y% L$ ?) d. S void NVIC_Configuration(void);& z( @8 i+ \. N% n6 K! k; Z void DMA_Configuration(void); 8 k9 O/ v! |3 n; {void USART1_Configuration(void);; b) B- O: x4 t7 U5 {2 b ! n$ T- V/ F1 n/ A& [9 p+ @ int fputc(int ch, FILE *f); $ d* A; m6 l. @5 l) Y9 Ivoid Delay(void); " ~2 L" Y, x4 H" Y# K# w) G* p: e7 t; y/ G /* Private functions ---------------------------------------------------------*/ ; _: B% B: o& `8 R+ e4 U* q/******************************************************************************* ( Z3 H! l( R! I* Function Name : main' \; N3 G+ }8 M7 J: u * Description : Main program.! p/ u. D, q! v! j: D' ` * Input : None7 O5 e3 J* d4 O * Output : None 5 |! N) z2 l& F: h3 J# o* Return : None3 g9 Z" X3 h3 K *******************************************************************************/ ; \6 l) _2 b$ B9 [" \& `# qint main(void) ! M+ Q, u+ u& M+ r3 V{ $ Y4 ~' K' M# c6 T: T: U u16 i;% p* b6 u9 k5 M6 ` #ifdef DEBUG + o6 t8 X0 e4 P7 g/ o3 v6 Q$ C1 Z) P debug(); # S5 G2 ^% L" s1 d#endif * p3 K7 b, p1 A recv_ptr = 0;5 W/ z: x& |3 E' [1 \3 s0 E 5 O4 ]3 x( v0 C5 Z0 C RCC_Configuration(); 7 F a8 x# f: \$ C0 a/ N" s7 H9 p6 z GPIO_Configuration(); ! M) H% y) y B NVIC_Configuration();# e5 B! N2 p6 ~" R R' {9 C DMA_Configuration(); 9 k. B1 g3 O& Y$ C( D USART1_Configuration();- v0 W7 z9 B3 X& F & a0 ~4 g5 o! Q5 U/ Z printf("\r\nSystem Start...\r\n"); & M6 E; C! F3 W. K- v6 \ printf("Initialling SendBuff... \r\n");3 Z" d ?& {9 t for(i=0;i {' v4 o0 t I: n W* l SendBuff = i&0xff; . Q, U# Q! U" x# m- D }' r" w* Z4 p6 r. T7 Z printf("Initial success!\r\nWaiting for transmission...\r\n");5 y! q) g, J, m" q8 b //发送去数据已经准备好,按下按键即开始传输 z! A6 ]* t4 O6 P, @. ~1 T while(GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_3)); x3 a, a5 V3 e0 J6 L ~6 A; Y 2 ?% p4 ?# o8 j; F9 o printf("Start DMA transmission!\r\n");% g% x5 y! w' d6 t% t' Z # N" t8 ~! E* c9 ? //这里是开始DMA传输前的一些准备工作,将USART1模块设置成DMA方式工作- u6 W0 X! o% n& |: p USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);, g$ j9 f+ r- t0 B2 N4 Z. M //开始一次DMA传输!3 V8 j5 ~, o* u+ Q9 [9 m DMA_Cmd(DMA1_Channel4, ENABLE);( }; c9 l! u, N! O : N+ q3 n9 b# q2 H //等待DMA传输完成,此时我们来做另外一些事,点灯 0 U1 O9 F" G* F: c" d( o //实际应用中,传输数据期间,可以执行另外的任务 , _( @* [0 |8 n" o8 ` j6 o) a' i" Z while(DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET)7 M: u2 w+ c- m { 3 _% C# A4 C. U! ]( I! A8 E LED_1_REV; //LED翻转& J' R0 G; i$ s4 w& v$ U" Q; ]" ?8 w Delay(); //浪费时间 , n0 `4 N. X) B# N }; ]) u- q1 D4 Q //DMA传输结束后,自动关闭了DMA通道,而无需手动关闭$ b$ z; a0 ?1 o8 |3 m# w( W- d$ h //下面的语句被注释+ u, X8 ~6 v2 ^ //DMA_Cmd(DMA1_Channel4, DISABLE); ; S, H |" X6 h6 ]( z/ C8 p- M 0 }/ q5 M3 A5 q5 ]) ? printf("\r\nDMA transmission successful!\r\n");2 X0 H0 w$ a1 u9 } b* ?' V& Q% v 8 }6 V' D5 R3 K8 K; x! v 2 S6 j2 W: j& r( o* v* S m /* Infinite loop */ / k/ l( O: H7 B" M( X# ^: ^ while (1)7 e5 M% M4 W% D9 F+ ~; h! ^6 l { * H# R+ t0 s; ^* G8 I. w } }. p/ a$ g! h9 V/ j } ( h4 o$ y. E3 Z$ U+ m: K " M7 l( i0 b4 | R6 E9 V6 K( x/******************************************************************************* 8 B/ u& \ H1 u) K/ G+ B* Function Name : 重定义系统putchar函数int fputc(int ch, FILE *f) & ~/ W0 _% q$ K+ N( ` h* ]$ k; S* Description : 串口发一个字节1 G4 D6 m% s: {9 R g * Input : int ch, FILE *f3 U7 m1 _. t# ^# y6 u * Output : $ H$ d; \* [- a; l * Return : int ch# |* G+ G) R0 a% ^1 v, C * 这个是使用printf的关键 ; N4 F2 K6 i1 m/ x) L*******************************************************************************/ ; d9 J0 w- I( F+ x, Y7 Y5 T' K$ sint fputc(int ch, FILE *f)1 H" w1 m7 J0 }& s( v {( x6 r) g# o5 @1 B$ ` //USART_SendData(USART1, (u8) ch);1 K$ Q" [$ \; d, `/ N7 N2 E3 I USART1->DR = (u8) ch; + P+ }) ~& }- z. T4 {- W# r - c% L& w6 d5 Z* e9 | /* Loop until the end of transmission */# O1 B" w8 f9 T4 j, W: f% A* y z while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)2 Q/ G% T- w+ B; \ { : E. J2 h6 w n+ S% o }. |) [ `' c! C/ B$ s ~% I* s* a, o * d$ _3 N$ A7 ^ return ch; " I, A- b7 r3 G- M& `5 Z* T- R! L}/ \& X* d* O3 g# O 8 D1 H4 [! p0 r8 J% ?6 S" j# _/******************************************************************************* 4 A: B. z" a7 q* Function Name : Delay3 ~! {# t; }, R * Description : 延时函数/ k9 J" V; V+ n8 { * Input : None: o( v* J) }. L/ Y4 ^ * Output : None 3 h. g5 `$ ~# \3 D" g# j# M* Return : None$ u. a2 c' O& e4 J. E *******************************************************************************/6 \$ E! ~+ x! d' J void Delay(void)4 S J9 T( Y! O0 h% O {7 }; y, t4 u" b7 } u32 i;3 x- b$ `5 e7 h$ G for(i=0;i外设 |* I3 r) z( ^, f* L0 U4 @- V //每次传输位:8bit ; }8 N; i& i2 f* h //传输大小DMA_BufferSize=SENDBUFF_SIZE1 `$ [" c( n$ ? //地址自增模式:外设地址不增,内存地址自增1! f# @$ u: c& _+ D: }. [8 O //DMA模式:一次传输,非循环$ F0 N; [9 @- p( C: {" b //优先级:中3 U$ z: k5 H! A" ~+ Q DMA_DeInit(DMA1_Channel4);) s2 g2 E `( T DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base; * Y9 l7 I! z# G DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff;! Y% B/ c, n- u: ?: c0 o DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;* x0 u$ |+ d1 d& U" q' P" _ DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE; - {& B+ J2 u% N" {9 I d DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 0 g6 g. p8 x+ Z7 |: A DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;2 I, K+ C% c9 y' b DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;+ s$ t# z2 t+ r- i7 H; Q& w DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; $ r6 q& ^* c6 G6 y/ l {3 b DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;9 b- G( U" ~2 n9 Q, S' y7 t DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;, @4 r6 J# d) p" ]( p6 u$ @- v DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; $ t D/ f/ q8 Q+ q/ p+ _- {, S DMA_Init(DMA1_Channel4, &DMA_InitStructure);* u) j3 K1 `+ n1 R }
意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器。关注该话题即可发布文章!
回复:STM32笔记(四)DMA、USART的演示
回复:STM32笔记(四)DMA、USART的演示
回复:STM32笔记(四)DMA、USART的演示
回复:STM32笔记(四)DMA、USART的演示
好文章
回复:STM32笔记(四)DMA、USART的演示
回复:STM32笔记(四)DMA、USART的演示
RE:STM32笔记(四)DMA、USART的演示
RE:STM32笔记(四)DMA、USART的演示
RE:STM32笔记(四)DMA、USART的演示
RE:STM32笔记(四)DMA、USART的演示
回复:STM32笔记(四)DMA、USART的演示
RE:STM32笔记(四)DMA、USART的演示
回复:STM32笔记(四)DMA、USART的演示
好的谢谢
RE:STM32笔记(四)DMA、USART的演示
回复:STM32笔记(四)DMA、USART的演示