stm32的ADC功能比较强大,可以实现多达18通道的ADC转换,而且还可以连续转换。这里采用的板子是STM32F103ZET6,由于初学,只使用了一路ADC通道。这里采用的是ADC1的通道1,没有重映射,引脚是PA1。普中的教程里面关于DMA篇的例程是串口发送。自己想加深对DMA的学习,于是就研究了一下ADC转换的DMA读取法。下面开始正文。
DMA简介
关于DMA的介绍我就不多说,手册上很清楚,我这里放一张图便于阅读。我重点讲一下,配置流程和配置过程中出现过的错误。
配置流程并不复杂,但是要注意,DMA的单次传输和循环传输是不同的。单次模式下,启动DMA传输之前都需要线关闭DMA使能,然后配置传输的数据量,然后再使能DMA,否则只能传输一次。在读取的时候也需要检查传输完成标志位TCx,并且需要手动清除。然后再读数据。如果配置的是连续传输,那么流程就简单了,直接开启,接收来自外设地址的请求,外设地址来多少数据,他就传输多少。不用先失能,再使能,也不用判断TCx标志位。但是一定要注意配置好DMA初始化结构体,我在配置存储器地址增量的时候就没有使其使能,这点是我得到了错误的数据。
ADC简介
ADC我也不过多赘述,简述一下常用的ADC,以ADC1为例,18通道,这里只用了一个通道,通道1,常规配置就讲了,大家也不会改动,比如分频系数,采样周期,模式什么的,我重点讲一下单通道单次转换和连续转换的区别。单次转换的时候,每次使用都需要软件开启,一般地还需要在转换开始的时候指定转换周期,通道数等参数。连续通道则不用关注。软件开启,使能ADC的DMA功能后,就不用管了,只需要,DMA读取就行了。
配置说明
ADC1的通道1,DMA1的通道1。ADC采用连续转换模式,DMA采用单次转换。用按键启动。
程序
ADC配置
#include "adc.h"
void ADC1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE);
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //adc的时钟配置为12M
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //单次扫描,既不用等待所有通道都扫描完成才产生EOC
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //连续转换
ADC_InitStructure.ADC_ExternalTrigConv =ADC_ExternalTrigConv_None; //软件触发
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // 右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; //通道数1个
ADC_Init(ADC1, &ADC_InitStructure);
ADC_Cmd</