CW32系列模数转换器(ADC)

news2024/11/24 20:31:40

模数转换器(ADC)的主要功能是将模拟量转换为数字量,方便MCU进行处理。下面以CW32L083为例介绍CW系列的模数转换器的特点和功能,并提供演示实例。

一、概述

CW32L083 内部集成一个 12 位精度、最高 1M SPS 转换速度的逐次逼近型模数转换器 (SAR ADC),最多可将 16 路模拟信号转换为数字信号。现实世界中的绝大多数信号都是模拟量,如光、电、声、图像信号等,都要由 ADC 转换成数字信号,才能由 MCU 进行数字化处理。

二、主要特性

• 12 位精度 

• 可编程转换速度,最高达 1M SPS 

• 16 路输入转换通道:13 路外部引脚输入 - 内置温度传感器 - 内置 BGR 1.2V 基准 - 1/3 VDDA 电源电压 

• 4 路参考电压源(Vref):- VDDA 电源电压 - ExRef(PB00)引脚电压 - 内置 1.5V 参考电压 - 内置 2.5V 参考电压 

• 采样电压输入范围:0 ~ Vref

 多种转换模式,全部支持转换累加功能 - 单次转换 - 多次转换 - 连续转换 - 序列扫描转换 - 序列断续转换 

• 支持单通道、序列通道两种通道选择,最大同时支持 8 个序列 

• 支持输入通道电压阈值监测

• 内置信号跟随器,可转换高阻抗输入信号 

• 支持片内外设自动触发 ADC 转换 

• 支持 ADC 转换完成触发 DMA

三、转换时序

ADC 的转换时序如下图所示:

向 ADC 控制寄存器 ADC_CR0 的 EN 位域写入 1,使能 ADC 模块。 

ADC_CR0.EN 由 0 变为 1 约 40μs 后 ADC_ISR.READY 标志位置 1,表示模拟电路初始化完成,可以开始进行 ADC 转换。 

向 ADC 启动寄存器 ADC_START 的 START 位域写入 1,启动 ADC 转换,转换完成后硬件自动清零。 

ADC 工作时钟 ADCCLK,由系统时钟 PCLK 经预分频器分频得到,通过控制寄存器 ADC_CR0 的 CLK 位域可选择 1 ~ 128 分频

四、工作模式

ADC 控制寄存器 ADC_CR0 的 MODE 位域配置 ADC 工作模式

启动 ADC 转换,可通过向 ADC 启动寄存器 ADC_START 的 START 位域写 1;也可通过其他外设来触发。

五、实际案例

GTIM1定时器定时1S,定时器1S中断触发启动ADC转换,采样AIN1,并通过GTIM2以PWM方波输出ADC采样值:PWM占空比50%,周期为1Hz-5000Hz,对应ADC的0-4095采样值。

1.配置ADC测试IO口

void ADC_PortInit(void)

{

    REGBITS_SET(CW_SYSCTRL->AHBEN, SYSCTRL_AHBEN_GPIOA_Msk); //打开GPIO时钟

    REGBITS_SET(CW_SYSCTRL->APBEN2, SYSCTRL_APBEN2_ADC_Msk); //打开ADC时钟

    PA01_ANALOG_ENABLE();//set PA01 as AIN1 INPUT

}

2.LED初始化

void LED_Init(void)

{

    GPIO_InitTypeDef GPIO_InitStructure = {0};

    REGBITS_SET(CW_SYSCTRL->AHBEN, SYSCTRL_AHBEN_GPIOC_Msk); //打开GPIO时钟

    /* Configure the GPIO_LED pin */

    GPIO_InitStructure.Pins = GPIO_PIN_2 | GPIO_PIN_3;

    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;

    GPIO_Init(CW_GPIOC, &GPIO_InitStructure);

    PC02_SETLOW();//LEDs are off.

    PC03_SETLOW();

}


3.PWM IO初始化

void PWM_PortInit(void)

{

    GPIO_InitTypeDef GPIO_InitStructure = {0};

    /* PA5 PWM 输出 */

    __RCC_GPIOA_CLK_ENABLE();

    /* Configure the PWM output pin */

    GPIO_InitStructure.Pins = GPIO_PIN_5;

    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;

    GPIO_Init(CW_GPIOA, &GPIO_InitStructure);

    PA05_AFx_GTIM2CH1();

}

4.GTIM初始化

void GTIM_Init(void)

{

GTIM_InitTypeDef GTIM_InitStruct = {0};



//REGBITS_SET(CW_SYSCTRL->APBEN1, SYSCTRL_APBEN1_GTIM1_Msk); //打开GTIM1 

__RCC_GTIM1_CLK_ENABLE(); //打开GTIM1时钟

    GTIM_InitStruct.Mode = GTIM_MODE_TIME;

    GTIM_InitStruct.OneShotMode = GTIM_COUNT_CONTINUE;

    GTIM_InitStruct.Prescaler = GTIM_PRESCALER_DIV1024;

    GTIM_InitStruct.ReloadValue = 62499ul; //T=1s.

    GTIM_InitStruct.ToggleOutState = DISABLE;

    GTIM_TimeBaseInit(CW_GTIM1, &GTIM_InitStruct);

    GTIM_ITConfig(CW_GTIM1, GTIM_IT_OV, ENABLE);

    NVIC_ClearPendingIRQ(GTIM1_IRQn);

    NVIC_EnableIRQ(GTIM1_IRQn);

    NVIC_SetPriority(GTIM1_IRQn, 0x03);



    __RCC_GTIM2_CLK_ENABLE();//打开GTIM2时钟

    GTIM_InitStruct.ReloadValue = 0xFFFFu;

    GTIM_InitStruct.ToggleOutState = ENABLE;

    GTIM_TimeBaseInit(CW_GTIM2, &GTIM_InitStruct);

    valuePeriod = GTIM_InitStruct.ReloadValue;

    valuePosWidth = valuePeriod >> 1u;

    GTIM_OCInit(CW_GTIM2, GTIM_CHANNEL1, GTIM_OC_OUTPUT_PWM_HIGH);

    GTIM_SetCompare1(CW_GTIM2, valuePosWidth);

    GTIM_Cmd(CW_GTIM2, ENABLE);

}

5.主程序main

uint16_t valueAdc;

uint32_t valueAdcAcc;

volatile uint8_t gFlagIrq;

uint16_t gCntEoc = 0;

uint8_t cntSample;

float fTsDegree;

uint32_t valuePeriod;

uint32_t valuePosWidth;

uint32_t valueReload = 0xFFFFu;

int main(void)

{   uint8_t res;

    ADC_InitTypeDef ADC_InitStructure = {0};

    ADC_WdtTypeDef ADC_WdtStructure = {0};

    ADC_SingleChTypeDef ADC_SingleChStructure = {0};

    RCC_HSI_Enable(RCC_HSIOSC_DIV6); //以下从HSI切换到PLL

RCC_PLL_Enable(RCC_PLLSOURCE_HSI, 8000000UL, RCC_PLL_MUL_8); 

//开启PLL,PLL源为HSI

__RCC_FLASH_CLK_ENABLE();//打开FLASH时钟

    FLASH_SetLatency(FLASH_Latency_3);

    res = RCC_SysClk_Switch(RCC_SYSCLKSRC_PLL); //切换系统时钟到PLL:64MHz。

    ADC_PortInit();//配置ADC测试IO口

    LED_Init();//LED初始化

    PWM_PortInit();

    GTIM_Init();

    ADC_StructInit(&ADC_InitStructure); //ADC默认值初始化

    ADC_WdtInit(&ADC_WdtStructure); //ADC模拟看门狗通道初始化

    ADC_InitStructure.ADC_ClkDiv = ADC_Clk_Div128;    //ADCCLK:500KHz.

    ADC_InitStructure.ADC_InBufEn = ADC_BufEnable;

    ADC_InitStructure.ADC_SampleTime = ADC_SampTime10Clk;

    ADC_SingleChStructure.ADC_DiscardEn = ADC_DiscardNull; //配置单通道转换模式

    ADC_SingleChStructure.ADC_Chmux = ADC_ExInputCH1; //选择ADC转换通道

    ADC_SingleChStructure.ADC_InitStruct = ADC_InitStructure;

    ADC_SingleChStructure.ADC_WdtStruct = ADC_WdtStructure;

    ADC_SingleChOneModeCfg(&ADC_SingleChStructure);

    ADC_ITConfig(ADC_IT_EOC, ENABLE);

    ADC_EnableIrq(ADC_INT_PRIORITY);

    ADC_ClearITPendingAll();

    ADC_Enable();//ADC使能

    ADC_ExtTrigCfg(ADC_TRIG_GTIM1, ENABLE); //ADC外部中断触发源配置

    GTIM_Cmd(CW_GTIM1, ENABLE);

    while (1)

    {

        while (!(gFlagIrq & ADC_ISR_EOC_Msk));

        gFlagIrq = 0u;

        PC03_TOG();

        valueAdc = ADC_GetConversionValue();

        valueReload = ((4095u * 125000ul) / (4999u * valueAdc + 4095u) + 1) >> 1;

        GTIM_SetCounterValue(CW_GTIM2, 0u);     //reset.

        GTIM_SetReloadValue(CW_GTIM2, valueReload);

        GTIM_SetCompare1(CW_GTIM2, valuePosWidth);

        //等待ADC外部中断触发源启动下一次ADC转换

    }

}

6.实验展示

通用定时器GTIM1定时1s自动触发ADC模块进行转换,ADC通道为AIN1:PA01。

通用定时器GTIM2将AIN1的ADC采样值转换成频率可变的PWM方波,占空比50%,使用PA05作为PWM输出。ADC采样值为0时,PWM方波频率为1Hz;ADC采样值为4095时,PWM方波频率为5KHz。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/599606.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

位操作符的应用

目录 位操作符的概念: 一、&(按位与):两个整数的补码对应的二进制位有0则为0,两个同时为1才为1,得到的数仍为补码。 二、|(按位或):两个整数的补码对应的二进制位…

Effective第三版 中英 | 第2章 创建和销毁对象 | 当面临多个参数的构造器时考虑使用构建器

文章目录 Effective第三版前言第2章 创建和销毁对象当面临多个参数的构造器时考虑使用构建器 Effective第三版 前言 大家好,这里是 Rocky 编程日记 ,喜欢后端架构及中间件源码,目前正在阅读 effective-java 书籍。同时也把自己学习该书时的笔…

【KKT】∇f(x)+λ∇g(x)=0中λ的讨论

Karush-Kuhn-Tucker (KKT)条件 〇、问题背景 在阅读 Karush-Kuhn-Tucker (KKT)条件 时,不太能理解 ∇ f \nabla f ∇f 的方向,以及 ∇ g \nabla g ∇g 的方向: 为什么 ∇ f \nabla f ∇f 是指向可行域内部, ∇ g \nabla g ∇g…

Java多线程方面知识

目录 1.程序、进程、线程 2.进程与线程的内存解析 3.并发与并行 4.Java程序的线程 5.多线程的创建:方式一:继承于Thread类 6.start方法的作用 7.使用start()时要注意的问题 8.Thread类中的一些方法 9.线程的优先级 10.多线程的创建&#xff1a…

【JAVA】清缓存(打断点删除 / 新增表或字段无效)

一. 打断点无效 情景 新写了一个获取列表数据接口,前端调用的,获取到的数据为空数组。在数据库中查看,是有数据的,但是调用接口返回数据为空。接下来就打断点啦,发现无效!表现如下 没有可执行的…

【Bio】牙的分类

文章目录 IncisorCentral IncisorLateral Incisor Canine / CuspidPremolarFirst PremolarSecond Premolar MolarFirst MolarSecond MolarThird Molar / Wisdom Tooth Ref Incisor Central Incisor Lateral Incisor Canine / Cuspid Premolar First Premolar Second Prem…

第六十二天学习记录:C语言进阶:C语言预处理2

带副作用的宏参数 当宏参数在宏的定义中出现超过一次的时候,如果参数带有副作用,那么你在使用这个宏的时候就可能出现危险,导致不可预测的后果。副作用就是表达式求值的时候出现的永久性效果。例如: x1;//不带副作用 x;//带有副作…

安全认证:

1. 认证概述 为什么要有认证? 防止非法路由器接入企业内网的ospf路由器,保护内网安全 2. 认证方式 认证方式分为接口认证和区域认证,接口认证和区域认证没有本质的区别,接口认证是当区域内链路过多的情况下,接口认证…

Java网络开发(Tomcat)—— Servlet学习 Web相关背景知识 JavaWeb项目初步

本文目录 引出一、软件架构BS和CS二、实现Web服务的条件和步骤三、Tomcat搭建Web项目初步1.pom.xml文件配置2.web.xml文件更新3.Tomcat运行环境配置4.项目文件层级解析 四、JavaWeb项目文件分类(1)静态文件—存放位置(2)动态文件-…

【用人话讲算法】leetcode无重复字符的最长子串

【用人话讲算法】leetcode无重复字符的最长子串 文章目录 【用人话讲算法】leetcode无重复字符的最长子串题目简单思路(暴力)优化思考怎么写代码?怎么到下一个?whilefor 思路总结while和for循环总结 题目 题目的意思是说&#xff…

一台电脑上安装多个版本的python,运行互不干扰,显示位置的一些命令,

首先需要知道一些命令: pip show 包名 可以使用pip show 包名的方式显示位置 pip list pip方式显示的是当前环境下的库 os.environ.get() python中os模块获取环境变量的一个方法 Python os.environ.get()的用法 …

使用Git LFS上传Unity大型资源文件

在使用Unity制作结课作业时,使用到git工具进行版本控制与多人协作。在提交项目至远程仓库的过程中,git bash提示了以下报错: remote: warning: File Assets/Models/Z_India_5.29.fbx is 57.31 MB; this is larger than GitHubs recommended m…

利用环回口建立IBGP邻居

利用环回口建立IBGP邻居 BGP的稳定性 IBGP : 1.一般使用环回口建立IBGP邻居 2.指定建立IBGP邻居的源地址为lookback地址 EBGP : 1.一般使用直连接口建立EBGP邻居关系 2.如果想使用环回口建立EBGP邻居,需要将TTL值修改为大于1,默认TTL1 修改命令…

在win10/11的右键菜单添加电源选项

前言: 今天,博主从网上找到了在右键菜单中添加电源选项的方法,觉得挺实用的所以来教大家 方法: 下载(懒人专用,直接打开文件即可): csdn中下载(启用和关闭文件都有&a…

基于 Docker_redis6.0.8 实现 Redis 集群扩缩容

文章目录 单机部署数据分区方案集群部署集群容错测试集群扩容测试集群缩容测试 LXL:这玩意太枯燥,看完需要耐心 ~~~ 单机部署 通过 dockerhub 查找 redis 镜像,选择 6.0.8 版本。创建挂载目录,并赋予权限。 mkdir -p /var/docker…

MicroPython应用基础-使用Thonny IDE

MicroPython应用基础-使用Thonny IDE 文章目录 MicroPython应用基础-使用Thonny IDE引言Thonny简介使用Thonny连接到MicroPython开发板使用Thonny的REPL窗口运行Python语句在Thonny中保存Python程序文件至MicroPython开发板中运行使用Thonny的注意要点 引言 在很长一段时间内&…

[论文分享]TimeMAE:解耦掩码自编码器时间序列的自监督表示

论文题目:TimeMAE: Self-Supervised Representations of Time Series with Decoupled Masked Autoencoders 论文地址:https://arxiv.org/abs/2303.00320 代码地址:https://github.com/Mingyue-Cheng/TimeMAE 1 摘要 利用自监督预训练增强基于…

Flume和Kafka的组合使用

一.安装Kafka 1.1下载安装包 通过百度网盘分享的文件:复制链接打开「百度网盘APP 即可获取」 链接:https://pan.baidu.com/s/1vC6Di3Pml6k1KMbnK0OE1Q?pwdhuan 提取码:huan 也可以访问官网,下载kafka2.4.0的安装文件 1.2解…

Hadoop3.1.3安装(单机、伪分布)

系列文章目录 Ubuntu常见基本问题 Hadoop3.1.3安装(单机、伪分布) Hadoop集群搭建 文章目录 系列文章目录一、环境1、创建hadoop用户 二、更新apt三、安装SSH、配置SSH无密码登陆四、安装Java环境五、安装 Hadoop3.1.3六、Hadoop单机配置(非分布式)七、…

chatgpt赋能python:Python为什么被吹得这么神?

Python为什么被吹得这么神? Python是一个开源、跨平台的高级编程语言,由Guido van Rossum于1989年在荷兰创造。Python在近几年因其方便易用、高效稳定和丰富的生态体系而备受欢迎。Python被广泛应用于数据科学、人工智能、机器学习、Web开发、自动化测试…