STM32F4-ADC/DAC

ADC

ADC:指模/数转换器或者模拟/数字转换器:是指将连续变量的模拟信号转换为离散的数字信号的器件。典型的模拟/数字转换器将模拟信号转换为表示一定比例电压值的数字信号。

逐次比较型ADC:

基本原理是从高位到低位逐位试探比较,好像用天平称物体,从重到轻逐级增减砝码进行试探。逐次逼近法转换过程是:初始化时将逐次逼近寄存器各位清零;转换开始时,先将逐次逼近寄存器最高位置1,送入D/A转换器,经D/A转换后生成的模拟量送入比较器,称为 Vo,与送入比较器的待转换的模拟量Vi进行比较,若Vo<Vi,该位1被保留,否则被清除。然后再置逐次逼近寄存器次高位为1,将寄存器中新的数字量送D/A转换器,输出的 Vo再与Vi比较,若Vo<Vi,该位1被保留,否则被清除。重复此过程,直至逼近寄存器最低位。转换结束后,将逐次逼近寄存器中的数字量送入缓冲寄存器,得到数字量的输出。

8位逐次逼近型ADC转换芯片内部结构图:(逐次逼近判断8次,从高位开始一位一位判断),12位的逐次逼近判断12次。

STM32F4x  ADC的主要特点:

  • 可配置12位,10位,8位或6位分辨率;
  • 最多带3个ADC控制器,可以单独使用,也可以使用双重/三重模式提高采样率;双重/三重模式(具有 2 个或更多 ADC 的器件提供);双重/三重 ADC 模式下可配置的 DMA 数据存储;双重/三重交替模式下可配置的转换间延迟;
  • 最多支持19个通道,可最多测量16个外部和2个内部信号源和Vbat通道信号;
  • 支持单次和连续转换模式;
  • 转换结束,注入转换结束,和发生模拟看门狗或者溢出事件时产生中断;
  • 通道0到通道n的自动扫描模式;
  • 自动校准;
  • 采样间隔可以按通道编程,独立设置各通道的采样时间;
  • 规则通道和注入通道均有外部触发选项,可为规则转换和注入转换配置极性;规则通道转换期间可以产生DMA请求。
  • 数据对齐保持内置数据一致性:转换结果支持左对齐或右对齐方式存储在16位数据寄存器;
  • ADC转换时间:最大转换速率 0.42us(在ADCCLK=36M,采样周期为3个周期下得到);
  • ADC供电要求:全速运行时为2.4V-3.6V;慢速运行时为1.8V。
  • ADC输入范围:VREF- ≤  VIN  ≤  VREF+。

STM32F40x的ADC外部通道和芯片引脚的对应关系

 ADC引脚:

ADC框图:

外部的16个通道在转换时分为:规则通道和注入通道。

其中规则通道最多有16路,注入通道最多有4路。
规则通道:
规则通道相当于正常运行的程序,是最平常、最常用的通道,平时的ADC转换都是用规则通道实现的。规则通道和它的转换顺序在ADC_SQRx寄存器中选择,规则组转换的总数应写入ADC_SQR1寄存器的L[3:0]中。
注入通道:
注入通道是相对于规则通道而言,注入通道可以在规则通道转换时,强行插队转换,相当于中断。当有注入通道需要转换时,规则通道的转换会停止,优先执行注入通道的转换,当注入通道的转换执行完毕后,再回到之前规则通道进行转换。可以理解为注入通道优先级比规则通道高。注入通道和它的转换顺序在ADC_JSQR寄存器中选择。注入通道里转化的总数应写入ADC_JSQR寄存器的L[1:0]中。

STM32F4的ADC的各通道可以单次,连续,扫描或间断(非扫描)模式执行。

ADC是一个独立的外设,转换一旦开始就一直在运行,直到转换完毕。 若在中途有中断信号触发,也只是CPU去处理,此时ADC还是正常转换,转换完毕会把数据存储在DR 寄存器中,等待CPU去处理。

单次转换模式:

单次转换模式下,ADC 执行一次转换。CONT 位为 0 时,可通过以下方式启动此模式:

  • 将 ADC_CR2 寄存器中的 SWSTART 位置 1(仅适用于规则通道)
  • 将 JSWSTART 位置 1 (适用于注入通道)
  • 外部触发(适用于规则通道或注入通道)

完成所选通道的转换之后:
如果转换了规则通道:

  • 转换数据存储在 16 位 ADC_DR 寄存器中
  • EOC (转换结束) 标志置 1
  • EOCIE 位置 1 时将产生中断

如果转换了注入通道:

  • 转换数据存储在 16 位 ADC_JDR1 存器中
  • JEOC(注入转换结束) 标志置 1
  • JEOCIE 位置 1 时将产生中断

然后,ADC 停止。

连续转换模式:

在连续转换模式下,ADC 结束一个转换后立即启动一个新的转换。CONT 位为 1 时,可通过外部触发或将 ADC_CR2 寄存器中的 SWSTRT 位置 1 来启动此模式(仅适用于规则通道)。

每次转换之后:

如果转换了规则通道组:

  • 上次转换的数据存储在 16 位 ADC_DR 存器中
  • EOC (转换结束) 标志置 1
  • EOCIE 位置 1 时将产生中断

无法连续转换注入通道。连续模式下唯一的例外情况是,注入通道配置为在规则通道之后自动转换 (使用JAUTO 位)。

扫描模式:

此模式用于扫描一组模拟通道。
通过将 ADC_CR1寄存器中的SCAN位置1来选择扫描模式。将此位置1后,ADC会扫描在ADC_SQRx 寄存器 (对于规则通道)或 ADC_JSQR 寄存器 (对于注入通道) 中选择的所有通道。为组中的每个通道都执行一次转换。每次转换结束后,会自动转换该组中的下一个通道。若将CONT 位置 1,规则通道转换不会在组中最后一个所选通道处停止,而是再次从第一个所选通道继续转换。
如果将 DMA 位置 1,则在每次规则通道转换之后,均使用直接存储器访问(DMA) 控制器将转换自规则通道组的数据 (存储在 ADCDR 寄存器中) 传输到 SRAM。

在以下情况下,ADC_SR 寄存器中的 EOC 位置 1:(EOC位置1类似于转换完成标志位)

  • 如果 EOCS 位清0,在每个规则组序列转换结束时,也就是所有规则组通道转换结束时;
  • 如果 EOCS 位置 1,在每个规则通道转换结束时从注入通道转换的数据始终存储在 ADC_JDRx 寄存器中。

从注入通道转换的数据始终存储在 ADC_JDRx 寄存器中。

ADC四种执行模式:

单次转换非扫描模式:转换完选定的一个通道,停止,等待下一次开启转换。

连续转换非扫描模式:转换玩选定的一个通道后继续返回转换。

单次转换扫描模式:单次扫描转换一次序列的通道,转换完停止,等待下次开启转换。

连续转换扫描模式:连续扫描转换序列的通道,转换完一次序列后返回继续进行循环转换。

ADC_CR1控制寄存器的位8来设置扫描模式的使能和失能。

ADC中断:

当模拟看门狗状态位和溢出状态位分别置 1 时,规则组和注入组在转换结束时可能会产生中断。可以使用单独的中断使能位以实现灵活性。
ADC_SR 寄存器中存在另外两个标志,但这两个标志不存在中断相关性

  • JSTRT (开始转换注入组的通道)
  • STRT (开始转换规则组的通道)

ADC相关寄存器介绍:

ADC时钟配置:(ADC通用控制寄存器:ADC_CCR)

ADC_CR1寄存器:

ADC_CR2寄存器:

ADC转换的触发:ADC需要一个触发信号来实行模/数转换。

  • 通过直接配置寄存器触发,通过配置控制寄存器CR2的ADON位,写1时开始转换,写0时停止转换。在程序运行过程中只要将CR2寄存器的ADON位置1就可以进行转换。
  • 还可通过内部定时器或者外部IO触发转换,也就是说可以利用内部时钟让ADC进行周期性的转换,也可以利用外部IO使ADC在需要时转换,具体的触发由控制寄存器CR2决定。

 数据对齐:

 ADC_SMPR1寄存器/ ADC_SMPR2寄存器:

ADC的采样时间:采样时间由输入时钟和采样周期来决定。

配置采样周期可以确定使用多少个ADC时钟周期来对电压进行采样,采样的周期数可通过 ADC采样时间寄存器 ADC_SMPR1 和 ADC_SMPR2 中的 SMPx[2:0]位设置。ADC_SMPR2 控制的是通道 0~9, ADC_SMPR1 控制的是通道 10~17。

 ADC_SQR1/SQR2/SQR3规则序列寄存器:规则通道中的转换顺序由这三个寄存器控制:它们都是32位寄存器。SQR寄存器控制着转换通道的数目和转换顺序。

 ADC_JSQR注入序列寄存器:

 ADC_DR:规则通道数据寄存器;

当使用多个通道转换数据时,会产生多个转换数据,然而数据寄存器只有一个,多个数据存放在一个寄存器中会覆盖数据导致ADC转换错误,所以我们经常在一个通道转换完成之后就立刻将数据取出来,方便下一个数据存放。一般开启DMA模式将转换的数据,传输在一个数组中,程序对数组读操作就可以得到转换的结果。

 ADC_JDR:注入通道数据寄存器。

ADC_SR状态寄存器:中断的配置都由ADC_SR寄存器决定

 ADC常用库函数:

void ADC_DeInit(void);
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);//每一个ADC控制器的初始化
void ADC_CommonInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct);//ADC通用初始化函数
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState);
void ADC_SoftwareStartInjectedConv(ADC_TypeDef* ADCx);//ADC使能软件转换函数
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);//ADC规则通道配置
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);//ADC获取转换结果函数

ADC_CommonInit函数结构体参数:(这个结构体用来配置ADC_CCR寄存器相关参数)

typedef struct 
{
  uint32_t ADC_Mode;               //多重ADC模式选择                 
  uint32_t ADC_Prescaler;          //ADC预分频     
  uint32_t ADC_DMAAccessMode;      //DMA访问模式      
  uint32_t ADC_TwoSamplingDelay;   //2个采样阶段之间的延迟      
}ADC_CommonInitTypeDef;

ADC_Init函数结构体参数:

typedef struct
{
  uint32_t ADC_Resolution;                   /ADC分辨率
  FunctionalState ADC_ScanConvMode;          //是否使用扫描模式        
  FunctionalState ADC_ContinuousConvMode;    //单次或者连续转换    
  uint32_t ADC_ExternalTrigConvEdge;         //外部触发使能方式   
  uint32_t ADC_ExternalTrigConv;             //触发方式           
  uint32_t ADC_DataAlign;                    //数据对齐方式     
  uint8_t  ADC_NbrOfConversion;              //规则通道序列长度         
}ADC_InitTypeDef;

ADC实验配置过程:

  • 开启PA口时钟和ADC1时钟,设置PA1为模拟输入:

        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);

        GPiO Init();

  • 复位ADC1,同时设置ADC1分频因子

        ADC_Delnit(ADC1);

  • 初始化ADC_CCR寄存器

        ADC_CommonInit();

  • 初始化ADC1参数,设置ADC1的工作模式以及规则序列的相关信息。

        voidADC_Init(ADC TypeDef*ADCX, ADC_IntTypeDef* ADC_InitStruct):

  • 使能ADC。

        ADC_Cmd(ADC1,ENABLE);

  • 配置规则通道参数:

        ADC_RegularChannelConfig();

  • 开启软件转换:

        ADC_SoftwareStartConvcmd(ADC1);

  • 等待转换完成,读取ADC值。

        ADC_GetConversionValuelADC1);

DAC

STM32F4 的 DAC 模块(数字/模拟转换模块)是 12 位数字输入,电压输出型的DAC。DAC
可以配置为 8 位或 12 位模式,也可以与 DMA 控制器配合使用。DAC 工作在 12 位模式时,
数据可以设置成左对齐或右对齐。 DAC 模块有 2 个输出通道,每个通道都有单独的转换器。
在双 DAC 模式下,2 个通道可以独立地进行转换,也可以同时进行转换并同步地更新 2 个
通道的输出。DAC可以通过引脚输入参考电压Vref+(通 ADC 共用) 以获得更精确的转换
结果。

STM32F4 的 DAC 模块主要特点有:

  • 2 个 DAC 转换器:每个转换器对应 1 个输出通道
  • 8 位或者 12 位单调输出
  • 12 位模式下数据左对齐或者右对齐
  • 同步更新功能
  • 噪声波形生成
  • 三角波形生成
  • 双 DAC 通道同时或者分别转换
  • 每个通道都有 DMA 功能

DAC框图:

 DAC引脚:

使能 DAC 通道x后,相应GPIO引脚(PA4 或PA5) 将自动连接到模转换器输出(DAC_OUTx)。为了避免寄生电流消耗,应首先将 PA4 或 PA5 引脚配置为模拟模式(AIN)。

DAC_OUT1-->PA4;DAC_OUT2-->PA5

DAC转换:

DAC_DORx寄存器无法直接写入,任何数据都必须通过加载 DAC_DHRx 寄存器(写入DAC_DHR8Rx、DAC_DHR12LX、DAC_DHR12RX、DAC_DHR8RD、DAC_DHR12LD 或DAC_ DHR12LD)才能传输到 DAC 通道。
如果未选择硬件触发(DAC_CR 寄存器中的 TENx 位复位),那么经过一个 APB1 时钟周期后,DAC_DHRx 寄存器中存储的数据将自动转移到 DAC_DORx 寄存器。但是,如果选择硬件触发(置位 DAC_CR 寄存器中的 TENX 位) 且触发条件到来,将在三个 APB1 时钟周期后进行转移。
当 DAC_DORx 加载了 DAC_DHRx 内容时,模输出电压将在一段时间t_{SETTLING} 后可用,具体时间取决于电源电压和模拟输出负载。

关闭硬件触发时的时序转换图:

 DAC的数据格式:

STM32F4 的 DAC 支持 8/12 位模式, 8 位模式的时候是固定的右对齐的,而 12 位模式又可以设置左对齐/右对齐。单 DAC 通道 x,总共有 3 种情况:

  • 8位数据右对齐:用户将数据写入DAC_DHR8Rx[7:0]位(实际存入DHRx[11:4]位)。
  • 12 位数据左对齐:用户将数据写入 DAC_DHR12Lx[15:4]位(实际存入 DHRx[11:0]位)
  • 12 位数据右对齐:用户将数据写入 DAC_DHR12Rx[11:0]位(实际存入 DHRx[11:0]位)。

DAC的触发选择:

DAC_CR寄存器中的TENx控制位置1,可通过外部事件(定时计数器,外部中断线)触发转换。TSEL[2:0]控制位决定通过8个可能事件中的哪一个来触发转换。

外部触发器:

每当 DAC 接口在所选定时器 TRGO 输出或所选外部中断线 9 上检测到上升沿时,DAC_DHRx寄存器中存储的最后一个数据即会转移到 DAC_DORx 寄存器中。发生触发后,再经过三个APB1 周期,DAC_DORx 寄存器将会得到更新。
如果选择软件触发,一旦 SWTRIG 位置 1,转换即会开始。DAC_DHRx 寄存器内容加载到DAC_ DORx 寄存器中后,SWTRIG 即由硬件复位。

DAC输出电压:

经过线性转换后,数字输入会转换为0到V_{REF+}之间的输出电压。各DAC通道引脚的模拟输出电压通过以下公式确定:

DACx输出电压 = V_{REF} x \frac{DOR}{4095}

DAC通道使能:

将 DAC_CR 寄存器中的相应 ENx 位置 1,即可接通对应 DAC 通道。经过一段启动时间t_{WAKEUP}后,DAC 通道被真正使能。
ENx 位只会使能模 DAC Channelx 宏单元。即使ENx 位复位,DAC Channelx 数字接口仍处于使能状态。

DAC输出缓冲器使能:

DAC 集成了两个输出缓冲器,可用来降低输出阻抗并在不增加外部运算放大器的情况下直接驱动外部负载。通过 DAC_CR 寄存器中的相应 BOFFX 位,可使能或禁止各 DAC 通道输出缓冲器。

DAC相关寄存器:

DAC通道1的12位右对齐数据保持寄存器DAC_DHR12R1。

 STM32F407开发板DAC硬件连接:PA4,PA5脚

DAC配置步骤:

  • 开启 PA 口时钟,设置 PA4 为模拟输入。

STM32F407ZGT6 的 DAC 通道 1 是接在 PA4上的,所以,我们先要使能GPIOA 的时钟,然后设置 PA4为模拟输入。虽然 DAC引脚设置为输入,但是 STM32F4 内部会连接在 DAC模拟输出上。

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能 GPIOA 时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//下拉
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化
  • 使能 DAC1 时钟。

同其他外设一样,要想使用,必须先开启相应的时钟。 STM32F4 的 DAC 模块时钟是由APB1 提供的,所以我们先要在通过调用函数 RCC_APB1PeriphClockCmd 来使能 DAC1 时钟。

  • 初始化 DAC,设置 DAC 的工作模式。

该部分设置全部通过 DAC_CR 设置实现,包括:DAC 通道 1 使能、DAC 通道 1 输出缓存关闭、不使用触发、不使用波形发生器等设置。 这里 DAC 初始化是通过函数 DAC_Init完成的:

void DAC_Init(uint32_t DAC_Channel, DAC_InitTypeDef* DAC_InitStruct);
typedef struct
{
uint32_t DAC_Trigger;//用来设置是否使用触发功能
uint32_t DAC_WaveGeneration;//用来设置是否使用触发功能
uint32_t DAC_LFSRUnmask_TriangleAmplitude;//用来设置屏蔽/幅值选择器
uint32_t DAC_OutputBuffer;//用来设置输出缓存控制位
}DAC_InitTypeDef;
  • 使能DAC转换通道

初始化 DAC 之后,理所当然要使能 DAC 转换通道:DAC_Cmd(DAC_Channel_1, ENABLE);

  • 设置DAC的输出值

我们使用 12 位右对齐数据格式,所以我们通过设置 DHR12R1,就可以在 DAC 输出引脚(PA4)得到不同的电压值了。
DAC_SetChannel1Data(DAC_Align_12b_R, 0); //12 位右对齐数据格式设置 DAC 值
第一个参数设置对齐方式,可以为:12 位右对齐 DAC_Align_12b_R, 12 位左对齐
DAC_Align_12b_L 以及 8 位右对齐 DAC_Align_8b_R 方式。
第二个参数就是DAC 的输入值了,这个很好理解,初始化设置为 0。

  • 还可以读出 DAC 对应通道最后一次转换的数值

DAC_GetDataOutputValue(DAC_Channel_1);

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值