精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

STM32G0開發筆記:多通道ADC與DMA的使用

CHANBAEK ? 來源:電子技術攻城獅 ? 作者:MakerInChina.cn ? 2023-01-17 10:41 ? 次閱讀

使用Platformio平臺的libopencm3開發框架來開發STM32G0,以下為多通道ADCDMA的使用。

1 新建項目

  • 建立adc_dma項目

PIO的Home頁面新建項目,項目名稱adc_dma,選擇開發板為 MonkeyPi_STM32_G070RB,開發框架選擇libopencm3;

  • 項目建立完成后在src目錄下新建main.c主程序文件;
  • 修改下載和調試方式,這里開發板使用的是DAPLink仿真器,因此修改platformio.ini文件如下:
1upload_protocol = cmsis-dap
2debug_tool = cmsis-dap

2 編寫程序

2.1 ADC 設置

這里設置PA0、PA1、PA2、PA3四個引腳為ADC:

1static void adc_setup(void)
 2{
 3    rcc_periph_clock_enable(RCC_ADC);
 4    rcc_periph_clock_enable(RCC_GPIOA);
 5
 6    gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO0);
 7    gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO1);
 8    gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO2);
 9    gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO3);
10
11    adc_power_off(ADC1);
12    adc_set_clk_prescale(ADC1, ADC_CCR_PRESC_DIV2);
13    adc_set_single_conversion_mode(ADC1);
14    adc_set_right_aligned(ADC1);
15    adc_set_sample_time_on_all_channels(ADC1, ADC_SMPTIME_160DOT5);
16
17    uint8_t channel_array[16] = {0};
18    channel_array[0] = 0;
19    channel_array[1] = 1;
20    channel_array[2] = 2;
21    channel_array[3] = 3;
22    adc_set_regular_sequence(ADC1, ADC_CHAN_CNT, channel_array);
23    adc_enable_dma_circular_mode(ADC1);
24    adc_set_resolution(ADC1, ADC_CFGR1_RES_12_BIT);
25    adc_power_on(ADC1);
26
27    /* Wait for ADC starting up. */
28    delay_ms(10); 
29}
2.2 DMA配置
1static void dma_setup(void *data, int size)
 2{
 3    dma_channel_reset(DMA1, DMA_CHANNEL1);
 4    dma_set_peripheral_address(DMA1, DMA_CHANNEL1, (uint32_t)&ADC_DR(ADC1));
 5    dma_set_memory_address(DMA1, DMA_CHANNEL1, (uint32_t)data);
 6    dma_set_number_of_data(DMA1, DMA_CHANNEL1, size);
 7    dma_set_read_from_peripheral(DMA1, DMA_CHANNEL1);
 8    dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL1);
 9    dma_set_peripheral_size(DMA1, DMA_CHANNEL1, DMA_CCR_PSIZE_16BIT);
10    dma_set_memory_size(DMA1, DMA_CHANNEL1, DMA_CCR_MSIZE_16BIT);
11    dma_enable_circular_mode(DMA1, DMA_CHANNEL1);
12    dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL1);
13    dma_enable_channel(DMA1, DMA_CHANNEL1);
14
15    dmamux_reset_dma_channel(DMAMUX1, DMA_CHANNEL1);
16    dmamux_set_dma_channel_request(DMAMUX1, DMA_CHANNEL1, DMAMUX_CxCR_DMAREQ_ID_ADC);
17}

主要是設置DMA的外設地址為ADC數據寄存器 ADC_DR;并設置內存地址為定義的buff,size為需要緩存的數據大小:

1#define ADC_CHAN_CNT        4
2#define ADC_FILETER_SIZE    32
3
4int16_t adc_values[ADC_FILETER_SIZE*ADC_CHAN_CNT];
2.3 ADC配置為DMA讀取和Timer觸發
1void tim3_setup(void)
 2{
 3    /* Enable TIM3 clock. */
 4    rcc_periph_clock_enable(RCC_TIM3);
 5
 6    /* Enable TIM3 interrupt. */
 7    nvic_enable_irq(NVIC_TIM3_IRQ);
 8
 9    /* Reset TIM3 peripheral to defaults. */
10    rcc_periph_reset_pulse(RST_TIM3);
11
12    /* Timer global mode:
13     * - No divider
14     * - Alignment edge
15     * - Direction up
16     * (These are actually default values after reset above, so this call
17     * is strictly unnecessary, but demos the api for alternative settings)
18     */
19    timer_set_mode(TIM3, TIM_CR1_CKD_CK_INT,
20                   TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
21
22    /*
23     * Please take note that the clock source for STM32 timers
24     * might not be the raw APB1/APB2 clocks.  In various conditions they
25     * are doubled.  See the Reference Manual for full details!
26     * In our case, TIM3 on APB1 is running at double frequency, so this
27     * sets the prescaler to have the timer run at 5kHz
28     */
29    timer_set_prescaler(TIM3, 64-1);
30
31    /* Disable preload. */
32    timer_disable_preload(TIM3);
33    timer_continuous_mode(TIM3);
34
35    timer_set_period(TIM3, 20000-1); //100Hz
36
37    timer_set_master_mode(TIM3, TIM_CR2_MMS_UPDATE);
38
39    timer_enable_irq(TIM3, TIM_DIER_UIE);
40}
41
42void tim3_enable_counter(bool en)
43{
44    if(en){
45        timer_enable_counter(TIM3);
46    }else{
47        timer_disable_counter(TIM3);
48    }
49}
50
51void tim3_isr(void)
52{
53    if (timer_get_flag(TIM3, TIM_SR_UIF)) {
54
55        /* Clear compare interrupt flag. */
56        timer_clear_flag(TIM3, TIM_SR_UIF);
57    }
58}
  • DMA設置和Timer觸發
1    rcc_periph_clock_enable(RCC_DMA);
 2    nvic_set_priority(NVIC_DMA1_CHANNEL1_IRQ, 3);
 3    nvic_enable_irq(NVIC_DMA1_CHANNEL1_IRQ);
 4
 5    adc_setup();
 6
 7    dma_setup(adc_values, ADC_CHAN_CNT*ADC_FILETER_SIZE);
 8
 9    adc_enable_overrun_interrupt(ADC1);
10
11    adc_enable_dma(ADC1);
12
13    ADC_CFGR1(ADC1) = (ADC_CFGR1(ADC1) & ~(0x3<<10)) | (0x1<<10);    // Hardware trigger detection on the rising edge
14    ADC_CFGR1(ADC1) = (ADC_CFGR1(ADC1) & ~ADC_CFGR1_EXTSEL) | (3<1_EXTSEL_SHIFT);    // toggle by tim3
15
16    tim3_setup();
17
18    adc_start_conversion_regular(ADC1);
19
20
21    tim3_enable_counter(true);
22
23    delay_ms(100);

DMA中斷時候即準備好讀取ADC數據,因此在DMA中斷中先把定時器關閉,讀取數據后再次打開:

1void dma1_channel1_isr(void)
 2{
 3
 4    if ((DMA1_ISR &DMA_ISR_TCIF1) != 0) {
 5        DMA1_IFCR |= DMA_IFCR_CTCIF1;
 6    }
 7
 8    tim3_enable_counter(false);
 9
10}
2.4 ADC讀取
1void adc_sample(void)
 2{
 3    uint32_t sum_val1 = 0;
 4    uint32_t sum_val2 = 0;
 5    uint32_t sum_val3 = 0;
 6    uint32_t sum_val4 = 0;
 7
 8    for(int i=0; i9        sum_val1 += adc_values[ADC_CHAN_CNT*i + 0];
10        sum_val2 += adc_values[ADC_CHAN_CNT*i + 1];
11        sum_val3 += adc_values[ADC_CHAN_CNT*i + 2];
12        sum_val4 += adc_values[ADC_CHAN_CNT*i + 3];
13    }
14
15    uint32_t filter_val1 = sum_val1/ADC_FILETER_SIZE;
16    uint32_t filter_val2 = sum_val2/ADC_FILETER_SIZE;
17    uint32_t filter_val3 = sum_val3/ADC_FILETER_SIZE;
18    uint32_t filter_val4 = sum_val4/ADC_FILETER_SIZE;
19
20    printf("adc:%d  %d  %d  %d\\r\\n", filter_val1, filter_val2, filter_val3, filter_val4);
21
22    tim3_enable_counter(true);
23}

讀取時候按照通道的順序從buff中取出,這里做了簡單的過濾;

3 燒寫測試

將程序燒寫到開發板,然后打開串口可以看到四個ADC通道的數據,在PA0/PA1/PA3/PA4四個引腳連接不同電壓可以看到變化:

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 寄存器
    +關注

    關注

    31

    文章

    5325

    瀏覽量

    120052
  • adc
    adc
    +關注

    關注

    98

    文章

    6452

    瀏覽量

    544147
  • STM32
    +關注

    關注

    2266

    文章

    10876

    瀏覽量

    354926
  • dma
    dma
    +關注

    關注

    3

    文章

    559

    瀏覽量

    100446
  • PIO
    PIO
    +關注

    關注

    0

    文章

    18

    瀏覽量

    6191
收藏 人收藏

    評論

    相關推薦

    stm32 定時器觸發ADC通道采樣+DMA提取數據相關資料下載

    stm32g0 定時器觸發ADC通道采樣+DMA提取數據stm32g0 定時器觸發
    發表于 02-15 06:46

    stm32 定時器觸發ADC通道采樣+DMA提取數據

    stm32g0 定時器觸發ADC通道采樣+DMA提取數據stm32g0 定時器觸發
    發表于 12-16 16:56 ?68次下載
    <b class='flag-5'>stm32</b> 定時器觸發<b class='flag-5'>ADC</b><b class='flag-5'>多</b><b class='flag-5'>通道</b>采樣+<b class='flag-5'>DMA</b>提取數據

    STM32G0開發筆記:FreeRTOS和FreeModbus庫使用

    使用Platformio平臺的libopencm3開發框架來開發STM32G0,以下為FreeRTOS和FreeModbus庫使用。
    的頭像 發表于 01-16 14:44 ?5460次閱讀
    <b class='flag-5'>STM32G0</b><b class='flag-5'>開發筆記</b>:FreeRTOS和FreeModbus庫使用

    STM32G0開發筆記:FreeRTOS和CLI組件使用

    使用Platformio平臺的libopencm3開發框架來開發STM32G0,以下為FreeRTOS和CLI組件使用。
    的頭像 發表于 01-16 14:47 ?3451次閱讀
    <b class='flag-5'>STM32G0</b><b class='flag-5'>開發筆記</b>:FreeRTOS和CLI組件使用

    STM32G0開發筆記:使用FreeRTOS系統的隊列Queue

    使用Platformio平臺的libopencm3開發框架來開發STM32G0,下面為使用FreeRTOS系統的隊列Queue。
    的頭像 發表于 01-16 14:50 ?1333次閱讀

    STM32G0開發筆記:使用FreeRTOS系統

    使用Platformio平臺的libopencm3開發框架來開發STM32G0,下面為使用FreeRTOS系統。
    的頭像 發表于 01-16 15:07 ?2343次閱讀
    <b class='flag-5'>STM32G0</b><b class='flag-5'>開發筆記</b>:使用FreeRTOS系統

    STM32G0開發筆記:使用ADC進行NTC溫度采集

    使用Platformio平臺的libopencm3開發框架來開發STM32G0,以下使用ADC進行NTC溫度采集。
    的頭像 發表于 01-16 15:12 ?9214次閱讀
    <b class='flag-5'>STM32G0</b><b class='flag-5'>開發筆記</b>:使用<b class='flag-5'>ADC</b>進行NTC溫度采集

    STM32G0開發筆記:用PWM來實現LED呼吸燈效果

    使用Platformio平臺的libopencm3開發框架來開發STM32G0,下面使用PWM來實現LED呼吸燈效果。
    的頭像 發表于 01-16 15:15 ?2219次閱讀
    <b class='flag-5'>STM32G0</b><b class='flag-5'>開發筆記</b>:用PWM來實現LED呼吸燈效果

    STM32G0開發筆記:EEPROM M24C02的使用方法

    使用Platformio平臺的libopencm3開發框架來開發STM32G0,以下為EEPROM M24C02的使用方法。
    的頭像 發表于 01-16 15:19 ?2762次閱讀
    <b class='flag-5'>STM32G0</b><b class='flag-5'>開發筆記</b>:EEPROM M24C02的使用方法

    STM32G0開發筆記:SD卡模塊的使用方法

    使用Platformio平臺的libopencm3開發框架來開發STM32G0,下面介紹SD卡模塊的使用方法。
    的頭像 發表于 01-19 16:27 ?2254次閱讀
    <b class='flag-5'>STM32G0</b><b class='flag-5'>開發筆記</b>:SD卡模塊的使用方法

    STM32G0開發筆記:SPI接口的基本使用

    使用Platformio平臺的libopencm3開發框架來開發STM32G0,下面介紹SPI接口的基本使用。
    的頭像 發表于 01-17 10:38 ?3040次閱讀
    <b class='flag-5'>STM32G0</b><b class='flag-5'>開發筆記</b>:SPI接口的基本使用

    STM32G0開發筆記:串口中斷的使用

    使用Platformio平臺的libopencm3開發框架來開發STM32G0,以下為串口中斷的使用。
    的頭像 發表于 01-17 10:46 ?2295次閱讀

    STM32G0開發筆記:GPIO接按鍵的使用方式

    使用Platformio平臺的libopencm3開發框架來開發STM32G0,下面為GPIO接按鍵的使用方式。
    的頭像 發表于 01-17 10:48 ?1741次閱讀

    STM32G0開發筆記:LED燈示例

    使用Platformio平臺的libopencm3開發框架來開發STM32G0,下面為LED燈示例。
    的頭像 發表于 01-17 10:52 ?1380次閱讀
    <b class='flag-5'>STM32G0</b><b class='flag-5'>開發筆記</b>:LED燈示例

    STM32G0開發筆記:使用libopencm3庫

    使用Platformio平臺的libopencm3開發框架來開發STM32G0開發環境為VSCode+PIO插件,這里以開發
    的頭像 發表于 01-17 10:56 ?1868次閱讀
    <b class='flag-5'>STM32G0</b><b class='flag-5'>開發筆記</b>:使用libopencm3庫