打印
[产品介绍及宣传专区]

CW32系列模数转换器(ADC)

[复制链接]
2965|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
模数转换器(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采样值。
配置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
}
LED初始化
void LED_Init(void)
{
GPIO_InitTypeDefGPIO_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();
}
PWM IO初始化
void PWM_PortInit(void)
{
GPIO_InitTypeDefGPIO_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();
}
GTIM初始化
void GTIM_Init(void)
{
GTIM_InitTypeDefGTIM_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);
}
主程序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_InitTypeDefADC_InitStructure = {0};
ADC_WdtTypeDefADC_WdtStructure = {0};
ADC_SingleChTypeDefADC_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转换
    }
}
实验展示
通用定时器GTIM1定时1s自动触发ADC模块进行转换,ADC通道为AIN1:PA01。
通用定时器GTIM2将AIN1的ADC采样值转换成频率可变的PWM方波,占空比50%,使用PA05作为PWM输出。ADC采样值为0时,PWM方波频率为1Hz;ADC采样值为4095时,PWM方波频率为5KHz。


使用特权

评论回复
沙发
caigang13| | 2023-6-3 16:48 | 只看该作者
还以为是出ADC芯片了,现在国产ADC芯片太少了。

使用特权

评论回复
板凳
duo点| | 2023-6-5 11:42 | 只看该作者
看标题确实以为是出ADC芯片了

使用特权

评论回复
地板
yangxiaor520| | 2023-7-1 11:54 | 只看该作者
支持同步采样嘛?

使用特权

评论回复
5
pssyx| | 2023-7-3 09:06 | 只看该作者
yangxiaor520 发表于 2023-7-1 11:54
支持同步采样嘛?

ADC不支持同步采样。

使用特权

评论回复
6
两只袜子| | 2023-7-4 15:03 | 只看该作者
总的来说这个模数转换器还不错

使用特权

评论回复
7
daichaodai| | 2023-8-18 08:23 | 只看该作者
多路ADC支持同步触发模式吗?

使用特权

评论回复
8
pssyx| | 2023-8-21 09:40 | 只看该作者
daichaodai 发表于 2023-8-18 08:23
多路ADC支持同步触发模式吗?

CW32 MCU只有一个ADC,因此不支持多通道同步采样的。

使用特权

评论回复
9
chenqianqian| | 2024-4-10 21:44 | 只看该作者
只有一个ADC,有点鸡肋了。

使用特权

评论回复
10
huquanz711| | 2024-4-16 07:35 | 只看该作者
还以为是ADC芯片呢

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

45

主题

45

帖子

0

粉丝