
% {4 J$ ?" X0 n8 c; M 这里有个小小的例子,来演示DMA模块与系统程序并行工作。: ]! O3 z. k0 O 用串口以低波特率发送一个10K的数据,花费近10s时间,此时按照以往方法,CPU要不断等待数据发送、送数据;或者送数据、进中断、送数据,处理起来比较消耗时间。' Q" B! A+ p" g7 t* v5 Y 使用了DMA功能以后,用户程序中只需配置好DMA,开启传输后,再也不需要操心,10K数据完成后会有标志位或中断产生,期间可以做任何想做的事,非常方便。$ g+ c7 x2 N* ^5 I# k j( ] 这个是相应的代码例子,基于STM32F103VBT6$ Z. a; ` }9 z. z3 |0 Q8 [ ' r0 z& n! Z# B2 T! z7 u# | /****************************************************************************** * 本文件实现串口发送功能(通过重构putchar函数,调用printf;或者USART_SendData() * 这里是一个用串口实现大量数据传输的例子,使用了DMA模块进行内存到USART的传输 E ~/ b! ^$ _ * 每当USART的发送缓冲区空时,USART模块产生一个DMA事件, * 此时DMA模块响应该事件,自动从预先定义好的发送缓冲区中拿出下一个字节送给USART- q, e; c% o7 Y. L1 F% ]+ M! e * 整个过程无需用户程序干预,用户只需启动DMA传输传输即可 * 在仿真器调试时,可以在数据传输过程中暂停运行,此时DMA模块并没有停止 * 串口依然发送,表明DMA传输是一个独立的过程。2 S- k9 ], g" K2 \ * 同时开启接收中断,在串口中断中将数据存入缓冲区,在main主循环中处理 c) s2 ~# ~$ Q6 A * 作者:jjldc(九九)- d: ?: m0 k# a; V+ h2 T7 w" H * 代码硬件基于万利199元的EK-STM32F开发板,CPU=STM32F103VBT6& Y- G; d6 X5 x+ m6 N3 I) w% T1 W9 P *******************************************************************************/ /* Includes ------------------------------------------------------------------*/ #include "stm32f10x_lib.h": _" A% \9 T1 J { #include "stdio.h"1 k+ }8 m9 c! k* x$ p0 W$ v 8 t! _% N* w+ r, t7 x3 M/ p" Z /* Private typedef -----------------------------------------------------------*/* @: y" Z% \ }. O4 p/ I5 L /* Private define ------------------------------------------------------------*/; O0 H& O, Y. g* t #define USART1_DR_Base 0x40013804 /* Private macro -------------------------------------------------------------*/* e" U1 [& K J /* Private variables ---------------------------------------------------------*/ #define SENDBUFF_SIZE 102408 n9 @+ m" ?: ]. _" u vu8 SendBuff[SENDBUFF_SIZE]; vu8 RecvBuff[10];; e3 m5 _1 m+ Q# v+ E vu8 recv_ptr;5 [' x( M/ {& B. } 6 z3 p8 a# Z# P. P /* Private function prototypes -----------------------------------------------*/ void RCC_Configuration(void); void GPIO_Configuration(void); void NVIC_Configuration(void); void DMA_Configuration(void); void USART1_Configuration(void); 2 p9 A! d% ?2 {6 g# M int fputc(int ch, FILE *f); void Delay(void);: K7 d6 F) Q( ^7 C% k( J; R" E% h /* Private functions ---------------------------------------------------------*/( w+ b k; _2 }9 K {9 d5 j /******************************************************************************* * Function Name : main * Description : Main program. * Input : None( ^, F7 N$ ~; Q" k, D * Output : None9 z2 l6 o4 ^$ F" F* X * Return : None *******************************************************************************/% i2 {4 `2 @! {. @# \& l; \ int main(void) { u16 i;1 H/ D9 \7 P1 `$ X$ N# ` #ifdef DEBUG debug(); #endif recv_ptr = 0; p& ^5 J. f4 l' C RCC_Configuration();3 q4 D7 |1 O+ D' n# _. h8 Q9 J GPIO_Configuration();, M$ a7 Q% t, k1 u! h8 j NVIC_Configuration(); DMA_Configuration();: o* i3 Y7 z* s& e USART1_Configuration(); printf("\r\nSystem Start...\r\n"); printf("Initialling SendBuff... \r\n");3 g, B/ [0 Y/ M* b U for(i=0;i { SendBuff = i&0xff; } printf("Initial success!\r\nWaiting for transmission...\r\n"); //发送去数据已经准备好,按下按键即开始传输 while(GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_3));% }! e7 Q1 T S% p! x/ _) n. c7 a 3 W! Y" V/ e2 n& J8 `3 J$ @5 Y printf("Start DMA transmission!\r\n");7 s# j" V, l" [9 g* P' a5 T# N 4 i$ _$ U+ i; y- h% M) `- X //这里是开始DMA传输前的一些准备工作,将USART1模块设置成DMA方式工作 USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);+ ^3 ]- R$ b' @: c9 m0 e //开始一次DMA传输!9 p9 w6 s' \% }; k DMA_Cmd(DMA1_Channel4, ENABLE);1 u8 c1 z+ J' y9 r3 O- u0 [ j //等待DMA传输完成,此时我们来做另外一些事,点灯 //实际应用中,传输数据期间,可以执行另外的任务 while(DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET)4 \$ `5 t- U2 G2 j# T, L { LED_1_REV; //LED翻转* I7 I. u* P. o v& h5 ^* c Delay(); //浪费时间 }5 M. R4 H: E1 U1 S" c- @: c6 Q1 K //DMA传输结束后,自动关闭了DMA通道,而无需手动关闭, X9 e1 J( k" Z% D( N8 S$ x) G6 F //下面的语句被注释+ A# V$ r+ `+ \2 s1 M& B5 h //DMA_Cmd(DMA1_Channel4, DISABLE); printf("\r\nDMA transmission successful!\r\n"); : b Y/ D5 v7 R( W: T) x# p /* Infinite loop *// j1 B/ ^1 F M: s; b! T while (1). L \3 K+ N o& E$ C {. o: ]8 K3 f) l% e } } ; @- j! V8 R9 r. U' ?% A /*******************************************************************************, B! o' U. j' f1 Y * Function Name : 重定义系统putchar函数int fputc(int ch, FILE *f) * Description : 串口发一个字节 * Input : int ch, FILE *f0 k: s" u# [! u1 d$ B- T/ ^ * Output : * Return : int ch. _5 s/ k" X4 s! d T% v * 这个是使用printf的关键; Z4 P' l7 g _- q; P. q$ ~ *******************************************************************************/ int fputc(int ch, FILE *f) { w) M) H1 W3 `; \ //USART_SendData(USART1, (u8) ch); USART1->DR = (u8) ch; - T9 L P" Q# e0 s /* Loop until the end of transmission */ while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET), k2 v( P% K% u* X: ~# g% X8 k. ` { }3 S) U6 }8 y2 n' N return ch;$ Y( y; S; v; t8 p& t$ M1 E }; Z8 ?! {+ L( p7 j6 }; @ ; l, F: j/ i0 ~# `8 s' J /******************************************************************************* * Function Name : Delay( b( @! J5 g S! B, s2 Y" l * Description : 延时函数4 {* T3 `/ f9 A! c+ N * Input : None' c0 O' e: q8 W5 `1 l * Output : None" V/ ?- J# e n4 B7 [ * Return : None *******************************************************************************// K6 a, p( u x4 W! Z# K void Delay(void)4 N$ G- |6 X4 O4 c8 ^ { u32 i;- J' v5 n% \9 o2 O' B for(i=0;i外设6 N7 ]( n( L5 ^ //每次传输位:8bit //传输大小DMA_BufferSize=SENDBUFF_SIZE //地址自增模式:外设地址不增,内存地址自增1 //DMA模式:一次传输,非循环. l4 \4 c: V/ c //优先级:中# E, U7 S3 ]: f ?) E1 y& T DMA_DeInit(DMA1_Channel4);2 P! B+ u. B! L- }0 N1 h. g DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;+ s9 V4 O$ }. N' q2 @# g& p# r" Y DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff; 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;# Q( b" h9 C3 l/ {; A5 k DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;/ l: G7 X: A% t0 }) [- k( N) q DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;# l& ]9 _% z. m+ A9 F7 @- L DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;1 u0 o" m- u2 g5 d# x7 k7 q" s DMA_Init(DMA1_Channel4, &DMA_InitStructure); } |
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的演示
- O% K2 I8 z9 g0 F6 _; h# I) ^1 S
haodongxi 好东西启封箱