第二十章 AT32F403A基于V2库 多通道adc+dma

目录

概述

硬件

软件

初始化

初始化代码

测试

最后


概述

         本文主要是使用AT32F403A开发板,基于V2库实现adc采集多通道电压值并使用dma搬运数据的功能。

         串口工具使用的Atlink-ez自带的串口功能。

         工程建立、调试工具配置在前面章节有详细介绍。


硬件

         硬件方面使用的是参考官方AT32F437 SURF板子而设计的一个AT32F403A开发板,板子上的芯片是AT32F403AVGT7的型号,开发板上面还板载了一个atlink-ez的仿真器,atlink-ez除了可以在线仿真和下载之外还有一个串口的功能,硬件上是通过跳线帽接到了MCU的串口1,pa9/10上面。

         如下图是开发板pcb图,以及硬件资源。(左边上角的就是atlink-ez,用usb线接到pc即可):


        如下是实物图:

        本章是adc采集多通道,并且使用dma来搬运采集到的数据,PC0是采集可变电阻的电压,PC1和PC2可直接通过排针接到vcc或者gnd即可。


软件

初始化

        关于adc的介绍可以去看上一章的内容,dma的可以去看串口dma的篇章。

        本文使用ADC1的通道10、11、12来转换电压,也就是PC0、PC1、PC2,IO都设置为模拟输入模式,无上下拉。

         开启ADC1的时钟,设置ADC分频系数为6,设置工作模式为独立模式, 开启序列模式,开启重复模式,设置普通通道数量为3,设置软件触发方式,使能adc dma功能,使能dma1 通道1。

         Dma方面支持ADC1使用dma来搬运数据,并且默认通道是DMA1的通道1,设置DMA1的通道1运输方向为外设到内存,外设地址为adc1的数据寄存器地址 ,内存地址递增,开启循环模式。这样adc就可以一直在循环的转换然后dma搬运数据。

初始化代码

/*
*adc dma 初始化
*ADC1-CH10 (PC0)
*ADC1-CH11 (PC1)
*ADC1-CH12 (PC2)
*软件触发
*3普通通道转换
*dma循环搬运
*/

void adc_dma_init(void)
{
	gpio_init_type gpio_initstructure;
	dma_init_type dma_init_struct;
	adc_base_config_type adc_base_struct;

	crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);		//开启gpioc时钟
	crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, TRUE);		//开启ADC1时钟
	crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE);		//开启dma1时钟
	crm_adc_clock_div_set(CRM_ADC_DIV_6);						//adc时钟六分频。

	gpio_default_para_init(&gpio_initstructure);
	gpio_initstructure.gpio_mode = GPIO_MODE_ANALOG;			//模拟输入模式
	gpio_initstructure.gpio_pins = GPIO_PINS_0|GPIO_PINS_1|GPIO_PINS_2 ;				//PA0、PA1、PA2
	gpio_init(GPIOC, &gpio_initstructure);
	
	dma_reset(DMA1_CHANNEL1);
	dma_default_para_init(&dma_init_struct);  
    dma_init_struct.buffer_size = 30;                               			//内存大小为30
    dma_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY;                   //传输方向为外设到内存
    dma_init_struct.memory_base_addr = (uint32_t)adc1_ordinary_valuetab;        //内存地址
    dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_HALFWORD;         //内存数据的宽度,16位
    dma_init_struct.memory_inc_enable = TRUE;                                   //内存地址递增打开
    dma_init_struct.peripheral_base_addr = (uint32_t)&(ADC1->odt);              //外设地址为adc数据寄存器地址
    dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_HALFWORD; //外设数据的宽度,16位
    dma_init_struct.peripheral_inc_enable = FALSE;                              //外设地址递增关闭
    dma_init_struct.priority = DMA_PRIORITY_MEDIUM;                             //中等优先级
    dma_init_struct.loop_mode_enable = TRUE;									//循环传输,传输完30个后重新开始
	dma_init(DMA1_CHANNEL1, &dma_init_struct);
	

	adc_base_default_para_init(&adc_base_struct);
	adc_base_struct.sequence_mode = TRUE;						//开启序列模式(多通道)
	adc_base_struct.repeat_mode = TRUE;							//开启重复模式
	adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT;			//数据右对齐
	adc_base_struct.ordinary_channel_length = 3;				//通道数为3
	adc_base_config(ADC1, &adc_base_struct);					//初始化参数

	adc_ordinary_channel_set(ADC1, ADC_CHANNEL_10, 1, ADC_SAMPLETIME_239_5);	//设置普通通道,adc1 ,通道10,序号为1,采样周期为239.5
	adc_ordinary_channel_set(ADC1, ADC_CHANNEL_11, 2, ADC_SAMPLETIME_239_5);	//设置普通通道,adc1 ,通道11,序号为2,采样周期为239.5
	adc_ordinary_channel_set(ADC1, ADC_CHANNEL_12, 3, ADC_SAMPLETIME_239_5);	//设置普通通道,adc1 ,通道12,序号为3,采样周期为239.5

	adc_ordinary_conversion_trigger_set(ADC1, ADC12_ORDINARY_TRIG_SOFTWARE, TRUE);		//普通通道触发设置为软件触发

	adc_dma_mode_enable(ADC1, TRUE);			//使能adc dma功能
	dma_channel_enable(DMA1_CHANNEL1, TRUE);  //使能通道1
	
	adc_enable(ADC1, TRUE);				//使能ADC1
	
	adc_calibration_init(ADC1);			//初始化校准
	while(adc_calibration_init_status_get(ADC1));	//初始化校准完毕
	adc_calibration_start(ADC1);				//开始校准
	while(adc_calibration_status_get(ADC1));	//校准完毕
	
	adc_ordinary_software_trigger_enable(ADC1, TRUE); //软件触发adc
  
}

   


测试

         测试代码

         通过每3秒输出每个通道所转换的10次的数据值,硬件上通过手动来短接PC1/2到gnd或者vcc以及调节可变电阻的阻值。

测试结果

         PC1短接gnd,PC2短接vcc,PC0调节可变电阻。测试正确的。


最后

         有问题的可以加QQ群技术交流,同时相关代码上传到QQ群中。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值