新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > stm32 ADC的規(guī)則通道和注入通道混合使用

        stm32 ADC的規(guī)則通道和注入通道混合使用

        作者: 時(shí)間:2016-11-10 來源:網(wǎng)絡(luò) 收藏
        之前完成了規(guī)則通道DMA的數(shù)據(jù)傳輸了,不過平時(shí)在使用ADC的時(shí)候可能就會(huì)遇到很多情況,不可能就這樣簡單的按規(guī)則通道來采樣,DMA存儲(chǔ),使用數(shù)據(jù)的;可能有時(shí)候會(huì)需要立刻采樣,那樣我們就需要利用到注入通道了。文檔關(guān)于注入通道的解釋:
        1      利用外部觸發(fā)或通過設(shè)置ADC_CR2寄存器的ADON位,啟動(dòng)一組規(guī)則通道的轉(zhuǎn)換。 2      如果在規(guī)則通道轉(zhuǎn)換期間產(chǎn)生一外部注入觸發(fā),當(dāng)前轉(zhuǎn)換被復(fù)位,注入通道序列被以單次掃描方式進(jìn)行轉(zhuǎn)換。 3      然后,恢復(fù)上次被中斷的規(guī)則組通道轉(zhuǎn)換。如果在注入轉(zhuǎn)換期間產(chǎn)生一規(guī)則事件,注入轉(zhuǎn)換不會(huì)被中斷,但是規(guī)則序列將在注入序列結(jié)束后被執(zhí)行。
          將變阻器的那路ADC設(shè)置為注入通道:
        1  ADC_InjectedSequencerLengthConfig(ADC1, 1);\設(shè)置注入通道長度2  ADC_InjectedChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_7Cycles5);\配置注入通道3  ADC_SoftwareStartInjectedConvCmd(ADC1, ENABLE);\開始注入通道數(shù)據(jù)采樣和轉(zhuǎn)換
          開始之后,延遲足夠的時(shí)間,讓ADC采樣和轉(zhuǎn)換完成。
        用ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_1);讀取注入通道1的數(shù)據(jù),結(jié)果發(fā)現(xiàn)數(shù)據(jù)一直不變,那肯定是哪里設(shè)置出錯(cuò)了,找了下別人的設(shè)置,并做了一些嘗試,發(fā)現(xiàn)了原來是設(shè)置的問題,注入采樣的觸發(fā)方式?jīng)]有設(shè)置:
        ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_None);
        這個(gè)函數(shù)設(shè)置注入方式使用軟件觸發(fā)方式,設(shè)置完之后用開始采樣和讀取數(shù)據(jù)函數(shù),就能采到正確的數(shù)據(jù)。
        上面的例子使用觸發(fā)注入完成的,下面又嘗試了自動(dòng)注入。這樣每次進(jìn)行規(guī)則通道采樣時(shí),也會(huì)順便把注入通道也進(jìn)行采樣了,而啟動(dòng)注入通道采樣則不會(huì)對規(guī)則通道進(jìn)行采樣。
        如果設(shè)置了 JAUTO 位,在規(guī)則組通道之后,注入組通道被自動(dòng)轉(zhuǎn)換。這可以用來轉(zhuǎn)換在 ADC_SQRx 和 ADC_JSQR 寄存器中設(shè)置的多至 20 個(gè)轉(zhuǎn)換序列。
        還有在規(guī)則通道使用DMA數(shù)據(jù)傳輸,且使用注入通道采樣時(shí),不知道會(huì)不會(huì)對數(shù)據(jù)有影響?
        查了下文檔,只有在規(guī)則通道的轉(zhuǎn)換結(jié)束時(shí)才產(chǎn)生 DMA 請求,并將轉(zhuǎn)換的數(shù)據(jù)從 ADC_DR 寄存器傳輸?shù)接脩糁付ǖ哪康牡刂罚€有注入方式轉(zhuǎn)換后數(shù)據(jù)存儲(chǔ)到 ADC_DRJx寄存器和規(guī)則方式轉(zhuǎn)換后數(shù)據(jù)存儲(chǔ)在ADC_DR寄存器中。
          在注入通道和規(guī)則通道的混合使用中,我花了不少時(shí)間去找正確的設(shè)置,問題是不知道哪些庫函數(shù)是必要的,哪些是非必要的,后來對著例子嘗試之后才知道。后面我還想了解下具體的寄存器設(shè)置,看了幾個(gè)初始化的函數(shù),發(fā)現(xiàn)其實(shí)很多設(shè)置都是對ADC_CR1的設(shè)置,有不少不明白的看了寄存器就知道了,看來函數(shù)的使用還是要和寄存器對應(yīng)的位結(jié)合起來,這樣才能理解的透徹點(diǎn)。
          下面是我整個(gè)代碼的設(shè)置,其他設(shè)置和上篇例子一樣,只改了ADC設(shè)置:

        本文引用地址:http://www.104case.com/article/201611/317106.htm
        [cpp]view plaincopy
        1. staticvoidProtect_AdcInit(void)
        2. {
        3. ADC_InitTypeDefADC_InitStructure;
        4. ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;
        5. ADC_InitStructure.ADC_ScanConvMode=ENABLE;
        6. ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;
        7. ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//軟件觸發(fā)
        8. ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;
        9. ADC_InitStructure.ADC_NbrOfChannel=2;//規(guī)則通道的數(shù)量
        10. ADC_Init(ADC1,&ADC_InitStructure);//這個(gè)大部分是初始化規(guī)則通道的
        11. ADC_TempSensorVrefintCmd(ENABLE);
        12. ADC_RegularChannelConfig(ADC1,ADC_Channel_TempSensor,1,ADC_SampleTime_239Cycles5);
        13. ADC_RegularChannelConfig(ADC1,ADC_Channel_Vrefint,2,ADC_SampleTime_239Cycles5);
        14. ADC_InjectedSequencerLengthConfig(ADC1,1);
        15. ADC_InjectedChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_7Cycles5);
        16. ADC_ExternalTrigInjectedConvConfig(ADC1,ADC_ExternalTrigInjecConv_None);//設(shè)置規(guī)則通道軟件觸發(fā)
        17. /*Enableautomaticinjectedconversionstartafterregularone*/
        18. //ADC_AutoInjectedConvCmd(ADC1,ENABLE);
        19. ADC_DMACmd(ADC1,ENABLE);
        20. /*EnableADC1externaltrigger*/
        21. ADC_ExternalTrigConvCmd(ADC1,DISABLE);
        22. ADC_ExternalTrigInjectedConvCmd(ADC1,DISABLE);
        23. ADC_Cmd(ADC1,ENABLE);
        24. ADC_ResetCalibration(ADC1);
        25. while(ADC_GetResetCalibrationStatus(ADC1));
        26. ADC_StartCalibration(ADC1);
        27. while(ADC_GetCalibrationStatus(ADC1));
        28. }

        ======================沒完,繼續(xù)=================

        讀取數(shù)據(jù)在這里:

        /* 注入轉(zhuǎn)換中斷 */
        void ADC1_2_IRQHandler(void)
        {
        s32 inj_v1,inj_v2,inj_v3,inj_v4;


        if(ADC_GetITStatus(ADC1,ADC_IT_JEOC) == SET){
        ADC_ClearITPendingBit(ADC1,ADC_IT_JEOC);
        inj_v1 = ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_1);
        inj_v1 += ADC_GetInjectedConversionValue(ADC2,ADC_InjectedChannel_4);
        inj_v1 >>= 1;


        inj_v2 = ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_2);
        inj_v2 += ADC_GetInjectedConversionValue(ADC2,ADC_InjectedChannel_3);
        inj_v2 >>= 1;


        inj_v3 = ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_3);
        inj_v3 += ADC_GetInjectedConversionValue(ADC2,ADC_InjectedChannel_2);
        inj_v3 >>= 1;


        inj_v4 = ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_4);
        inj_v4 += ADC_GetInjectedConversionValue(ADC2,ADC_InjectedChannel_1);
        inj_v4 >>= 1;
        }
        }


        /* 規(guī)則轉(zhuǎn)換中斷 */
        void DMA1_Channel1_IRQHandler(void)
        {
        if(DMA_GetFlagStatus(DMA1_FLAG_TC1) == SET){
        DMA_ClearFlag(DMA1_FLAG_TC1);
        DMA_ClearITPendingBit(DMA1_IT_GL1);
        ADC_SoftwareStartConvCmd(ADC1,DISABLE);
        DMA_Cmd(DMA1_Channel1,DISABLE);


        /* ¼ÆËãת»»Öµ */
        regular_convert_calc();


        /* Æô¶¯ÏÂÒ»´Î´«Êä */
        DMA1_Channel1->CNDTR = NUM_OF_REG_CHANNEL;
        DMA_Cmd(DMA1_Channel1,ENABLE);
        ADC_SoftwareStartConvCmd(ADC1,ENABLE);
        }
        }

        還有這篇說的也不錯(cuò):用TIM1產(chǎn)生6路ADC,用CCR4觸發(fā)ADC1的注入通道采樣



        評論


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

        關(guān)閉
        主站蜘蛛池模板: 新昌县| 思南县| 陆丰市| 鄯善县| 岳阳县| 松溪县| 濮阳县| 泾源县| 久治县| 鄯善县| 丁青县| 威信县| 揭西县| 得荣县| 宁陵县| 汪清县| 抚顺县| 台中市| 鹤庆县| 利辛县| 迁安市| 石家庄市| 同心县| 昌乐县| 宁强县| 资兴市| 栾城县| 桃江县| 班戈县| 五寨县| 昌宁县| 沙田区| 富锦市| 阳西县| 仁布县| 简阳市| 金秀| 治多县| 革吉县| 崇州市| 泸州市|