使用platformio平台的libopencm3开发框架来开发stm32g0,以下为多通道adc与dma的使用。
1 新建项目建立adc_dma项目在pio的home页面新建项目,项目名称adc_dma,选择开发板为 monkeypi_stm32_g070rb,开发框架选择libopencm3;
项目建立完成后在src目录下新建main.c主程序文件;修改下载和调试方式,这里开发板使用的是daplink仿真器,因此修改platformio.ini文件如下:1upload_protocol = cmsis-dap2debug_tool = cmsis-dap2 编写程序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);1011 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);1617 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);2627 /* 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);1415 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 42#define adc_fileter_size 3234int16_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);1112 /* timer global mode:13 * - no divider14 * - alignment edge15 * - direction up16 * (these are actually default values after reset above, so this call17 * 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);2122 /*23 * please take note that the clock source for stm32 timers24 * might not be the raw apb1/apb2 clocks. in various conditions they25 * are doubled. see the reference manual for full details!26 * in our case, tim3 on apb1 is running at double frequency, so this27 * sets the prescaler to have the timer run at 5khz28 */29 timer_set_prescaler(tim3, 64-1);3031 /* disable preload. */32 timer_disable_preload(tim3);33 timer_continuous_mode(tim3);3435 timer_set_period(tim3, 20000-1); //100hz3637 timer_set_master_mode(tim3, tim_cr2_mms_update);3839 timer_enable_irq(tim3, tim_dier_uie);40}4142void tim3_enable_counter(bool en)43{44 if(en){45 timer_enable_counter(tim3);46 }else{47 timer_disable_counter(tim3);48 }49}5051void tim3_isr(void)52{53 if (timer_get_flag(tim3, tim_sr_uif)) {5455 /* 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);1011 adc_enable_dma(adc1);1213 adc_cfgr1(adc1) = (adc_cfgr1(adc1) & ~(0x3<<10)) | (0x1<<10); // hardware trigger detection on the rising edge14 adc_cfgr1(adc1) = (adc_cfgr1(adc1) & ~adc_cfgr1_extsel) | (3<
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); 910}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; i3 烧写测试将程序烧写到开发板,然后打开串口可以看到四个adc通道的数据,在pa0/pa1/pa3/pa4四个引脚连接不同电压可以看到变化:
Counterpoint预测功能机市场将在未来五年持续增长
点钞机lcd段码液晶屏显示驱动芯片的功能特点
华强北的“全球智能硬件天堂”是怎样炼成的?
关于设计定制电缆组件时的专业知识介绍
智联安高精定位低速RedCap芯片MK8520荣获本次IOTE 2023创新产品金奖
STM32G0开发笔记:多通道ADC与DMA的使用
WiSA E开发套件开始向全球发货,旨在统一非Sonos音频市场
液体特性对微孔压电超声雾化效果影响
中国光伏企业的未来,筹码是国外新兴市场?
2K+骁龙835+8G+全面屏,一加5即将发布碾压小米6
宁德时代和本田合约细节分析 双方共同为本田未来电动车型研发电池
井通科技应邀参加“2017-2018中国区块链风云榜盛典” 一举斩获4项年度
抗击洪涝灾害,河道水雨情动态在线监测解决方案
变频器的应用及组成
译码器、多路选择器介绍
MGT-PR小鼠步态行为分析系统说明
便携式边界扫描故障诊断仪的软硬件设计与实现
瑞为智慧导航导乘方案为旅客提供丰富的查询服务
采购拉力试验机,需要注意什么?类型、品质、价格
车联网再次提速,哪些领域将面临机会和挑战