0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

CKS32F4xx系列ADC单通道电压采集的实现

中科芯MCU 来源:中科芯MCU 2023-07-21 09:32 次阅读

CKS32F4xx

ADC单通道电压采集

ADC可以将现实世界中连续变化的模拟量,如温度、压力、流量、速度、光强等,转换成离散的数字量,输入到计算机中进行处理。按照原理不同,ADC可以分为积分型、逐次逼近型(SAR)、并行比较型、Σ-∆调制型、电容阵列逐次比较型及压频变换型。逐次逼近型(SAR)ADC由比较器和DA转换器构成,它从最高有效MSB位开始通过逐次比较,按顺序以位位单位对输入电压与内置DA转换器输出电压进行比较,经过多次比较输出相应的数字值。逐次逼近型(SAR)ADC的电路规模属于中等,它的优点是速度较快、功耗低、成本适中。

ADC简介

CKS32F4xx系列产品内嵌3个12位SAR型ADC,每个ADC多达19个复用通道,可测量来自16个外部、2个内部和VBAT通道的信号,具有独立模式、双重模式和三种模式,并支持单次、连续、扫描或间断采样模式下进行A/D转换,对于不同AD转换要求几乎都有合适的模式可选,转换的结果可以按照左对齐或右对齐的方式存储在16位数据寄存器中。下图是CKS32F4xx系列产品ADC的结构框图,每个模块的具体描述和技术参数可以参阅《CKS32F4xx参考手册》。

71a10af0-26f9-11ee-962d-dac502259ad0.png

ADC主要特性

分辨率支持12位,10位,8位,6位,可软件配置

支持转换结束产生中断、包括规则通道和注入通道

支持单次、连续、间隔转换模式

可独立设置各通道采样时间

规则通道转换和注入通道转换均有外部触发选项,支持软件或者硬件触发转换

支持模拟看门狗

支持双重或者三重模式(具有2个或以上ADC的器件)

支持双重或者三重模式下可配置的DMA数据存储

可配置双重或者三重交替采样模式下的转换延迟时间间隔

ADC供电要求:全速模式下为2.4V到3.6V,低速模式下为1.8V

ADC输入电压范围:Vref-≤Vin≤Vref+

规则通道转换期间可产生DMA请求

固件库中与ADC相关的主要API

CKS32F4xx系列固件库中与ADC相关的API定义在cks32f4xx_adc.h和cks32f4xx_adc.c两个文件中,前者为头文件,包含寄存器地址、常量定义、API函数声明,后者为API的具体实现。CKS32F4xx系列产品最多有3个ADC,编号分别为ADC1、ADC2、ADC3,大多数API的第一个参数为ADC_TypeDef*ADCx,表示操作的ADC实体编号。下表列出了常用的API函数:

API函数原型 函数功能
void ADC_DeInit(void) 复位ADC外设寄存器
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct) 根据ADC_InitStruct中参数初始化ADC
void ADC_StructInit(ADC_InitTypeDef* ADC_InitStruct) 复位结构体成员
void ADC_CommonInit(ADC_CommonInitTypeDef* ADC_CommonInitStruct) 根据结构体参数初始化ADC外设
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState) 使能或者禁止ADC外设
void ADC_TempSensorVrefintCmd(FunctionalState NewState) 使能或者禁止温度传感器通道
void ADC_VBATCmd(FunctionalState NewState) 使能或者禁止VBAT通道
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime) 设置ADC规则通道的参数和采样时间
void ADC_SoftwareStartConv(ADC_TypeDef* ADCx) 软件启动ADC转换
FlagStatus ADC_GetSoftwareStartConvStatus(ADC_TypeDef* ADCx) 得到ADC转换状态
voidADC_EOCOnEachRegularChannelCmd(ADC_TypeDef* ADCx, FunctionalState NewState) 使能或者禁止每个规则转换通道的EOC
void ADC_ContinuousModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) 使能或者禁止ADC的连续转换模式
void ADC_DiscModeChannelCountConfig(ADC_TypeDef* ADCx, uint8_t Number) 配置ADC规则组通道的间断模式
void ADC_DiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) 使能或者禁止ADC的规则组通道
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx) 得到规则通道最后一次转换的数值
void ADC_DMACmd(ADC_TypeDef* ADCx, FunctionalState NewState) 使能或者禁止ADC的DMA请求
void ADC_InjectedChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime) 设置ADC注入通道的参数和采样时间
void ADC_InjectedSequencerLengthConfig(ADC_TypeDef* ADCx, uint8_t Length) 配置注入通道序列长度
void ADC_SetInjectedOffset(ADC_TypeDef* ADCx, uint8_t ADC_InjectedChannel, uint16_t Offset) 设置注入通道转换值偏移
void ADC_ExternalTrigInjectedConvConfig(ADC_TypeDef* ADCx, uint32_t ADC_ExternalTrigInjecConv) 配置注入通道的外部触发
void ADC_SoftwareStartInjectedConv(ADC_TypeDef* ADCx) 配置注入通道转换
void ADC_InjectedDiscModeCmd(ADC_TypeDef* ADCx, FunctionalState NewState) 使能注入通道组的间断模式
void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState) 使能或者禁止ADC中断
FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG) 检测ADC特定标志是否设置
void ADC_ClearFlag(ADC_TypeDef* ADCx, uint8_t ADC_FLAG) 清除ADC标志
ITStatus ADC_GetITStatus(ADC_TypeDef* ADCx, uint16_t ADC_IT) 通过相应标志检测是否发生相应中断
void ADC_ClearITPendingBit(ADC_TypeDef* ADCx, uint16_t ADC_IT) 清除中断挂起位

实现ADC单通道电压采集

CKS32F4xx系列的ADC功能繁多,我们设计几个实验尽量完整的展示ADC的功能。本次课堂主要介绍比较基础实用的单通道电压采集,实现开发板上引脚电压的采集并通过串口打印至PC端串口调试助手。单通道电压采集适用AD转换完成中断,在中断服务函数中读取数据,不使用DMA传输,在后期多通道采集实验中再使用DMA传输。相关核心代码实现如下:

(1)ADC宏定义

// ADC GPIO 宏定义
#define TEMP_ADC_GPIO_PORT GPIOB
#define TEMP_ADC_GPIO_PIN GPIO_Pin_0
#define TEMP_ADC_GPIO_CLK RCC_AHB1Periph_GPIOB
// ADC 序号宏定义
#define TEMP_ADC ADC1
#define TEMP_ADC_CLK RCC_APB2Periph_ADC1
#define TEMP_ADC_CHANNEL ADC_Channel_8
// ADC 中断宏定义
#define Temp_ADC_IRQ ADC_IRQn
#define Temp_ADC_INT_FUNCTION ADC_IRQHandler

(2)ADC GPIO初始化

static void Temp_ADC_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(TEMP_ADC_GPIO_CLK, ENABLE);// 使能 GPIO 时钟
GPIO_InitStructure.GPIO_Pin = TEMP_ADC_GPIO_PIN;  // 配置 IO
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;    // 配置为模拟输入
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;  //不上拉不下拉
GPIO_Init(TEMP_ADC_GPIO_PORT, &GPIO_InitStructure);
}

使用到GPIO时候都必须开启对应的GPIO时钟,GPIO用于AD转换功能必须配置为模拟输入模式。

(3)配置ADC工作模式

static void Temp_ADC_Mode_Config(void)
{
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
RCC_APB2PeriphClockCmd(TEMP_ADC_CLK , ENABLE);     // 开启ADC时钟
 
// -------------------ADC Common 结构体 参数 初始化------------------------
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; // 独立ADC模式
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;// 时钟为fpclk x分频
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;// 禁止DMA直接访问模式
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles;   // 采样时间间隔 ADC_CommonInit(&ADC_CommonInitStructure);


// -------------------ADC Init 结构体 参数 初始化--------------------------
ADC_StructInit(&ADC_InitStructure);
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; // ADC 分辨率
ADC_InitStructure.ADC_ScanConvMode = DISABLE; // 禁止扫描模式,多通道采集才需要
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;  // 连续转换
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//禁止外部边沿触发
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; //外部触发通道,本例子使用软件触发,此值随便赋值即可
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据右对齐
ADC_InitStructure.ADC_NbrOfConversion = 1;         //转换通道 1个                      
ADC_Init(TEMP_ADC, &ADC_InitStructure);


// 配置 ADC 通道转换顺序为1,第一个转换,采样时间为3个时钟周期
ADC_RegularChannelConfig(TEMP_ADC, TEMP_ADC_CHANNEL, 1, ADC_SampleTime_56Cycles);
// ADC 转换结束产生中断,在中断服务程序中读取转换值
ADC_ITConfig(TEMP_ADC, ADC_IT_EOC, ENABLE);
ADC_Cmd(TEMP_ADC, ENABLE);  // 使能ADC
ADC_SoftwareStartConv(TEMP_ADC);//开始ADC转换,软件触发
}

首先,使用ADC_InitTypeDef和ADC_CommonInitTypeDef结构体分别定义一个ADC初始化和ADC通用类型变量。调用RCC_APB2PeriphClockCmd()开启ADC时钟。接下来使用ADC_CommonInitTypeDef结构体变量ADC_CommonInitStructure来配置ADC为独立模式、分频系数为2、不需要设置DMA模式、20个周期的采样延迟,并调用ADC_CommonInit函数完成ADC通用工作环境配置。我们使用ADC_InitTypeDef结构体变量ADC_InitStructure来配置ADC1为12位分辨率、单通道采集不需要扫描、启动连续转换、使用内部软件触发无需外部触发事件、使用右对齐数据格式转换通道为1,并调用ADC_Init函数完成ADC1工作环境配置。

ADC_RegularChannelConfifig函数用来绑定ADC通道转换顺序和时间。它接收4个形参,第一个形参选择ADC外设,可为ADC1、ADC2或ADC3;第二个形参通道选择,总共可选18个通道;第三个形参为转换顺序,可选为1到16;第四个形参为采样周期选择,采样周期越短,ADC转换数据输出周期就越短但数据精度也越低,采样周期越长,ADC转换数据输出周期就越长同时数据精度越高。PC3对应ADC通道ADC_Channel_13,这里我们选择ADC_SampleTime_56Cycles即56周期的采样时间。

利用ADC转换完成中断可以非常方便的保证我们读取到的数据是转换完成后的数据而不用担心该数据可能是ADC正在转换时“不稳定”数据。我们使用ADC_ITConfifig函数使能ADC转换完成中断,并在中断服务函数中读取转换结果数据。ADC_Cmd函数控制ADC转换启动和停止。

最后使用软件触发调用ADC_SoftwareStartConvCmd函数进行使能配置。

(4)在Temp_ADC_NVIC_Config函数中配置ADC转换完成中断的优先级分组和优先级。

static void Temp_ADC_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); // 配置优先级分组
NVIC_InitStructure.NVIC_IRQChannel = Temp_ADC_IRQ;  // 配置中断优先级
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}

(5)ADC中断服务程序

void ADC_IRQHandler(void)
{
if(ADC_GetITStatus(TEMP_ADC,ADC_IT_EOC)==SET)
{
ADC_ConvertedValue = ADC_GetConversionValue(TEMP_ADC);  // 读取ADC的转换值
}
ADC_ClearITPendingBit(TEMP_ADC,ADC_IT_EOC);
}

中断服务函数一般定义在cks32f4xx_it.c文件内,我们使能了ADC转换完成中断,因此在ADC转换完成后就会进入中断服务函数,在中断服务函数内直接读取ADC转换结果保存在变量ADC_ConvertedValue(在main.c中定义)中。ADC_GetConversionValue函数是获取ADC转换结果值的库函数,只有一个形参为ADC外设,可选为ADC1、ADC2或ADC3,该函数返回一个16位的ADC转换结果值。

(6)Main程序

int main(void)
{
Debug_USART_Config(); //初始化USART1
Temp_Init();
while(1)
{
   ADC_Vol =(float) ADC_ConvertedValue/4096*(float)3.3; // 读取转换的AD值
printf("
 The current AD value = %f V 
",ADC_Vol);     
Delay(0xffffee);  
}
}

主函数先配置调试串口相关参数,接下来调用Temp_Init函数进行ADC初始化配置并启动ADC。在ADC中断服务函数中把AD转换结果保存在变量ADC_ConvertedValue中,可以计算出对应的IO口电压值,最后把相关数据打印至串口调试助手。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 转换器
    +关注

    关注

    27

    文章

    8621

    浏览量

    146828
  • 寄存器
    +关注

    关注

    31

    文章

    5308

    浏览量

    119975
  • adc
    adc
    +关注

    关注

    98

    文章

    6429

    浏览量

    544035
  • 比较器
    +关注

    关注

    14

    文章

    1633

    浏览量

    107086
  • 电压采集
    +关注

    关注

    2

    文章

    21

    浏览量

    14170

原文标题:MCU微课堂|CKS32F4xx系列ADC单通道电压采集

文章出处:【微信号:中科芯MCU,微信公众号:中科芯MCU】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    CKS32F4xx系列ETH通信详解

    CKS32F4xx系列芯片自带以太网模块,该模块包括带专用DMA控制器的MAC 802.3(介质访问控制)控制器
    的头像 发表于 11-10 11:13 953次阅读
    <b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列</b>ETH通信详解

    CKS32F4xx系列DSP功能介绍

    CKS32F4xx系列使用高性能的32位内核,支持浮点运算单元(FPU),同时还支持DSP指令以及存储保护(MPU)用来加强应用的安全性。
    的头像 发表于 03-04 13:43 1502次阅读
    <b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列</b>DSP功能介绍

    CKS32F4xx系列产品串口DMA传输

    在上一讲,我们讲过CKS32F4xx系列的6个串口都支持DMA传输。因此本节我们对CKS32F4xx系列的DMA进行介绍,同时利用DMA对串口数据进行传输。
    的头像 发表于 04-10 11:18 1004次阅读

    CKS32F4xx系列RNG功能设置

    主机读数时提供一个32位的随机数。     CKS32F4xx系列的随机数发生器框图如图1所示: 图1.RNG框图     CKS32F4xx系列的随机数发生器(RNG)采用模拟电路
    的头像 发表于 09-08 10:01 572次阅读
    <b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列</b>RNG功能设置

    CKS32F4xx系列DAC功能

    CKS32F4xx系列DAC功能
    的头像 发表于 11-06 16:56 815次阅读
    <b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列</b>DAC功能

    CKS32F4xx系列ADC通道DMA电压采集

    CKS32F4xx系列ADC通道DMA电压采集
    的头像 发表于 11-06 16:53 1065次阅读

    CKS32F4xx系列ADC单通道电压采集

    CKS32F4xx系列ADC单通道电压采集
    的头像 发表于 11-06 16:54 945次阅读
    <b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列</b><b class='flag-5'>ADC</b><b class='flag-5'>单通道</b><b class='flag-5'>电压</b><b class='flag-5'>采集</b>

    CKS32F4xx系列低功耗模式STANDBY模式

    CKS32F4xx系列低功耗模式STANDBY模式
    的头像 发表于 11-06 16:57 451次阅读
    <b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列</b>低功耗模式STANDBY模式

    CKS32F4xx系列低功耗模式SLEEP模式

    CKS32F4xx系列低功耗模式SLEEP模式
    的头像 发表于 11-06 16:59 648次阅读
    <b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列</b>低功耗模式SLEEP模式

    CKS32F4xx系列低功耗模式STOP模式

    CKS32F4xx系列低功耗模式STOP模式
    的头像 发表于 11-06 17:08 593次阅读
    <b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列</b>低功耗模式STOP模式

    CKS32F4xx系列产品Timer的基本使用方法-比较输出

    CKS32F4xx系列产品Timer的基本使用方法-比较输出
    的头像 发表于 11-09 17:39 811次阅读
    <b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列</b>产品Timer的基本使用方法-比较输出

    CKS32F4xx系列产品Timer的基本使用方法-定时操作

    CKS32F4xx系列产品Timer的基本使用方法-定时操作
    的头像 发表于 11-09 17:41 575次阅读
    <b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列</b>产品Timer的基本使用方法-定时操作

    MCU微课堂 | CKS32F4xx系列产品SPI通信

    MCU微课堂 | CKS32F4xx系列产品SPI通信
    的头像 发表于 10-24 17:12 662次阅读
    MCU微课堂 | <b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列</b>产品SPI通信

    MCU微课堂 | CKS32F4xx系列产品GPIO口配置

    MCU微课堂 | CKS32F4xx系列产品GPIO口配置
    的头像 发表于 10-24 15:14 741次阅读
    MCU微课堂 | <b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列</b>产品GPIO口配置

    CKS32F4xx系列FSMC功能简介

    本课讲为大家讲解CKS32F4xx系列产品的FSMC应用实例,FSMC全称是Flexible Static Memory Controller,读作灵活的静态存储控制器,顾名思义,MCU可以通过FSMC扩展静态内存
    的头像 发表于 04-14 15:06 857次阅读
    <b class='flag-5'>CKS32F4xx</b><b class='flag-5'>系列</b>FSMC功能简介