
: S5 B, O8 A, r4 F( \; R0 g 这里有个小小的例子,来演示DMA模块与系统程序并行工作。6 j( h6 u& X7 w5 ^$ i 用串口以低波特率发送一个10K的数据,花费近10s时间,此时按照以往方法,CPU要不断等待数据发送、送数据;或者送数据、进中断、送数据,处理起来比较消耗时间。! Z# z/ F9 y" i9 J4 T$ R: I 使用了DMA功能以后,用户程序中只需配置好DMA,开启传输后,再也不需要操心,10K数据完成后会有标志位或中断产生,期间可以做任何想做的事,非常方便。 这个是相应的代码例子,基于STM32F103VBT62 e+ J% D) i$ w7 V! S3 r3 E ) x5 }% f$ [6 w, G4 z I# {5 i: _! E# V5 j2 U /****************************************************************************** * 本文件实现串口发送功能(通过重构putchar函数,调用printf;或者USART_SendData()! t5 D, _2 j0 a/ j * 这里是一个用串口实现大量数据传输的例子,使用了DMA模块进行内存到USART的传输6 K8 e, x e7 t4 ?% f. E; z1 ` * 每当USART的发送缓冲区空时,USART模块产生一个DMA事件,+ U1 R6 }5 Y' I P; J) t. ?) n * 此时DMA模块响应该事件,自动从预先定义好的发送缓冲区中拿出下一个字节送给USART6 T- ?: ^5 ?0 i: L, g. P+ H * 整个过程无需用户程序干预,用户只需启动DMA传输传输即可; u" N( {3 h1 V1 M0 h * 在仿真器调试时,可以在数据传输过程中暂停运行,此时DMA模块并没有停止# B- T; O/ G% ]- x * 串口依然发送,表明DMA传输是一个独立的过程。$ ~3 {* ?6 k# B1 i * 同时开启接收中断,在串口中断中将数据存入缓冲区,在main主循环中处理 * 作者:jjldc(九九) * 代码硬件基于万利199元的EK-STM32F开发板,CPU=STM32F103VBT62 v' C* ?" }( o6 q" x ? *******************************************************************************/3 m$ }) c. o& \( |3 y) T" e( ~ /* Includes ------------------------------------------------------------------*/! @$ b8 E: o/ K8 b8 }! k #include "stm32f10x_lib.h" #include "stdio.h" 9 j$ r6 V1 H; ~* Q4 V /* Private typedef -----------------------------------------------------------*/ P9 E$ ~, _# {$ l9 B7 J* U& V1 D8 [ /* Private define ------------------------------------------------------------*/ #define USART1_DR_Base 0x40013804 /* Private macro -------------------------------------------------------------*/, `: [. r- Y- r7 p /* Private variables ---------------------------------------------------------*/ #define SENDBUFF_SIZE 10240 vu8 SendBuff[SENDBUFF_SIZE]; vu8 RecvBuff[10]; vu8 recv_ptr; 6 f/ P% @" n& } ~ /* Private function prototypes -----------------------------------------------*// L2 e1 T2 [: [8 u* Z, z) r void RCC_Configuration(void); void GPIO_Configuration(void);* k( I, M2 W' D4 S& G void NVIC_Configuration(void); void DMA_Configuration(void); void USART1_Configuration(void); int fputc(int ch, FILE *f);7 \8 L9 j2 U! g void Delay(void); / _* l( G! l$ M" X, c% W% d. O7 W /* Private functions ---------------------------------------------------------*/ /******************************************************************************* * Function Name : main1 R1 j) O" ?- ]7 b" p: v+ U- f * Description : Main program. * Input : None) l" f3 d! P, @! [* e( Q * Output : None * Return : None4 ]) l: ^. S2 L *******************************************************************************/ int main(void)4 U, C& y7 P. I% t { u16 i; #ifdef DEBUG debug(); #endif recv_ptr = 0;$ [% T' }5 V# ~0 k- I7 V+ D. C RCC_Configuration();- |' L+ F& K! U/ d: x0 y7 o GPIO_Configuration(); NVIC_Configuration(); DMA_Configuration();1 C" @* a/ z+ ] USART1_Configuration();3 ~) J; _7 }" }% |) z* _! k 0 s1 l1 y. |, g! v printf("\r\nSystem Start...\r\n");/ o! P& }/ C1 ^ printf("Initialling SendBuff... \r\n"); for(i=0;i { SendBuff = i&0xff;* @3 w/ `8 L: b, r } printf("Initial success!\r\nWaiting for transmission...\r\n"); //发送去数据已经准备好,按下按键即开始传输 while(GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_3)); printf("Start DMA transmission!\r\n"); //这里是开始DMA传输前的一些准备工作,将USART1模块设置成DMA方式工作 USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); //开始一次DMA传输!+ v/ F! u6 Q2 N- V1 K DMA_Cmd(DMA1_Channel4, ENABLE); //等待DMA传输完成,此时我们来做另外一些事,点灯; n! i% [" [( E9 U //实际应用中,传输数据期间,可以执行另外的任务$ s" ^* g9 h& J% Q7 l" a8 B; k while(DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET); @1 N [% R a( W; v# Y" U {# W3 L9 b& q9 j; s. ~ LED_1_REV; //LED翻转 Delay(); //浪费时间# ^8 n( I3 Z, d+ k }) K/ i' J8 \8 u //DMA传输结束后,自动关闭了DMA通道,而无需手动关闭 //下面的语句被注释! ` ]6 E0 w$ X1 \+ a //DMA_Cmd(DMA1_Channel4, DISABLE);! i5 w8 I2 y& n9 F% x / J' r* i% c% X2 f printf("\r\nDMA transmission successful!\r\n"); C: w9 H/ b3 u7 k# c" G" i/ A /* Infinite loop */( x h. }# \ D while (1)5 Z% h. Y. q' c { } } 1 Q2 M6 B$ y7 z" o% c3 I+ D1 u /*******************************************************************************. G: b: b' @0 H% Z+ C * Function Name : 重定义系统putchar函数int fputc(int ch, FILE *f)5 W, a, s+ B8 @+ y: R/ A. R& u * Description : 串口发一个字节 * Input : int ch, FILE *f * Output : % z. p4 f3 j+ j0 M4 d" u * Return : int ch * 这个是使用printf的关键) }" Z0 N, ~6 U p, Q *******************************************************************************/ int fputc(int ch, FILE *f) { //USART_SendData(USART1, (u8) ch);2 {# |8 @' z9 S8 d, ^ USART1->DR = (u8) ch;6 D3 S3 W' X, w ' v. @! i! k5 n /* Loop until the end of transmission */) p- K2 X9 r- t' V0 U7 T while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) { } return ch;9 _' Q- h; _# f/ `3 [3 @8 Q } /*******************************************************************************+ z C0 ?' G0 S, r3 z) j * Function Name : Delay& D: b3 z r: r * Description : 延时函数$ H9 [' z+ j# ]6 O, W$ L * Input : None3 p: Y& x! ^# m4 h; y * Output : None * Return : None *******************************************************************************/ void Delay(void) { u32 i; for(i=0;i外设 //每次传输位:8bit //传输大小DMA_BufferSize=SENDBUFF_SIZE9 ?6 {- H0 C4 N: q- H$ I# B; i! Y //地址自增模式:外设地址不增,内存地址自增1 //DMA模式:一次传输,非循环& s* h) H# D3 @% ?" [7 p" H6 w/ C h //优先级:中* S9 |# n$ z+ i$ [0 E DMA_DeInit(DMA1_Channel4); DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base; DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff;3 F- d: H5 b6 i, L5 }; p! A, D DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;- e5 k1 d/ E+ {% O- t DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE; 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;. A, |5 K, X- E7 G1 ? DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;7 b8 G2 W5 G2 H! b! Q DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;3 X: j6 l0 I: S& t' g& |/ ~ DMA_Init(DMA1_Channel4, &DMA_InitStructure);$ t i2 W) W4 {9 E" r! x } |
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的演示
! Y Y6 ?( T4 X) _
1 O+ _3 Q- Q- G
haodongxi 好东西启封箱