模数转换器(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。
来源:武汉芯源半导体
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理
三菱 FX 3u以太网模块
基于PLC远程监控维护的自动化污水处理系统
陶瓷滤波器在调幅收音机中放电路中的应用
RTX 2080 Ti系列显卡将成为英伟达目前的顶级游戏GPU!
日本电产安萨尔多工业系统公司推出了新款超快速充电器
浅谈CW32系列模数转换器(ADC)
森普光电始终坚持技术创新,引领商业照明新风尚
怎样使用单激式变压器设计一个开关电源?地磁感应对大型变压器有什么危害?
三星S8晚了、华为P10蔫了,小米6的机会来了吗?
便携式高精度温度检测仪可使用国产ADC,可替代AD7192
维护废水处理设备的7个步骤
谷歌的YouTube VR已经能够在三星的Gear VR上使用了
电压控制高通滤波电路(VCA610)
场效应管与晶体管的比较_场效应管的应用领域
三星电子发布采用8nm工艺打造的首款集成5G的处理器
打造信息安全“国家队”,助力国家信息安全保障
K歌类APP开发方案
马斯克研究脑机接口实验引发的思索和忧虑
工业显示器的布局结构都有哪些特点
一个智能互联、以数据为中心的未来已经到来