: Q% M7 J+ ^9 U( j+ h 这里有个小小的例子,来演示DMA模块与系统程序并行工作。 用串口以低波特率发送一个10K的数据,花费近10s时间,此时按照以往方法,CPU要不断等待数据发送、送数据;或者送数据、进中断、送数据,处理起来比较消耗时间。 使用了DMA功能以后,用户程序中只需配置好DMA,开启传输后,再也不需要操心,10K数据完成后会有标志位或中断产生,期间可以做任何想做的事,非常方便。& c/ x4 y& }( q$ R5 G 这个是相应的代码例子,基于STM32F103VBT6) c1 D4 R" R. F+ i0 I: d; W 7 T7 M$ `2 S3 L# j2 i9 T* t /****************************************************************************** * 本文件实现串口发送功能(通过重构putchar函数,调用printf;或者USART_SendData() * 这里是一个用串口实现大量数据传输的例子,使用了DMA模块进行内存到USART的传输8 }$ `" u% X, m& { * 每当USART的发送缓冲区空时,USART模块产生一个DMA事件, * 此时DMA模块响应该事件,自动从预先定义好的发送缓冲区中拿出下一个字节送给USART * 整个过程无需用户程序干预,用户只需启动DMA传输传输即可5 {) I1 s# ^- i* c; l0 Q * 在仿真器调试时,可以在数据传输过程中暂停运行,此时DMA模块并没有停止2 E1 }8 U" d* n" N2 Z * 串口依然发送,表明DMA传输是一个独立的过程。6 M W% R& s2 F* I: S/ b3 d3 n * 同时开启接收中断,在串口中断中将数据存入缓冲区,在main主循环中处理! h2 K+ k$ b0 p0 \+ {7 T3 q7 v * 作者:jjldc(九九) * 代码硬件基于万利199元的EK-STM32F开发板,CPU=STM32F103VBT6 *******************************************************************************/ ' w' E9 g' A; [' O* R /* Includes ------------------------------------------------------------------*/ #include "stm32f10x_lib.h" #include "stdio.h"6 ?9 f* Q# G. |0 j9 @/ B5 t G 3 g- i+ z# F. `/ w8 [ P /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ #define USART1_DR_Base 0x40013804 /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ #define SENDBUFF_SIZE 10240; q5 {- {* Y) N6 E4 ^% `# t! f vu8 SendBuff[SENDBUFF_SIZE]; vu8 RecvBuff[10]; vu8 recv_ptr;* X' x, I4 y' d8 ^; G# n& A- P /* Private function prototypes -----------------------------------------------*/7 W/ M6 D$ L+ }- k% c void RCC_Configuration(void);3 X- f$ I# i8 [5 Z. u0 K$ u- g void GPIO_Configuration(void); void NVIC_Configuration(void);5 @. }4 [+ L0 o2 _ void DMA_Configuration(void);2 h2 ] D+ u2 @ W Q void USART1_Configuration(void);" {) I( z8 X ?3 G5 L , o0 j) G# D# N# Y int fputc(int ch, FILE *f); E& t% L [& k void Delay(void); ' Q4 N9 s" F ?8 H5 D$ W: Q. \ /* Private functions ---------------------------------------------------------*/4 l' |7 X4 C2 u+ s2 c /******************************************************************************* * Function Name : main * Description : Main program. * Input : None * Output : None+ @0 M4 F' {9 n' T * Return : None8 M. G b9 u% T: {4 `- S/ w+ T- P *******************************************************************************/ int main(void)4 i) f7 @" f4 d$ c" ~ n9 G& s {8 @+ c7 H/ W, D3 p" {! f u16 i; #ifdef DEBUG debug(); #endif recv_ptr = 0;) t% N( l' N: o9 K: P. \ RCC_Configuration(); GPIO_Configuration();- J) E2 f# v) d. J4 `* ] NVIC_Configuration();$ B) s9 j5 D; M4 O1 l DMA_Configuration();5 ^4 ]: |# Z4 v& R USART1_Configuration();4 j3 o5 |8 O* G( m$ ?8 q+ V printf("\r\nSystem Start...\r\n"); printf("Initialling SendBuff... \r\n"); for(i=0;i {* M$ J$ S- r, ?& o$ i: j SendBuff = i&0xff; }% O5 y }3 \3 A4 B7 ^- I( e printf("Initial success!\r\nWaiting for transmission...\r\n");) `9 h. `1 w) d/ y8 D( X! n5 T //发送去数据已经准备好,按下按键即开始传输! H/ u- u t# b$ }- p+ t+ d while(GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_3)); printf("Start DMA transmission!\r\n");2 }+ F% v {, m: N3 h7 H9 G % I. i$ f. z0 n% K( e/ O" F0 E/ H) ^ //这里是开始DMA传输前的一些准备工作,将USART1模块设置成DMA方式工作3 \2 v' S8 ^0 Y0 `7 D. {2 |: u! g i5 y USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); \# l, }% j# [8 u5 B //开始一次DMA传输! DMA_Cmd(DMA1_Channel4, ENABLE); //等待DMA传输完成,此时我们来做另外一些事,点灯 //实际应用中,传输数据期间,可以执行另外的任务 while(DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET)) J) ^1 C: y$ g {# O( y" Y, U- B; E. ~ LED_1_REV; //LED翻转, r9 K& h7 i, Z& Y; u Delay(); //浪费时间1 @$ i1 s" M' h) S4 o9 d( a } //DMA传输结束后,自动关闭了DMA通道,而无需手动关闭 //下面的语句被注释 //DMA_Cmd(DMA1_Channel4, DISABLE);" s5 r- E8 c2 h1 Y: R/ ~$ ? printf("\r\nDMA transmission successful!\r\n");% n3 v3 w% p- r: o% H 1 k8 V6 k% R( [( b9 [ [( {9 z $ K1 k) K0 Y o/ w) ~, e( D* U /* Infinite loop */ while (1)( x6 Q1 |' l3 H {( p( U6 u$ k0 e$ c }+ d' k9 {( N3 N0 G$ y5 A } ; o0 g0 F; O; _; W4 \, T$ o /*******************************************************************************& C+ E! _. m) } }" N; _6 o * Function Name : 重定义系统putchar函数int fputc(int ch, FILE *f) * Description : 串口发一个字节 * Input : int ch, FILE *f: L/ y/ G1 g% d' {2 t * Output : * Return : int ch * 这个是使用printf的关键! O0 X3 ~ y! d p9 z' w' L$ ?0 x *******************************************************************************/ int fputc(int ch, FILE *f) {4 k& P/ L% A: D. s" m //USART_SendData(USART1, (u8) ch);4 I s( Q' r9 |! D USART1->DR = (u8) ch; /* Loop until the end of transmission */4 I2 z% B; `) K5 O while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)9 u' s9 F( _ \( v3 N. ? {+ W! \! ?8 b3 h& U! _5 ? }, J7 l/ }& T# Y4 l- O" b- _ * k2 z7 y" W k* U- ^/ _ return ch; } ( n% P, l9 R2 s9 Q0 t# U' s$ C% } /******************************************************************************* * Function Name : Delay * Description : 延时函数 * Input : None * Output : None * Return : None |+ b& Q. |( l. a: Z: [ *******************************************************************************/# ^, @2 o. j& p6 x2 x! t void Delay(void) { u32 i; for(i=0;i外设 //每次传输位:8bit$ O; T+ i5 G* I //传输大小DMA_BufferSize=SENDBUFF_SIZE& o+ |( d# [/ c6 D //地址自增模式:外设地址不增,内存地址自增12 H2 I2 @$ G. _ R- w: G" C9 b" G //DMA模式:一次传输,非循环" V- U$ t( p8 i0 H9 }! T3 G //优先级:中7 `$ a# F+ I. a7 H3 d DMA_DeInit(DMA1_Channel4); DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base; DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;7 L- Y& m% N# V" G DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;& [' K; y# P& ~9 B9 \! ? |* K- C( P DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;% U- c2 `2 u6 h! {# a DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel4, &DMA_InitStructure);8 f! g3 z) Z: O8 g- 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的演示
haodongxi 好东西启封箱