
这里有个小小的例子,来演示DMA模块与系统程序并行工作。 用串口以低波特率发送一个10K的数据,花费近10s时间,此时按照以往方法,CPU要不断等待数据发送、送数据;或者送数据、进中断、送数据,处理起来比较消耗时间。 使用了DMA功能以后,用户程序中只需配置好DMA,开启传输后,再也不需要操心,10K数据完成后会有标志位或中断产生,期间可以做任何想做的事,非常方便。2 S5 m) E2 ^. ?+ ~: g8 q& r 这个是相应的代码例子,基于STM32F103VBT63 K) d$ d' E' o1 r/ Q " I' u+ E5 R' E /****************************************************************************** * 本文件实现串口发送功能(通过重构putchar函数,调用printf;或者USART_SendData() * 这里是一个用串口实现大量数据传输的例子,使用了DMA模块进行内存到USART的传输8 A& u% T& ]7 Q * 每当USART的发送缓冲区空时,USART模块产生一个DMA事件, * 此时DMA模块响应该事件,自动从预先定义好的发送缓冲区中拿出下一个字节送给USART! d6 T! D( Y2 |" R% O7 T( v0 l' I, Z+ } * 整个过程无需用户程序干预,用户只需启动DMA传输传输即可/ d# v7 C* m, s8 g1 u8 `, h * 在仿真器调试时,可以在数据传输过程中暂停运行,此时DMA模块并没有停止* l* Z& O. S& y- |+ G/ r3 o * 串口依然发送,表明DMA传输是一个独立的过程。; D, d6 t' ?2 ^ * 同时开启接收中断,在串口中断中将数据存入缓冲区,在main主循环中处理 * 作者:jjldc(九九)( t4 C5 Q. W" f q8 E9 g* o * 代码硬件基于万利199元的EK-STM32F开发板,CPU=STM32F103VBT6# L, i! L4 @- s' G7 F( Y *******************************************************************************// x$ f+ b) v; B" U# R3 K ; }- o9 |, t! h o; T /* Includes ------------------------------------------------------------------*/ #include "stm32f10x_lib.h" #include "stdio.h"1 g5 f6 K' U' V3 ~2 @) r) m4 w 8 h! j! ^$ b3 M/ w$ q /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ #define USART1_DR_Base 0x40013804 / p z0 U+ s. Q+ g /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ #define SENDBUFF_SIZE 10240 vu8 SendBuff[SENDBUFF_SIZE];& }* T% J$ ~2 w vu8 RecvBuff[10]; vu8 recv_ptr;1 h" M ^- O9 Q( s /* Private function prototypes -----------------------------------------------*/ void RCC_Configuration(void);* t5 H- l1 f, x2 N" o void GPIO_Configuration(void); void NVIC_Configuration(void); void DMA_Configuration(void); void USART1_Configuration(void); int fputc(int ch, FILE *f); void Delay(void);! |- B: c' E' O9 p4 l /* Private functions ---------------------------------------------------------*/: P+ t! \$ \7 R/ q" [! n+ b /******************************************************************************* * Function Name : main * Description : Main program.& q6 U3 j% l2 U2 N * Input : None * Output : None * Return : None* ]2 x% i6 s2 Q2 }% x& ?% z *******************************************************************************/: G, c( ^& P, Q7 t int main(void)) z& D5 E p$ {1 A9 T# F { u16 i; #ifdef DEBUG& n9 @1 |! j7 h2 t% Q; K% @ debug(); #endif recv_ptr = 0; ) S8 l6 \ T5 s* w5 }& S RCC_Configuration();/ c# G* W5 z! Q: V2 M GPIO_Configuration(); NVIC_Configuration();: D- C, ?2 Q! u9 b3 I DMA_Configuration(); USART1_Configuration(); printf("\r\nSystem Start...\r\n"); printf("Initialling SendBuff... \r\n");& ^. r8 H2 i# d$ v( X+ \ for(i=0;i {4 q5 Y/ e2 |$ y5 M# f SendBuff = i&0xff;0 {' U- b: Q# |. t' v/ y) X } printf("Initial success!\r\nWaiting for transmission...\r\n");1 a- M% Y0 |' S* M9 _% F+ b //发送去数据已经准备好,按下按键即开始传输 while(GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_3)); printf("Start DMA transmission!\r\n");4 m+ y2 L# ^9 d- p0 i3 K! ~8 A //这里是开始DMA传输前的一些准备工作,将USART1模块设置成DMA方式工作 USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); //开始一次DMA传输!) I3 B* J* _. ?5 @0 q$ l0 ? DMA_Cmd(DMA1_Channel4, ENABLE);0 D$ ^1 x9 d$ v) d. ?4 |, P, U+ M //等待DMA传输完成,此时我们来做另外一些事,点灯! F, q+ C3 \, ?6 i7 ? //实际应用中,传输数据期间,可以执行另外的任务 while(DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET) {8 ]3 O1 t4 c4 Z; v! j LED_1_REV; //LED翻转) q5 H( b5 @( O9 I# v1 `7 ]! r Delay(); //浪费时间 }* A) B6 W2 Y. P( x //DMA传输结束后,自动关闭了DMA通道,而无需手动关闭 //下面的语句被注释 //DMA_Cmd(DMA1_Channel4, DISABLE);* d3 Y8 M1 l6 D+ I& Y' O printf("\r\nDMA transmission successful!\r\n"); ! `7 c6 m; R# G1 Q5 H /* Infinite loop */ while (1) { } } 5 s: T# J7 I- p/ n /******************************************************************************* * Function Name : 重定义系统putchar函数int fputc(int ch, FILE *f) * Description : 串口发一个字节 K7 k9 K1 A; L6 e * Input : int ch, FILE *f2 \( c, F [8 `( [ * Output : $ R$ }! ~/ V# L+ R& \" ?% ]* X+ L& u * Return : int ch7 y% y7 \# J. Q! T9 z * 这个是使用printf的关键 *******************************************************************************/- }( P6 V/ q+ R int fputc(int ch, FILE *f)5 _1 k4 U% F0 _3 T2 r0 I { //USART_SendData(USART1, (u8) ch);% x* u) D6 U& j. c USART1->DR = (u8) ch;1 L. J) @% _4 y- c0 Z /* Loop until the end of transmission */ while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) { }: Z- g+ M% v8 l# M. o1 A ' [$ R! ], z7 C0 P return ch; } /*******************************************************************************, @" q9 ~2 K" T * Function Name : Delay3 s9 }) m8 U d& w * Description : 延时函数 * Input : None * Output : None6 n2 N/ q5 m$ m * Return : None *******************************************************************************/ void Delay(void). A6 k- z7 m3 f {. i% j1 z+ v+ b8 }5 Y P/ n1 U u32 i; for(i=0;i外设 //每次传输位:8bit2 n, I: E3 `7 U9 E- C& x //传输大小DMA_BufferSize=SENDBUFF_SIZE9 P+ |- Z9 p: ?' x3 Z //地址自增模式:外设地址不增,内存地址自增1: s/ r! _! a" ]. K) @ //DMA模式:一次传输,非循环 //优先级:中 L/ a: x- `7 Q: n DMA_DeInit(DMA1_Channel4); DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base; DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff;. ~$ z1 f4 @8 E* g# Z DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;( `. d3 [0 l2 o DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;& R; H% @9 ?- [; h, N DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;" o6 b1 m+ W$ B) C( Q% { DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;0 B' k0 e* P' Z) v8 ` DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;/ L7 M" M8 V3 ?# _7 g DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;+ d# e) `, O9 C$ x* N DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel4, &DMA_InitStructure);+ C0 h% L2 x1 W7 U; r7 _# U2 d } |
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的演示
% |5 x4 j4 P2 k+ G
, x& s: n3 F* {( P: P- [4 a
haodongxi 好东西启封箱