OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2955|回复: 0

基于AT32F403的ADC学习(STM32F103类似)

[复制链接]

3

主题

3

帖子

0

精华

新手上路

积分
36
金钱
36
注册时间
2017-2-15
在线时间
5 小时
发表于 2020-12-9 18:50:46 | 显示全部楼层 |阅读模式
使用ADC的基础配置步骤包括:开启时钟,配置ADC相关的GPIO口,配置和使能ADC对应的DMA通道,配置和使能ADCADC校准,开始触发。
1)使能ADC对应时钟,对应DMA的时钟,对应GPIO时钟:
  RCC_AHBPeriphClockCmd(RCC_AHBPERIPH_DMA1, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_ADC1, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOA, ENABLE);
2)配置对应GPIO为模拟输入模式:
   GPIO_InitStructure.GPIO_Pins = GPIO_Pins_0 | GPIO_Pins_1| GPIO_Pins_2 |GPIO_Pins_3 ;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_ANALOG;
   GPIO_Init(GPIOA, &GPIO_InitStructure);
3)配置ADC对应的DMA:需要先在DMA章节查找ADC对应的DMA通道(示例里就是DMA1_Channel1)。需要使用DMA是因为规则组的多通道ADC共用一个数据寄存器,所以多通道转化时需要开启DMA,否则数据会丢失。开启对应DMA后,每转换完一个通道的数据,DMA都会自动将数据寄存器里的数据搬运到用户预先设置好的数组里,这个搬运过程不需要用户关注/操作。
   DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;//外设地址ADC1数据寄存器地址
   DMA_InitStructure.DMA_MemoryBaseAddr=(uint32_t)&ADC_RegularConvertedValueTab;//内存地址用户需要存储ADC转换数据的数组首地址
   DMA_InitStructure.DMA_Direction = DMA_DIR_PERIPHERALSRC;//DMA传输方向这里是外设到内存
   DMA_InitStructure.DMA_BufferSize = 4;//DMA传输数据量这里是4,与ADC通道数量一样
   DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE;//外设地址自增--不自增,一直都是ADC1的数据寄存器
   DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE; //内存地址自增--自增,每传输完一次数据,内存地址就加一。例如:DMA第一次搬运的数据放在ADC_RegularConvertedValueTab[0],下一次搬运的数据就放在ADC_RegularConvertedValueTab[1]了,依次增加。直到达到DMA设置的BufferSize,这里时4
   DMA_InitStructure.DMA_PeripheralDataWidth= DMA_PERIPHERALDATAWIDTH_HALFWORD;//外设数据格式--16bitAT32F403ADC有效数据是12bit,这里选择16bit的数据格式就可以。
   DMA_InitStructure.DMA_MemoryDataWidth = DMA_PERIPHERALDATAWIDTH_HALFWORD;//内存数据格式--16bit,注意对应的ADC_RegularConvertedValueTab数组定义的时候需要定义为16bit格式。
   DMA_InitStructure.DMA_Mode = DMA_MODE_CIRCULAR; //传输模式--循环模式,循环模式即DMA搬运完4次之后,内存地址又从ADC_RegularConvertedValueTab[0]开始。
   DMA_InitStructure.DMA_Priority = DMA_PRIORITY_HIGH; //传输优先级--
   DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE; //内存到内存--关闭
   DMA_Init(DMA1_Channel1, &DMA_InitStructure);
   DMA_ChannelEnable(DMA1_Channel1, ENABLE); //DMA通道使能
4)配置ADC
   ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC模式--独立模式
   ADC_InitStructure.ADC_ScanMode = ENABLE; //扫描模式--使能,多通道转换的时候,需要开启扫描模式,否则会一直转换第一个通道。
   ADC_InitStructure.ADC_ContinuousMode = DISABLE; //连续模式--失能
   ADC_InitStructure.ADC_ExternalTrig = ADC_ExternalTrig_None; //外部触发选择软件触发(触发方式还可以使用定时器触发/外部中断触发等方式,这里选择最基础的软件触发)
   ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据对齐--右对齐
   ADC_InitStructure.ADC_NumOfChannel = 4; //转换通道数--4
   ADC_Init(ADC1, &ADC_InitStructure);   
5)使能ADCDMA功能:
  ADC_DMACtrl(ADC1, ENABLE);
6ADC通道配置(通道顺序,采样时间):
  ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_41_5);//ADC1的通道0(对应GPIO口为PA0),转化顺序为1,采样时间为41.5ADCCLK
  ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_41_5);//ADC1的通道1(对应GPIO口为PA1),转化顺序为2,采样时间为41.5ADCCLK
  ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_41_5); //ADC1的通道2(对应GPIO口为PA2),转化顺序为3,采样时间为41.5ADCCLK
  ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_41_5); //ADC1的通道3(对应GPIO口为PA3),转化顺序为4,采样时间为41.5ADCCLK
7ADC外部触发使能、配置:
  ADC_ExternalTrigConvCtrl(ADC1, ENABLE);//外部触发使能注意,软触发也算外部触发,也需要使能外部触发。
8ADC使能/唤醒:
  ADC_Ctrl(ADC1, ENABLE);
9ADC校准:
  ADC_RstCalibration(ADC1);
  while(ADC_GetResetCalibrationStatus(ADC1));
  ADC_StartCalibration(ADC1);
  while(ADC_GetCalibrationStatus(ADC1));
  delay_ms(10);
10ADC软触发--开始转换:
ADC_SoftwareStartConvCtrl(ADC1, ENABLE);

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-23 15:43

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表