<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          STM32---DMA(USART)的演示

          作者: 時(shí)間:2016-12-02 來源:網(wǎng)絡(luò) 收藏
           這里有個(gè)小小的例子,來演示DMA模塊與系統(tǒng)程序并行工作。

            用串口以低波特率發(fā)送一個(gè)10K的數(shù)據(jù),花費(fèi)近10s時(shí)間,此時(shí)按照以往方法,CPU要不斷等待數(shù)據(jù)發(fā)送、送數(shù)據(jù);或者送數(shù)據(jù)、進(jìn)中斷、送數(shù)據(jù),處理起來比較消耗時(shí)間。
            使用了DMA功能以后,用戶程序中只需配置好DMA,開啟傳輸后,再也不需要操心,10K數(shù)據(jù)完成后會(huì)有標(biāo)志位或中斷產(chǎn)生,期間可以做任何想做的事,非常方便。
            這個(gè)是相應(yīng)的代碼例子,基于STM32F103VBT6

          本文引用地址:http://www.ex-cimer.com/article/201612/325021.htm


          /******************************************************************************
          * 本文件實(shí)現(xiàn)串口發(fā)送功能(通過重構(gòu)putchar函數(shù),調(diào)用printf;或者USART_SendData()
          * 這里是一個(gè)用串口實(shí)現(xiàn)大量數(shù)據(jù)傳輸?shù)睦?,使用了DMA模塊進(jìn)行內(nèi)存到USART的傳輸
          * 每當(dāng)USART的發(fā)送緩沖區(qū)空時(shí),USART模塊產(chǎn)生一個(gè)DMA事件,
          * 此時(shí)DMA模塊響應(yīng)該事件,自動(dòng)從預(yù)先定義好的發(fā)送緩沖區(qū)中拿出下一個(gè)字節(jié)送給USART
          * 整個(gè)過程無需用戶程序干預(yù),用戶只需啟動(dòng)DMA傳輸傳輸即可
          * 在仿真器調(diào)試時(shí),可以在數(shù)據(jù)傳輸過程中暫停運(yùn)行,此時(shí)DMA模塊并沒有停止
          * 串口依然發(fā)送,表明DMA傳輸是一個(gè)獨(dú)立的過程。
          * 同時(shí)開啟接收中斷,在串口中斷中將數(shù)據(jù)存入緩沖區(qū),在main主循環(huán)中處理
          *******************************************************************************/

          /* Includes ------------------------------------------------------------------*/
          #i nclude "stm32f10x_lib.h"
          #i nclude "stdio.h"

          /* Private typedef -----------------------------------------------------------*/
          /* Private define ------------------------------------------------------------*/
          #define USART1_DR_Base 0x40013804

          /* Private macro -------------------------------------------------------------*/
          /* Private variables ---------------------------------------------------------*/
          #define SENDBUFF_SIZE 10240
          vu8 SendBuff[SENDBUFF_SIZE];
          vu8 RecvBuff[10];
          vu8 recv_ptr;

          /* Private prototypes -----------------------------------------------*/
          void RCC_Configuration(void);
          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);

          /* Private s ---------------------------------------------------------*/
          /*******************************************************************************
          * Name : main
          * Deion : Main program.
          * Input : None
          * Output : None
          * Return : None
          *******************************************************************************/
          int main(void)
          {
          u16 i;
          #ifdef DEBUG
          debug();
          #endif
          recv_ptr = 0;

          RCC_Configuration();
          GPIO_Configuration();
          NVIC_Configuration();
          DMA_Configuration();
          USART1_Configuration();

          printf("rnSystem Start...rn");
          printf("Initialling SendBuff... rn");
          for(i=0;i {
          SendBuff[i] = i&0xff;
          }
          printf("Initial success!rnWaiting for transmission...rn");
          //發(fā)送去數(shù)據(jù)已經(jīng)準(zhǔn)備好,按下按鍵即開始傳輸
          while(GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_3));

          printf("Start DMA transmission!rn");

          //這里是開始DMA傳輸前的一些準(zhǔn)備工作,將USART1模塊設(shè)置成DMA方式工作
          USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
          //開始一次DMA傳輸!
          DMA_Cmd(DMA1_Channel4, ENABLE);

          //等待DMA傳輸完成,此時(shí)我們來做另外一些事,點(diǎn)燈
          //實(shí)際應(yīng)用中,傳輸數(shù)據(jù)期間,可以執(zhí)行另外的任務(wù)
          while(DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET)
          {
          LED_1_REV; //LED翻轉(zhuǎn)
          Delay(); //浪費(fèi)時(shí)間
          }
          //DMA傳輸結(jié)束后,自動(dòng)關(guān)閉了DMA通道,而無需手動(dòng)關(guān)閉
          //下面的語句被注釋
          //DMA_Cmd(DMA1_Channel4, DISABLE);

          printf("rnDMA transmission successful!rn");


          /* Infinite loop */
          while (1)
          {
          }
          }

          /*******************************************************************************
          * Name : 重定義系統(tǒng)putchar函數(shù)int fputc(int ch, FILE *f)
          * Deion : 串口發(fā)一個(gè)字節(jié)
          * Input : int ch, FILE *f
          * Output :
          * Return : int ch
          * 這個(gè)是使用printf的關(guān)鍵
          *******************************************************************************/
          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)
          {
          }

          return ch;
          }

          /*******************************************************************************
          * Name : Delay
          * Deion : 延時(shí)函數(shù)
          * Input : None
          * Output : None
          * Return : None
          *******************************************************************************/
          void Delay(void)
          {
          u32 i;
          for(i=0;i<0xF0000;i++);
          return;
          }

          /*******************************************************************************
          * Name : RCC_Configuration
          * Deion : 系統(tǒng)時(shí)鐘設(shè)置
          * Input : None
          * Output : None
          * Return : None
          *******************************************************************************/
          void RCC_Configuration(void)
          {
          ErrorStatus HSEStartUpStatus;

          //使能外部晶振
          RCC_HSEConfig(RCC_HSE_ON);
          //等待外部晶振穩(wěn)定
          HSEStartUpStatus = RCC_WaitForHSEStartUp();
          //如果外部晶振啟動(dòng)成功,則進(jìn)行下一步操作
          if(HSEStartUpStatus==SUCCESS)
          {
          //設(shè)置HCLK(AHB時(shí)鐘)=SYSCLK
          RCC_HCLKConfig(RCC_SYSCLK_Div1);

          //PCLK1(APB1) = HCLK/2
          RCC_PCLK1Config(RCC_HCLK_Div2);

          //PCLK2(APB2) = HCLK
          RCC_PCLK2Config(RCC_HCLK_Div1);

          //FLASH時(shí)序控制
          //推薦值:SYSCLK = 0~24MHz Latency=0
          // SYSCLK = 24~48MHz Latency=1
          // SYSCLK = 48~72MHz Latency=2
          FLASH_SetLatency(FLASH_Latency_2);
          //開啟FLASH預(yù)取指功能
          FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

          //PLL設(shè)置 SYSCLK/1 * 9 = 8*1*9 = 72MHz
          RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
          //啟動(dòng)PLL
          RCC_PLLCmd(ENABLE);
          //等待PLL穩(wěn)定
          while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
          //系統(tǒng)時(shí)鐘SYSCLK來自PLL輸出
          RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
          //切換時(shí)鐘后等待系統(tǒng)時(shí)鐘穩(wěn)定
          while(RCC_GetSYSCLKSource()!=0x08);


          /*
          //設(shè)置系統(tǒng)SYSCLK時(shí)鐘為HSE輸入
          RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE);
          //等待時(shí)鐘切換成功
          while(RCC_GetSYSCLKSource() != 0x04);
          */
          }

          //下面是給各模塊開啟時(shí)鐘
          //啟動(dòng)GPIO
          RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
          RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD,
          ENABLE);
          //啟動(dòng)AFIO
          RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
          //啟動(dòng)USART1
          RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
          //啟動(dòng)DMA時(shí)鐘
          RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

          }

          /*******************************************************************************
          * Name : GPIO_Configuration
          * Deion : GPIO設(shè)置
          * Input : None
          * Output : None
          * Return : None
          *******************************************************************************/
          void GPIO_Configuration(void)
          {
          GPIO_InitTypeDef GPIO_InitStructure;

          //PC口4567腳設(shè)置GPIO輸出,推挽 2M
          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
          GPIO_Init(GPIOC, &GPIO_InitStructure);

          //KEY2 KEY3 JOYKEY
          //位于PD口的3 4 11-15腳,使能設(shè)置為輸入
          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_11 | GPIO_Pin_12 |
          GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
          GPIO_Init(GPIOD, &GPIO_InitStructure);

          //USART1_TX
          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
          GPIO_Init(GPIOA, &GPIO_InitStructure);

          //USART1_RX
          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
          GPIO_Init(GPIOA, &GPIO_InitStructure);

          }

          /*******************************************************************************
          * Name : NVIC_Configuration
          * Deion : NVIC設(shè)置
          * Input : None
          * Output : None
          * Return : None
          *******************************************************************************/
          void NVIC_Configuration(void)
          {
          NVIC_InitTypeDef NVIC_InitStructure;

          #ifdef VECT_TAB_RAM
          // Set the Vector Table base location at 0x20000000
          NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
          #else /* VECT_TAB_FLASH */
          // Set the Vector Table base location at 0x08000000
          NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
          #endif

          //設(shè)置NVIC優(yōu)先級(jí)分組為Group2:0-3搶占式優(yōu)先級(jí),0-3的響應(yīng)式優(yōu)先級(jí)
          NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
          //串口接收中斷打開
          NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
          NVIC_Init(&NVIC_InitStructure);
          }


          /*******************************************************************************
          * Name : USART1_Configuration
          * Deion : NUSART1設(shè)置
          * Input : None
          * Output : None
          * Return : None
          *******************************************************************************/
          void USART1_Configuration(void)
          {
          USART_InitTypeDef USART_InitStructure;

          USART_InitStructure.USART_BaudRate = 9600;
          USART_InitStructure.USART_WordLength = USART_WordLength_8b;
          USART_InitStructure.USART_StopBits = USART_StopBits_1;
          USART_InitStructure.USART_Parity = USART_Parity_No;
          USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
          USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
          USART_Init(USART1, &USART_InitStructure);

          USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

          USART_Cmd(USART1, ENABLE);
          }


          void DMA_Configuration(void)
          {
          DMA_InitTypeDef DMA_InitStructure;
          //DMA設(shè)置:
          //設(shè)置DMA源:內(nèi)存地址&串口數(shù)據(jù)寄存器地址
          //方向:內(nèi)存-->外設(shè)
          //每次傳輸位:8bit
          //傳輸大小DMA_BufferSize=SENDBUFF_SIZE
          //地址自增模式:外設(shè)地址不增,內(nèi)存地址自增1
          //DMA模式:一次傳輸,非循環(huán)
          //優(yōu)先級(jí):中
          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;
          DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
          DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
          DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
          DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
          DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
          DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
          DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
          DMA_Init(DMA1_Channel4, &DMA_InitStructure);
          }



          關(guān)鍵詞: STM32DMAUSAR

          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();