在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            stm32之DMA徹底研究(2)

            作者: 時(shí)間:2016-11-19 來(lái)源:網(wǎng)絡(luò) 收藏
            AD轉(zhuǎn)換之DMA

            1、DMA的配置

            本文引用地址:http://www.biyoush.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; //片內(nèi)外設(shè)作源頭
            DMA_InitStructure.DMA_BufferSize = 16; //每次DMA16個(gè)數(shù)據(jù)
            DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外設(shè)地址不增加
            DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //內(nèi)存地址增加
            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)先級(jí)
            DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //非內(nèi)存到內(nèi)存
            DMA_Init(DMA1_Channel1, &DMA_InitStructure);

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

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

            要配置的內(nèi)容有:

            (1)DMA1的AHB時(shí)鐘使能

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

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

            (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); //清除全部中斷標(biāo)志
            ADC_Ok=TRUE;
            }
            }

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

            重新允許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);
            }

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

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

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

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

            DMAReConfig();//重新啟動(dòng)DMA

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

            //轉(zhuǎn)換為溫度值,實(shí)際應(yīng)用中,可考慮用毫伏為單位,避免浮點(diǎn)運(yùn)算

            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("當(dāng)前溫度是:");
            USART1_Putc(a+0);
            USART1_Putc(b+0);
            USART1_Putc(c+0);
            USART1_Putc(d+0);
            USART1_Puts("C rn");
            }
            }
            }

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

            (1)當(dāng)一次DMA傳輸完成后,主程序根據(jù)標(biāo)志量,計(jì)算轉(zhuǎn)換出來(lái)的ad值。

            (2)重新啟動(dòng)DMA

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

            (4)等待下一個(gè)DMA傳輸完成的到來(lái),進(jìn)行下一個(gè)周期的轉(zhuǎn)換和計(jì)算。

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

            //設(shè)置所有的中斷允許

            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中斷的時(shí)候,也可以配置成傳輸一半產(chǎn)生中斷的方式。

            我們可以做如下實(shí)驗(yàn):

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

            DMA_ITConfig(DMA1_Channel4, DMA_IT_HT, ENABLE);

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

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

            }
            }

            在此中斷中設(shè)置斷點(diǎn),當(dāng)產(chǎn)生中斷后,發(fā)現(xiàn)DMA傳送并沒(méi)有結(jié)束。

            只是cpu“停止”了。

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



            關(guān)鍵詞: STM32DM

            評(píng)論


            技術(shù)專(zhuān)區(qū)

            關(guān)閉