; u/ q. ]6 K5 v: Q5 } 这里有个小小的例子,来演示DMA模块与系统程序并行工作。0 @! |! h7 b; }: B3 P 用串口以低波特率发送一个10K的数据,花费近10s时间,此时按照以往方法,CPU要不断等待数据发送、送数据;或者送数据、进中断、送数据,处理起来比较消耗时间。 使用了DMA功能以后,用户程序中只需配置好DMA,开启传输后,再也不需要操心,10K数据完成后会有标志位或中断产生,期间可以做任何想做的事,非常方便。 这个是相应的代码例子,基于STM32F103VBT6 / [1 b0 P( v( u' L4 | 1 o+ w7 L$ r2 `/ d /****************************************************************************** * 本文件实现串口发送功能(通过重构putchar函数,调用printf;或者USART_SendData()- P9 L7 t0 M0 }8 H8 v6 U! F, K * 这里是一个用串口实现大量数据传输的例子,使用了DMA模块进行内存到USART的传输 * 每当USART的发送缓冲区空时,USART模块产生一个DMA事件, * 此时DMA模块响应该事件,自动从预先定义好的发送缓冲区中拿出下一个字节送给USART * 整个过程无需用户程序干预,用户只需启动DMA传输传输即可 ]/ S' n" F, q; t P" Y/ A3 l * 在仿真器调试时,可以在数据传输过程中暂停运行,此时DMA模块并没有停止 * 串口依然发送,表明DMA传输是一个独立的过程。 * 同时开启接收中断,在串口中断中将数据存入缓冲区,在main主循环中处理 * 作者:jjldc(九九)4 [3 Q$ B$ h* c7 d( X * 代码硬件基于万利199元的EK-STM32F开发板,CPU=STM32F103VBT6: q1 r& [) U7 N/ N *******************************************************************************/ /* Includes ------------------------------------------------------------------*/ #include "stm32f10x_lib.h"" h& A+ A! u6 n1 |7 k6 s% X #include "stdio.h"2 Q) T C" s+ ?3 |2 w( t /* Private typedef -----------------------------------------------------------*/& W9 Z& e1 c% X% L | /* Private define ------------------------------------------------------------*/6 R' C( I; v1 Q$ T" j; J- j' Q #define USART1_DR_Base 0x40013804 : V0 X" N9 z+ @, z0 R8 n1 C /* Private macro -------------------------------------------------------------*/) I5 L2 g, V! |5 ] /* Private variables ---------------------------------------------------------*/( C. X* Z1 |" |/ h$ m* `; X #define SENDBUFF_SIZE 10240 vu8 SendBuff[SENDBUFF_SIZE];9 {8 y: r5 z, j9 Z; c vu8 RecvBuff[10]; vu8 recv_ptr;8 r7 c* t y# y8 c6 M: p$ i. t5 A 3 x, X4 P; f4 j# ]7 A* b /* Private function prototypes -----------------------------------------------*/7 b v1 B3 P" Q- g& w; K- i8 u void RCC_Configuration(void);! u; `# Z; Y0 o1 R' I/ T- N void GPIO_Configuration(void); void NVIC_Configuration(void);# ~. Y, O @5 a/ m$ M+ q( G void DMA_Configuration(void);2 i- Q/ ]0 e* b' R" h: L void USART1_Configuration(void); int fputc(int ch, FILE *f); void Delay(void);4 i% u. ~1 J( s$ M7 `3 @ 1 F4 ]; C8 m+ [3 T& B /* Private functions ---------------------------------------------------------*/ /******************************************************************************* * Function Name : main7 a1 X+ k/ d$ I * Description : Main program.9 A" k! G! u% h3 G M * Input : None * Output : None * Return : None *******************************************************************************/6 M, e9 K* B* q% S- \" J int main(void)5 V+ s0 y' l& Y$ o& _- r, V0 O; u4 @ { u16 i; #ifdef DEBUG& M! R' c/ l" q/ H debug();. l& Z; U; T" J# D/ K# R) u #endif+ K8 P8 s4 d& ^% g recv_ptr = 0;- j, @0 C U. R' T) ] RCC_Configuration(); GPIO_Configuration();0 G! O' ?' _9 N NVIC_Configuration();' L6 I# F& r1 J/ U; { DMA_Configuration(); USART1_Configuration();1 E9 Q0 j* D4 P9 f4 ^& Z * x/ E1 w$ t( _9 K printf("\r\nSystem Start...\r\n");. |% t# B5 E, u; d: a o+ G6 K printf("Initialling SendBuff... \r\n");: j# [+ |( r2 p for(i=0;i { SendBuff = i&0xff; } printf("Initial success!\r\nWaiting for transmission...\r\n"); //发送去数据已经准备好,按下按键即开始传输! _7 _9 j9 v2 V, W9 N$ T while(GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_3)); I" d- i# k. x6 o " d3 D6 S8 ?& w s printf("Start DMA transmission!\r\n");6 b" N# g( j. d( H //这里是开始DMA传输前的一些准备工作,将USART1模块设置成DMA方式工作; g8 n! ^; L8 V USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); //开始一次DMA传输! DMA_Cmd(DMA1_Channel4, ENABLE);. i% h7 l% I9 o 6 \% c+ u L+ _ //等待DMA传输完成,此时我们来做另外一些事,点灯; j/ d6 ^# o" C+ E" \ //实际应用中,传输数据期间,可以执行另外的任务 while(DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET) { LED_1_REV; //LED翻转) x/ z: F' a0 A+ M Delay(); //浪费时间 }& k9 g: F* y1 Y8 B0 z4 f- i8 x //DMA传输结束后,自动关闭了DMA通道,而无需手动关闭) m5 |- g" f' ]2 J" ~* Z6 h5 n //下面的语句被注释, `# \1 Q7 v4 x; g //DMA_Cmd(DMA1_Channel4, DISABLE);4 b6 y' m* ?0 L a printf("\r\nDMA transmission successful!\r\n"); /* Infinite loop */ while (1) { } } ! x1 A# j( `# O' E* e /******************************************************************************* * Function Name : 重定义系统putchar函数int fputc(int ch, FILE *f)7 R( T, ]0 J* L& c9 { * Description : 串口发一个字节( A& d" E, F" ^1 S * Input : int ch, FILE *f * Output : o D0 p) M; D. w+ K * Return : int ch8 H/ P& s! l- w9 |: F5 Z * 这个是使用printf的关键% N z: S5 u7 `% ^ *******************************************************************************/9 x# S2 R2 {0 Y int fputc(int ch, FILE *f) {5 [. [2 x: {4 J$ e* f& m //USART_SendData(USART1, (u8) ch); USART1->DR = (u8) ch; b+ F r2 n2 N! I0 V6 g- _6 w- { /* Loop until the end of transmission */ while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)0 D; n( b% r) P { } 5 I- e& g& O* `( k X return ch; } /*******************************************************************************% a) l( s9 V2 j; P w7 [ * Function Name : Delay6 ~( ^5 j6 O- r+ c" t; Z% x * Description : 延时函数8 I# q, Z" i% a * Input : None$ C9 l8 Z* h% v1 W- c Y; C ] * Output : None * Return : None *******************************************************************************/* I" ]/ M7 A- I; H2 s2 g, ], S void Delay(void) { u32 i;& z# v3 `3 R& T4 v% o4 \" N/ M for(i=0;i外设. S3 O7 S. T/ m( P //每次传输位:8bit+ I9 b3 U0 C/ o" b9 B% P //传输大小DMA_BufferSize=SENDBUFF_SIZE( ~/ |* X9 j* r Y* N) k- ] //地址自增模式:外设地址不增,内存地址自增1 //DMA模式:一次传输,非循环 //优先级:中 DMA_DeInit(DMA1_Channel4);8 w* |# v5 x+ o5 L$ C+ d2 ?9 N7 Z DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;+ m( u+ U$ P: F+ `3 z/ y5 }" x4 x5 B( w 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; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;2 Q" Z" {: ~( x& c DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;% n9 Q' ~% |' O! b: G+ } DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; F# ]. { J% v+ Q2 u& X, }6 X DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;; u# ^. u9 I, w2 r5 a5 F1 a DMA_Init(DMA1_Channel4, &DMA_InitStructure);# f, E- O( A# m& d4 k } |
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的演示
- F5 o8 t5 ~# [" O' j
haodongxi 好东西启封箱