|
这里有个小小的例子,来演示DMA模块与系统程序并行工作。/ l/ y) A' Q7 \" `0 T9 J2 b4 t 用串口以低波特率发送一个10K的数据,花费近10s时间,此时按照以往方法,CPU要不断等待数据发送、送数据;或者送数据、进中断、送数据,处理起来比较消耗时间。4 c; H% `5 H5 m 使用了DMA功能以后,用户程序中只需配置好DMA,开启传输后,再也不需要操心,10K数据完成后会有标志位或中断产生,期间可以做任何想做的事,非常方便。 这个是相应的代码例子,基于STM32F103VBT6 1 L7 c; g7 K2 z- E/ c9 S" p6 l 9 v% H: V: Z! W6 E( e1 ]" Z+ I6 `) T( _ /****************************************************************************** * 本文件实现串口发送功能(通过重构putchar函数,调用printf;或者USART_SendData() * 这里是一个用串口实现大量数据传输的例子,使用了DMA模块进行内存到USART的传输 * 每当USART的发送缓冲区空时,USART模块产生一个DMA事件, * 此时DMA模块响应该事件,自动从预先定义好的发送缓冲区中拿出下一个字节送给USART% O3 g$ _' n6 ~2 Q6 F' n * 整个过程无需用户程序干预,用户只需启动DMA传输传输即可 S, j8 P2 t% s D. \5 c * 在仿真器调试时,可以在数据传输过程中暂停运行,此时DMA模块并没有停止# C* f3 `- p8 a$ A1 L6 J1 M8 Z0 Z( M * 串口依然发送,表明DMA传输是一个独立的过程。7 @, E8 `3 b4 x/ O, W * 同时开启接收中断,在串口中断中将数据存入缓冲区,在main主循环中处理) r" `( w4 i$ B5 b. h8 n- H" t0 w * 作者:jjldc(九九)5 y2 {$ _, G( ^# r5 C- E * 代码硬件基于万利199元的EK-STM32F开发板,CPU=STM32F103VBT6 *******************************************************************************/7 W* m! \8 c' B" t & r, ~4 N, v" {3 W: h) }' r3 E* F /* Includes ------------------------------------------------------------------*/ #include "stm32f10x_lib.h" #include "stdio.h" /* Private typedef -----------------------------------------------------------*/) d% y. L' Y1 t( {* |, I /* Private define ------------------------------------------------------------*/( u$ V7 U: F( ]4 u6 u #define USART1_DR_Base 0x40013804 : s0 w, D3 C7 }/ w1 H /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/1 u4 I! v& k$ d/ y$ R# @0 Z #define SENDBUFF_SIZE 10240 vu8 SendBuff[SENDBUFF_SIZE]; vu8 RecvBuff[10]; vu8 recv_ptr;, D6 [$ Q) D% G: {- S; e( w /* Private function prototypes -----------------------------------------------*/ void RCC_Configuration(void); void GPIO_Configuration(void);/ z$ @, c1 b) h! S0 } void NVIC_Configuration(void);: h/ O" w; K8 W void DMA_Configuration(void);! }/ [4 u w: M. I- q- G void USART1_Configuration(void);& [" `+ C* V9 t: I3 J* \1 m2 i " c+ I2 o z* s8 n4 P8 O7 [ int fputc(int ch, FILE *f); void Delay(void); M$ @: i2 C0 l6 \# Q 6 }- N7 O6 L0 B" o/ D! d. m/ Q6 p /* Private functions ---------------------------------------------------------*/ /*******************************************************************************% Z& P4 b0 M% d) N, h+ ~ * Function Name : main * Description : Main program. * Input : None * Output : None * Return : None *******************************************************************************/ int main(void) { u16 i; #ifdef DEBUG debug(); #endif recv_ptr = 0;! X& C7 ]) Z$ P2 s! A3 ?0 ~( ~$ t, b: ~! Y RCC_Configuration();# g0 e7 u0 P) ] GPIO_Configuration(); NVIC_Configuration(); T$ V* c; L: K+ @) o* Y; j DMA_Configuration();5 s$ C. R3 h( n! A& M USART1_Configuration();4 l; k2 E1 u( p3 T; o% D2 Q) n+ R ! {0 u. l, S6 E printf("\r\nSystem Start...\r\n"); printf("Initialling SendBuff... \r\n");' b( u5 Z, m' O* c6 P. ? for(i=0;i {& {. ?0 }/ X8 O7 B2 c SendBuff = i&0xff;5 i& q0 }8 Y4 N }! }* Y% x* C" g) q4 B printf("Initial success!\r\nWaiting for transmission...\r\n"); //发送去数据已经准备好,按下按键即开始传输/ h1 p- q: O2 E) `1 ?: w8 F while(GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_3)); printf("Start DMA transmission!\r\n");4 M7 H' J4 m6 i //这里是开始DMA传输前的一些准备工作,将USART1模块设置成DMA方式工作$ Z9 ?' a' S: U% I USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); //开始一次DMA传输!: G8 v& C e% E5 d3 V DMA_Cmd(DMA1_Channel4, ENABLE);5 S' N: K" d$ o- }6 K" ~ //等待DMA传输完成,此时我们来做另外一些事,点灯+ d4 X% ], u9 D" q, D( l `# |! p //实际应用中,传输数据期间,可以执行另外的任务 while(DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET) {% |; x- h) L9 d/ T! i: `* M7 E LED_1_REV; //LED翻转 Delay(); //浪费时间7 s: \& l3 r n } //DMA传输结束后,自动关闭了DMA通道,而无需手动关闭4 w5 T- A+ Y3 I$ H( D! P! n6 S# s //下面的语句被注释/ H( H" H& W% c# x B6 |$ @ //DMA_Cmd(DMA1_Channel4, DISABLE);: T: D% r2 c! o% Z6 `! c* t3 _ printf("\r\nDMA transmission successful!\r\n");8 P4 g* i; y$ [' I9 e* \/ i3 R4 [ /* Infinite loop */ while (1) {6 t& z9 L* ^+ a. Z2 P8 ? } }7 `" Y; M h2 i* S /*******************************************************************************/ d- c+ G6 H) \" D7 k * Function Name : 重定义系统putchar函数int fputc(int ch, FILE *f)+ A% _$ z( _' m& [6 s7 n3 j * Description : 串口发一个字节 * Input : int ch, FILE *f * Output : $ K; v) I' ^; C* a* ?5 x * Return : int ch+ A; f6 S! y. ^% I$ H+ \3 @1 _ X0 z4 H * 这个是使用printf的关键7 P" i9 k0 K0 v *******************************************************************************/! O/ |6 |* f0 U7 k int fputc(int ch, FILE *f) { //USART_SendData(USART1, (u8) ch); USART1->DR = (u8) ch; /* Loop until the end of transmission */ while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET). ?; ~/ o& d6 X) ~, { {3 B* i4 `7 L. c( L3 c0 d! O }5 T, I0 z* e: G8 K / j4 N7 L0 e2 q5 a5 I return ch; } /*******************************************************************************7 `* O: D" z* ~2 i/ e1 c2 t. A * Function Name : Delay * Description : 延时函数 * Input : None * Output : None * Return : None *******************************************************************************/ void Delay(void) {# @$ z$ }4 Z0 [2 w u32 i; for(i=0;i外设 //每次传输位:8bit$ z$ D5 p% s7 t) {' _ V //传输大小DMA_BufferSize=SENDBUFF_SIZE5 i8 j$ q- l" n //地址自增模式:外设地址不增,内存地址自增1 //DMA模式:一次传输,非循环/ c+ o4 y$ c$ y5 s K //优先级:中 DMA_DeInit(DMA1_Channel4); DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base; DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff;4 N* a6 |3 C: [7 T DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;. O; F! _# W5 f5 c1 D6 m7 ?$ }. O DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;; r6 h' @' C$ H3 k2 n DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;8 W. ?5 l% [9 W DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;! g8 g. I' I j DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;3 h: r# L+ d7 k 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的演示
haodongxi 好东西启封箱