|
1 }" k' n0 Y: W- A A: R 这里有个小小的例子,来演示DMA模块与系统程序并行工作。 用串口以低波特率发送一个10K的数据,花费近10s时间,此时按照以往方法,CPU要不断等待数据发送、送数据;或者送数据、进中断、送数据,处理起来比较消耗时间。/ }3 q( P0 l' P) F. y0 n* X' ?- \ 使用了DMA功能以后,用户程序中只需配置好DMA,开启传输后,再也不需要操心,10K数据完成后会有标志位或中断产生,期间可以做任何想做的事,非常方便。 这个是相应的代码例子,基于STM32F103VBT6 4 d7 B; B4 q7 Z. w5 F q6 R /******************************************************************************5 x3 J, v/ I( l" i% k * 本文件实现串口发送功能(通过重构putchar函数,调用printf;或者USART_SendData() * 这里是一个用串口实现大量数据传输的例子,使用了DMA模块进行内存到USART的传输 * 每当USART的发送缓冲区空时,USART模块产生一个DMA事件, * 此时DMA模块响应该事件,自动从预先定义好的发送缓冲区中拿出下一个字节送给USART * 整个过程无需用户程序干预,用户只需启动DMA传输传输即可 * 在仿真器调试时,可以在数据传输过程中暂停运行,此时DMA模块并没有停止& G2 s; Y' Y8 f' W * 串口依然发送,表明DMA传输是一个独立的过程。 * 同时开启接收中断,在串口中断中将数据存入缓冲区,在main主循环中处理" |/ Q- G! z9 x * 作者:jjldc(九九)4 _# E& Y0 t* b! J * 代码硬件基于万利199元的EK-STM32F开发板,CPU=STM32F103VBT6 *******************************************************************************/& J- l/ J/ k: n /* Includes ------------------------------------------------------------------*/& h, ?& w# h2 G4 K O #include "stm32f10x_lib.h" #include "stdio.h" /* Private typedef -----------------------------------------------------------*/; @" g) s" J9 O+ U1 J2 |& s /* Private define ------------------------------------------------------------*/ #define USART1_DR_Base 0x400138045 I7 h# ?( A% x' D# _$ I. f7 E /* Private macro -------------------------------------------------------------*/( m5 X, A+ D2 h" w /* Private variables ---------------------------------------------------------*/, Y- R, o( o- q. K #define SENDBUFF_SIZE 10240 vu8 SendBuff[SENDBUFF_SIZE];$ j1 S. o3 \ M* h5 F vu8 RecvBuff[10]; vu8 recv_ptr; 3 h* u$ O7 b8 Q% J /* Private function prototypes -----------------------------------------------*/" ]% h) z, w7 U2 B" s$ x- P7 \ void RCC_Configuration(void);$ b, r7 C+ g, N$ ~ void GPIO_Configuration(void); void NVIC_Configuration(void);. @. X8 g+ C8 x" y- y) C void DMA_Configuration(void);9 D! \4 J+ g; ^9 \1 J, r* `" q void USART1_Configuration(void);- h- A" m* j8 S0 p S ( k% z+ h u& A3 Y2 r int fputc(int ch, FILE *f); void Delay(void);- q$ R8 h$ B! q e1 H( S4 N! I4 G3 q% _2 f3 \ /* Private functions ---------------------------------------------------------*/ /******************************************************************************* * Function Name : main; y) S% E4 @; J; w( S7 Q, J5 z * Description : Main program.+ T2 U( m I. E4 ?; |- J9 z8 N' z * Input : None" P2 s+ Y9 t3 t * Output : None * Return : None( ^) i; M0 y [- G1 J: t6 y' b" S *******************************************************************************/ int main(void)$ ]6 U" Y( m1 q, q {; q+ [* g# M F' z3 x; ? m; D/ i u16 i; #ifdef DEBUG( h" r& g2 u; H2 I& ~ debug();; M! Q0 @6 n, I #endif recv_ptr = 0; RCC_Configuration();) B( \; [) f, r$ d: u0 k GPIO_Configuration();# F+ }( f% q4 B. l7 p; s NVIC_Configuration(); DMA_Configuration();4 C& ]% D# R' g& T+ M5 f USART1_Configuration(); printf("\r\nSystem Start...\r\n");' j8 D( H, F3 s) k7 m printf("Initialling SendBuff... \r\n"); for(i=0;i { SendBuff = i&0xff; } printf("Initial success!\r\nWaiting for transmission...\r\n");- L2 C/ g' K7 b. n //发送去数据已经准备好,按下按键即开始传输 while(GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_3)); & v+ }7 C4 F: |* S8 P1 z; j: J printf("Start DMA transmission!\r\n");+ x6 H& B' w1 x# c! `: [% { //这里是开始DMA传输前的一些准备工作,将USART1模块设置成DMA方式工作 USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); //开始一次DMA传输! DMA_Cmd(DMA1_Channel4, ENABLE);2 v5 b6 A) [4 Y7 o* r; ^: P - R/ M5 ]- o; N% c% _2 V- [ //等待DMA传输完成,此时我们来做另外一些事,点灯6 t" T* \8 @# [( v //实际应用中,传输数据期间,可以执行另外的任务) ?( e- ?5 B, Y while(DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET) {* I6 e% j7 U. z# l- }% u! x) S LED_1_REV; //LED翻转9 d' e6 {. _+ K6 J, a: G" u+ b9 C2 H/ P7 @ Delay(); //浪费时间 }$ O1 R+ h2 C, M$ A r/ ` //DMA传输结束后,自动关闭了DMA通道,而无需手动关闭' S# Q" |, m# c# d6 {- V# Z$ |& h //下面的语句被注释3 P* t' J* F+ ?: s2 C3 z //DMA_Cmd(DMA1_Channel4, DISABLE); printf("\r\nDMA transmission successful!\r\n");4 Z: r7 n1 Y: Z: ^ 9 N3 C/ O' k# h2 P /* Infinite loop */3 a! J1 a: a! a4 q while (1) { }# M, @) O) d! e0 m' L7 ?2 p6 w" V' U }0 ^8 |& K+ w7 p8 [: L. s4 e) X0 x( _ /*******************************************************************************/ e s- i; }" l3 W * Function Name : 重定义系统putchar函数int fputc(int ch, FILE *f) * Description : 串口发一个字节 * Input : int ch, FILE *f2 x1 Q8 O; L3 ]8 L8 i * Output : # K( c! p6 z2 ^6 M( \ * Return : int ch% M/ D; U+ o% h0 ]8 _ * 这个是使用printf的关键 *******************************************************************************/ int fputc(int ch, FILE *f), N. y, i: O. w$ y3 Q8 ~ {9 T3 X/ B, X0 p7 u5 N) y //USART_SendData(USART1, (u8) ch); USART1->DR = (u8) ch; ( b; l' L, t' m( [, L /* Loop until the end of transmission */ while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) { } 0 T0 Q7 b% o8 O! P' O6 @ return ch;0 p6 X w# ?- L9 q( U- K \ } ; t5 i9 B$ E4 V; z /*******************************************************************************8 [" N ^+ m( |) v0 \4 z * Function Name : Delay * Description : 延时函数 * Input : None: T8 X8 u% C f' e) j * Output : None' T2 [- f2 d2 L0 `" J6 ` * Return : None/ C, U3 V% |" [ *******************************************************************************/ void Delay(void) {# n8 ^3 ]. Z1 D0 _# H u32 i; for(i=0;i外设! s4 U* p. o4 Q //每次传输位:8bit2 A' C J8 g. Y' k8 u9 | //传输大小DMA_BufferSize=SENDBUFF_SIZE( _! `* Y; b; D; |3 W* @" J //地址自增模式:外设地址不增,内存地址自增1 //DMA模式:一次传输,非循环( [8 S7 G& I, G( J //优先级:中" x+ ~7 }: B" @! e DMA_DeInit(DMA1_Channel4);- D9 M& ?: v! u, C DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base; DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff;8 d, J5 j6 z) w: Z$ s, E DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE; d9 d: R6 R# J0 Q DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;3 y% l5 k$ b9 ]1 N+ t DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;/ g. ^* m) _ n3 |0 a3 @ DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;( r- }+ Y# e! R DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;; L; z/ q i1 h4 D0 x$ Z 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的演示
8 g9 R( `! ~- T6 @+ w
haodongxi 好东西启封箱