你的浏览器版本过低,可能导致网站不能正常访问!为了你能正常使用网站功能,请使用这些浏览器。
原帖由私奔于2009-01-04 14:30发表:1 |% v& b2 k1 a* @/ a7 Y 这里有个小小的例子,来演示DMA模块与系统程序并行工作。- W1 O& P5 \3 X+ O0 C3 w) k6 r 用串口以低波特率发送一个10K的数据,花费近10s时间,此时按照以往方法,CPU要不断等待数据发送、送数据;或者送数据、进中断、送数据,处理起来比较消耗时间。 K1 W8 K" w% a1 N, J- Z9 M 使用了DMA功能以后,用户程序中只需配置好DMA,开启传输后,再也不需要操心,10K数据完成后会有标志位或中断产生,期间可以做任何想做的事,非常方便。3 z5 [% G, R7 M$ m1 r5 A 这个是相应的代码例子,基于STM32F103VBT6 . O4 }; `% O1 X5 a5 V6 ~7 V! p$ q* X& I: I! H! C4 K 9 t+ \2 y0 y0 \7 o! I& i+ Z/******************************************************************************4 v' h f. B" {/ T: J * 本文件实现串口发送功能(通过重构putchar函数,调用printf;或者USART_SendData()3 q9 Z; T+ n5 d( t( O" m * 这里是一个用串口实现大量数据传输的例子,使用了DMA模块进行内存到USART的传输, A, l0 V z9 D; m1 B' X * 每当USART的发送缓冲区空时,USART模块产生一个DMA事件, 6 C4 n+ d# K& j1 l* 此时DMA模块响应该事件,自动从预先定义好的发送缓冲区中拿出下一个字节送给USART# a! U2 b% g7 c: @7 X3 n * 整个过程无需用户程序干预,用户只需启动DMA传输传输即可 1 J# Q l3 ^/ n9 K& Z7 m7 U* 在仿真器调试时,可以在数据传输过程中暂停运行,此时DMA模块并没有停止) M3 Q# V8 ?% }. o- f/ e2 s * 串口依然发送,表明DMA传输是一个独立的过程。; V3 E! o. r3 n% A& u * 同时开启接收中断,在串口中断中将数据存入缓冲区,在main主循环中处理 7 z+ f# q7 d6 K. Y, q2 p- i* 作者:jjldc(九九)5 n. P+ l; B4 s# X, ]; G) g * 代码硬件基于万利199元的EK-STM32F开发板,CPU=STM32F103VBT63 e6 ~! C- K/ r; i/ e2 _ *******************************************************************************/1 d0 o, W& \2 P% R" h% E8 r/ b. A / _1 q* ]7 _& I1 ]) b/* Includes ------------------------------------------------------------------*/3 T, N% p* ?/ L2 H #include "stm32f10x_lib.h" 3 s3 N1 W" I/ z#include "stdio.h"; u6 h/ R3 O' \2 e8 ~! }( o" R ! O+ b2 w: D0 `/ T4 S3 _; U/* Private typedef -----------------------------------------------------------*/ ! M6 @" L5 R( a2 H. ^0 a4 w: g/* Private define ------------------------------------------------------------*/$ y+ ~1 s! D, G0 K. X #define USART1_DR_Base 0x40013804& H) o! I- G t; X4 n- P , {: s, q$ Q {% r /* Private macro -------------------------------------------------------------*/ 1 a0 E2 K. m2 u# z y/* Private variables ---------------------------------------------------------*/ - h M) g" D- o0 m$ D8 z#define SENDBUFF_SIZE 10240 ) o( d D% ?1 Z0 Ovu8 SendBuff[SENDBUFF_SIZE]; $ t$ h2 `1 l9 y3 `/ F. Nvu8 RecvBuff[10]; $ f: W! G$ S* Y4 N/ f; Ivu8 recv_ptr; ! }3 B5 z9 F! u$ Z" N6 C 3 x1 q5 |3 c/ F s; l, {/* Private function prototypes -----------------------------------------------*/ * ~! R$ B( \8 L3 c1 D8 ]+ T) _void RCC_Configuration(void);" [. ?6 P; w# s) P void GPIO_Configuration(void); 2 {+ X* _0 g: x0 m: Y0 _" T Gvoid NVIC_Configuration(void); 6 G* h+ i. m, p# dvoid DMA_Configuration(void); 1 \$ B) p, u' I$ B/ o \void USART1_Configuration(void); " h. K4 L5 A4 _7 k9 @+ _" p1 c& J" ?+ Z6 [( n4 ` int fputc(int ch, FILE *f); ' d' L! r& P K7 K" A& Avoid Delay(void);) m8 `- A0 A0 f$ c ~& Y; E $ X7 T ~) ?( \5 J2 k9 Y/* Private functions ---------------------------------------------------------*/1 w' Z @3 h. p7 d/ p /*******************************************************************************/ I( S+ c/ L9 f * Function Name : main ' Z$ P1 Z. S5 e3 T* Description : Main program. : m% E* W, [" h, p- w6 _* Input : None $ p& A( ^* ?' O" n" `* Output : None L) H4 U" E! g# i o% Z, m* Return : None ) S, R$ |0 I) d9 a0 ?; c*******************************************************************************/. z/ o/ \; l% g6 ]0 K int main(void) 2 r% j: x6 @3 l6 v9 G2 P- d& h4 r{7 c% x3 k4 F; }7 P4 \2 A u16 i;" u8 G, {. B3 y# s8 s% B #ifdef DEBUG $ [6 e& C# q; R( d# \ debug(); 4 J6 V) _& j; P4 b#endif - m5 ]. B$ C$ N) J+ C recv_ptr = 0; - U0 J+ Z, Z, E 5 k1 K b/ p1 m- {& @ RCC_Configuration();( q4 Z3 G S9 r" F' F' F) h0 R; ] GPIO_Configuration(); % q D) w, m& m9 u; S* _ NVIC_Configuration();! U8 H! B5 u- v& Y& e. p6 W, M; | DMA_Configuration(); 3 A+ T& v* [3 F- C7 V$ ? USART1_Configuration();! O6 M# H% r3 w1 I 9 Z9 q n- P5 i; [6 v6 J( J% r printf("\r\nSystem Start...\r\n"); 1 x! n+ k& Q" e( y# u. } printf("Initialling SendBuff... \r\n"); k, y9 [! w% L3 n9 ]8 l for(i=0;i { - k U; B B' M+ i SendBuff = i&0xff;4 [6 `4 Y* B- p } / r9 V- n. N R- Q% H printf("Initial success!\r\nWaiting for transmission...\r\n");4 ^" \) h: P( v% d: M2 _ //发送去数据已经准备好,按下按键即开始传输 6 T5 M2 [( h5 S) Q while(GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_3)); ) h: c, a# Q' e9 d- T& T , {; l7 ]+ Q2 {) B; U printf("Start DMA transmission!\r\n");, g( Z& Q$ w9 s" k4 y " T5 m. l6 n& c+ q* \ //这里是开始DMA传输前的一些准备工作,将USART1模块设置成DMA方式工作( J+ G. ]/ j+ V/ r0 @, { USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);7 u+ c2 g+ i" ? //开始一次DMA传输! 9 | u* e8 |8 N D DMA_Cmd(DMA1_Channel4, ENABLE); 1 d% s; J/ {" A- G # a" o0 D+ z" S //等待DMA传输完成,此时我们来做另外一些事,点灯: P5 X& x. d+ R //实际应用中,传输数据期间,可以执行另外的任务 & |! b9 d5 e. |8 O while(DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET) 8 A9 |+ v1 ^% Z0 g { & S% K5 |* _9 C6 s0 C* L: r LED_1_REV; //LED翻转0 \, P2 Y# Z# V2 Z Delay(); //浪费时间 , `2 |! ^( ^7 Y$ J } , E% g7 W* O/ U //DMA传输结束后,自动关闭了DMA通道,而无需手动关闭! L1 \8 a+ G) S; B& m% Z! D //下面的语句被注释 2 T8 p$ f2 N5 L% W //DMA_Cmd(DMA1_Channel4, DISABLE);9 d4 @* n# o; I& D: L$ m + B5 z, s& U( {" R u5 X4 `/ A printf("\r\nDMA transmission successful!\r\n"); $ C- X- I9 [! D0 o1 k# _) @; Z" ~- @, L( m1 U ) V/ H+ W3 M; m# h3 t$ I /* Infinite loop */ " l# O" M9 F# w3 k+ x while (1)5 ~9 a8 R# B6 }) S7 f; R { : f& K4 V/ A, P9 Z4 |6 r } ; h8 B, D/ e, v9 B} $ |& U, d% o. C" Z! V& ?8 A& G! `( c9 I% |# c4 b' i5 }/ \6 r. {" f /******************************************************************************* 8 w" j8 K! N6 }5 t( @* Function Name : 重定义系统putchar函数int fputc(int ch, FILE *f)7 C, G% L9 S6 \6 P * Description : 串口发一个字节 / d+ T- n6 l( O7 } W+ X* Input : int ch, FILE *f* d' f, D' T; x3 ?6 S' L * Output : % n) Y- Q" @& v3 } * Return : int ch 0 g: q% J3 w( V+ O) C0 ^* 这个是使用printf的关键 ) F- L7 X- g% o5 P*******************************************************************************/ 0 O$ Z! f9 t+ q. tint fputc(int ch, FILE *f)% g0 D' V* ?9 L% ?: I- n3 ^ {+ r% v. ~ S1 r8 \: P v9 g! j- C //USART_SendData(USART1, (u8) ch); . n& x7 E# d0 ]; g$ ] USART1->DR = (u8) ch; - V/ p( e" z# k$ W, t ; R7 L: r/ {7 V6 O /* Loop until the end of transmission */ / C' F+ t; g/ n h5 R; J' e4 P( N while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) 0 x3 j5 s/ a% l- @2 Y {. p/ x! }9 _3 K; d4 d4 h }* V9 F/ k Z( h& g4 \ ' n1 [% j) N3 [" g return ch;8 }8 ?" g" { Y& ^, J% W9 d/ [ }* T- y* Y0 C6 u. M + \: b I( K' z3 d/ e/ e8 B /*******************************************************************************7 q! o$ u8 m" p8 ]& T * Function Name : Delay* u0 S+ W7 h- c/ {: r- C+ m& Q) I- j * Description : 延时函数 7 o% U% y+ S% M, N1 F* Input : None 3 F: x- Z0 Q: ]. E4 J5 c* Output : None % b; |2 w' T9 h( M3 [: b* Return : None& M$ H2 X2 q& L( X. \ *******************************************************************************/# w* o6 i6 S+ V. B+ U5 R5 d8 G void Delay(void)5 p9 D: C# ^' a' C {# W, I* {# J8 x- c1 U9 v y u32 i; 6 b& G( g* U: x6 C for(i=0;i外设) J }/ L6 M: m6 T+ G5 p% Z //每次传输位:8bit5 |& H+ o% U, Y/ |+ ?/ C //传输大小DMA_BufferSize=SENDBUFF_SIZE# S# x# E* W- h //地址自增模式:外设地址不增,内存地址自增1 + Q, H1 ?" r+ Z! N; N/ u6 e. [ //DMA模式:一次传输,非循环: \) M; D# n1 E- s& S# Q. V6 H //优先级:中8 N; |2 }$ r! t. K; o5 Y DMA_DeInit(DMA1_Channel4);& p/ u, y8 i! V) ]: g# X9 R/ k) W/ @$ _. F DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;7 U' T1 y+ H2 G* [+ j# L DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff; K3 z# j% f# a& c0 T DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;6 N$ W, e4 S8 `5 N8 B- ]; ~, E) Y8 Y DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE; , c6 w0 p" t8 e5 K6 C* G) { DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; : l- c C7 u, } DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;9 D8 W K9 u. L* n DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;! N! t+ O( E5 m1 u9 A. A DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; ! u4 F8 m4 _3 X& l7 D- r. ^/ _ DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; : E! c6 V: n# Z/ o+ H DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;, T2 t* X) P6 I% @) f2 [$ G- { DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;% P1 o( ?* N% k9 `& M DMA_Init(DMA1_Channel4, &DMA_InitStructure); & f, E! j G" W) f$ s% x}
意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器。关注该话题即可发布文章!
RE:STM32笔记(四)DMA、USART的演示
RE:STM32笔记(四)DMA、USART的演示
回复:STM32笔记(四)DMA、USART的演示
RE:STM32笔记(四)DMA、USART的演示
#define TxBufferSize 16
#define RxBufferSize 16
uint8_t TxBuffer[TxBufferSize] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F};
uint8_t RxBuffer[RxBufferSize];
void DMA_Configuration(void)2 o% |6 z2 _: v* B( A' i
{& N. ^$ Y+ X/ i. u" D' ] B, |
DMA_InitTypeDef DMA_InitStructure;
DMA_DeInit(DMA1_Channel7); ' i; w$ b4 C1 s1 C* Q
DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40004404;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)TxBuffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = TxBufferSize;' Z9 I: ?& d' ~8 C4 z6 ^
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;. L: q9 @8 y* \( e* G% U, q( c
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;0 u& x$ U7 R! r$ w3 L$ \; A
DMA_Init(DMA1_Channel7, &DMA_InitStructure);* u2 {( N$ m [
DMA_DeInit(DMA1_Channel6);
DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40004404;+ J- z% ?( ^3 r* M+ |; w8 ~
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)RxBuffer;+ O! z) l9 Z8 S+ N6 Q3 X
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;" p# T2 @% B. t
DMA_InitStructure.DMA_BufferSize = RxBufferSize;
DMA_Init(DMA1_Channel6, &DMA_InitStructure);
}
void USART_Configuration(void)1 q n7 c( `8 Y1 _; O$ B# p7 X$ r3 w3 i
{
USART_InitTypeDef USART_InitStructure;1 x* X) Y- z) g$ w1 H
USART_DeInit(USART2);- b- M* [% \2 R8 W& v7 F
USART_InitStructure.USART_BaudRate = 115200;- t0 E# I% x, a0 X/ J7 Z
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;" h, ?4 q9 Q! T$ ?3 D) S( E
USART_InitStructure.USART_Parity = USART_Parity_No ;! j9 S, z9 ^' j2 u- y5 ^$ `0 o
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;* |- E, j0 ^5 V7 I ]
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART2,&USART_InitStructure);
}
void GPIO_Board_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* DMA1 Periph clock enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* GPIO Periph clock enable */- [% L1 e" Y& }' `1 \
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO , ENABLE);; e8 i& g1 o- I" s) a5 W7 S' R
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 , ENABLE);
/* Configure GPIOA Out mode */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_8 | GPIO_Pin_11 | GPIO_Pin_12;( j, L+ H, E Q# G& k$ o" h
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);! O$ e7 x" r) ]5 o' p- e
/* Configure GPIOB Out mode */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_5 | GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Configure GPIOC Out mode */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;3 G+ I4 p. u# a z: X
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Configure USART2 Rx as input floating */& i4 L" Y4 `7 q8 m! I3 w3 T; M5 Z) e
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;: K8 c" C$ j2 O! d3 d) ~
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;7 F% m# f% ~+ @6 P
GPIO_Init(GPIOA, &GPIO_InitStructure);6 Y5 D: ^% l) O& w( n3 ]; b; i
/* Configure USART2 Tx as alternate function push-pull */! O o% b# o: B( |
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; _$ P% U! {% U) x: v( Q* |3 h, f
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
int main(void)
{- @( D) X; @- T( F7 B: g
while(1)- g, ?9 b! u) p8 O+ a- p$ ]0 K+ |
{
if(DMA_GetFlagStatus(DMA1_FLAG_TC6) == SET)1 h1 k& f: C, |1 r' J. m
{% d m6 s4 k" l' l; X
DMA_ClearFlag(DMA1_FLAG_TC6);# k' [8 l/ l# S* f8 o! K9 e" N
DMA_Cmd(DMA1_Channel6, DISABLE);" m# k% I& n4 _
DMA_SetCurrDataCounter(DMA1_Channel6,RxBufferSize);
GPIO_SetBits(GPIOC,GPIO_Pin_8);# V# U* n( y" Y- h4 c
delay(500);9 @4 {+ q9 L5 f g! C& n
GPIO_ResetBits(GPIOC,GPIO_Pin_8 );
delay(500);! k2 C# { R( R! X* T2 v+ e9 G) G
}7 v( s4 w' c. e
else
{. G/ p; k0 e" r2 G
GPIO_SetBits(GPIOC,GPIO_Pin_9);
delay(500);
GPIO_ResetBits(GPIOC,GPIO_Pin_9 );
delay(500);( M: P! n# _! y! Z% \
}
}' y, Z+ L. e5 t! ]% p
}
回复:STM32笔记(四)DMA、USART的演示
回复:STM32笔记(四)DMA、USART的演示
谢谢分享
RE:STM32笔记(四)DMA、USART的演示
回复:STM32笔记(四)DMA、USART的演示
回复:STM32笔记(四)DMA、USART的演示
回复:STM32笔记(四)DMA、USART的演示
回复:STM32笔记(四)DMA、USART的演示
回复:STM32笔记(四)DMA、USART的演示
回复:STM32笔记(四)DMA、USART的演示
回复:STM32笔记(四)DMA、USART的演示
回复:STM32笔记(四)DMA、USART的演示