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

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > stm32之DMA徹底研究(2)

          stm32之DMA徹底研究(2)

          作者: 時間:2016-11-19 來源:網(wǎng)絡 收藏
          AD轉換之DMA

          1、DMA的配置

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

          //DMA的配置
          void DMA_Configuration(void)
          {

          /* 允許 DMA1 */
          RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
          /* DMA通道1*/
          DMA_DeInit(DMA1_Channel1);
          DMA_InitStructure.DMA_PeripheralBaseAddr =(u32)( &(ADC1->DR)); //ADC1數(shù)據(jù)寄存器
          DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADCCov; //獲取ADC的數(shù)組
          DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //片內外設作源頭
          DMA_InitStructure.DMA_BufferSize = 16; //每次DMA16個數(shù)據(jù)
          DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外設地址不增加
          DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //內存地址增加
          DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //半字
          DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //半字
          DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //普通模式
          DMA_InitStructure.DMA_Priority = DMA_Priority_High; //高優(yōu)先級
          DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //非內存到內存
          DMA_Init(DMA1_Channel1, &DMA_InitStructure);

          DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); //DMA通道1傳輸完成中斷

          /* Enable DMA1 channel1 */
          DMA_Cmd(DMA1_Channel1, ENABLE);
          }

          要配置的內容有:

          (1)DMA1的AHB時鐘使能

          (2)DMA的源端和目的端的配置以及傳輸方向的配置

          (3)每次DMA的數(shù)據(jù)長度、地址是否增加、模式、優(yōu)先級等等

          (4)使能DMA中斷

          (5)使能DMA1的通道1(通道選擇)

          本例程中DMA中斷的操作如下:

          /*******************************************************************************
          * Function Name : DMAChannel1_IRQHandler
          * Description : This function handles DMA Stream 1 interrupt request.
          * Input : None
          * Output : None
          * Return : None
          *******************************************************************************/
          extern volatile bool ADC_Ok;
          void DMA1_Channel1_IRQHandler(void)
          {
          if(DMA_GetITStatus(DMA1_IT_TC1))
          {
          DMA_ClearITPendingBit(DMA1_IT_GL1); //清除全部中斷標志
          ADC_Ok=TRUE;
          }
          }

          在DMA1的1通道的中斷程序中,清楚中斷標志,并且將AD標志位置位。

          重新允許DMA

          void DMAReConfig(void)
          {
          DMA_DeInit(DMA1_Channel1);
          DMA_Init(DMA1_Channel1, &DMA_InitStructure);
          DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
          DMA_Cmd(DMA1_Channel1, ENABLE);
          }

          下面是主程序中,對AD和DMA的使用操作:

          int main(void)
          {
          u16 adc;
          u8 a,b,c,d;

          ChipHalInit(); //片內硬件初始化
          ChipOutHalInit(); //片外硬件初始化

          for(;;)
          {
          if(ADC_Ok==TRUE)
          {
          ADC_Ok=FALSE;
          adc=DigitFilter(ADCCov,16); //濾波

          DMAReConfig();//重新啟動DMA

          adc=(1.42 - adc*3.3/4096)*1000/4.35 + 25;

          //轉換為溫度值,實際應用中,可考慮用毫伏為單位,避免浮點運算

          a = adc/1000;
          b = (adc - a*1000)/100;
          c = (adc - a*1000 - b*100)/10;
          d = adc - a*1000 - b*100 - c*10;

          USART1_Puts("當前溫度是:");
          USART1_Putc(a+0);
          USART1_Putc(b+0);
          USART1_Putc(c+0);
          USART1_Putc(d+0);
          USART1_Puts("C rn");
          }
          }
          }

          這段程序所完成的操作有:

          (1)當一次DMA傳輸完成后,主程序根據(jù)標志量,計算轉換出來的ad值。

          (2)重新啟動DMA

          (3)將ad值計算成溫度,然后將溫度值通過串口發(fā)送出去。

          (4)等待下一個DMA傳輸完成的到來,進行下一個周期的轉換和計算。

          還有一點比較重要的就是NVIC的配置,任何stm32的中斷程序都需要配置NVIC,有的時候有一忽視掉。

          //設置所有的中斷允許

          void NVIC_Configuration(void)
          {
          NVIC_InitTypeDef NVIC_InitStructure;

          /* Configure one bit for preemption priority */
          NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

          /* Enable DMA channel1 IRQ Channel */
          NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
          NVIC_Init(&NVIC_InitStructure);

          }

          另外,在配置DMA中斷的時候,也可以配置成傳輸一半產(chǎn)生中斷的方式。

          我們可以做如下實驗:

          將DMA中斷設置成傳輸一半產(chǎn)生中斷,如下:

          DMA_ITConfig(DMA1_Channel4, DMA_IT_HT, ENABLE);

          當數(shù)據(jù)傳送到一半的時候發(fā)現(xiàn)進入到中斷:

          void DMA1_Channel4_IRQHandler(void)
          {
          if(DMA_GetITStatus(DMA1_IT_HT4))
          {
          DMA_ClearITPendingBit(DMA1_IT_HT4);

          }
          }

          在此中斷中設置斷點,當產(chǎn)生中斷后,發(fā)現(xiàn)DMA傳送并沒有結束。

          只是cpu“停止”了。

          DMA仍然將剩下的一半數(shù)據(jù)傳送完。



          關鍵詞: STM32DM

          評論


          技術專區(qū)

          關閉
          看屁屁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); })();