三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

CH32F20x系列MCU模拟外设深度解析:温度传感器、DAC与OPA实战指南

CH32F20x系列MCU模拟外设深度解析:温度传感器、DAC与OPA实战指南

1. 项目概述:为什么需要关注CH32F20x系列MCU的模拟外设?

在嵌入式开发领域,MCU的选型往往是一场在性能、成本、外设资源和开发便利性之间的权衡。当项目需求从简单的逻辑控制延伸到需要感知物理世界、输出模拟信号或进行信号调理时,模拟外设的质量和易用性就成了决定性的砝码。最近在评估一款需要高精度温度监控和模拟信号生成的项目时,我深入研究了沁恒微电子的CH32F205/207/203系列大容量MCU。这个系列以其高性价比和丰富的外设资源在市场上颇受关注,但其数据手册中关于模拟部分——特别是内置温度传感器、数模转换器(DAC)和运算放大器(OPA)——的描述相对分散,实际应用中的细节和“坑点”需要结合实践才能摸清。网络上相关的热词,如“热敏电阻制作温度传感器”、“DAC输出三角波”、“MCU选型”等,也恰恰反映了工程师们在处理模拟信号时的普遍需求和困惑。本文将结合数据手册和实测经验,为你深度拆解这三项关键模拟特性,希望能为你的下一个项目选型或设计提供一份可靠的参考。

2. 核心特性总览与选型考量

CH32F205/207/203系列同属一个产品家族,内核基于ARM Cortex-M3,主打大容量Flash(128KB至512KB)和SRAM(64KB至96KB),并集成了丰富的外设。在模拟部分,它们都配备了1个12位ADC、2个12位DAC和2个运算放大器(OPA)。但细微的差异决定了它们的最佳应用场景。

2.1 型号差异与选型指南

虽然模拟外设的“数量”看起来一致,但性能边界和封装选项有所不同,这直接影响了系统设计的灵活性和成本。

  • CH32F207:可以看作是该系列的“完全体”。它运行频率最高(144MHz),Flash和SRAM容量最大(512KB Flash, 96KB SRAM)。更重要的是,其DAC输出缓冲器的驱动能力更强,OPA的带宽和压摆率指标通常也更优(具体需以最新数据手册为准)。这意味着在需要生成高频或驱动较重负载的模拟信号时,F207是更稳妥的选择。
  • CH32F205:可以理解为F207的“性价比”版本。主频略低(120MHz或144MHz,取决于型号),存储容量适中。其模拟外设的性能参数可能略低于F207,但对于大多数中低速、中精度的应用(如音频生成、慢速波形输出、温度监控)完全足够。
  • CH32F203:通常是该系列的入门款或引脚精简款。主频和存储容量进一步精简,部分型号的封装更小,引脚数更少。这里有一个关键点需要核实:对于引脚数少的封装(如LQFP48或更小),芯片可能无法引出全部2个DAC通道和2个OPA的所有输入输出引脚。在选型时,必须仔细核对具体封装型号的引脚分配图,确认你需要的DAC和OPA引脚是否可用。

选型心得:不要只看“有没有”,更要看“能不能用得好”。如果你的设计对模拟信号质量(如低噪声、高速度)有要求,或者需要驱动低阻抗负载,优先考虑F207。如果成本敏感,且应用场景对模拟性能要求不高,F205是均衡之选。如果项目尺寸受限,需要小封装,务必仔细检查F203对应封装的引脚复用表,避免硬件设计完成才发现关键模拟引脚被占用或未引出。

2.2 模拟子系统关联性分析

这三个模块并非孤立存在,它们可以协同工作,构建更强大的模拟信号链,这也是该系列MCU的一个设计亮点。

  1. 温度传感器 -> ADC:片内温度传感器的输出是一个与结温成比例的模拟电压(典型值约1.4V @ 25°C),它直接连接到ADC的一个内部输入通道(通常是通道16或17)。因此,测温的精度本质上取决于ADC的精度和稳定性。
  2. DAC -> OPA:DAC的输出电压范围通常是0~VREF+(参考电压)。这个电压可能驱动能力有限,或者需要放大、衰减、缓冲。此时,可以将DAC输出直接连接到OPA的同相或反相输入端,利用OPA构成电压跟随器、同相/反相放大器、滤波电路等,从而灵活调理信号。
  3. OPA -> ADC:OPA的输出也可以回送到ADC的另一个通道进行采样,实现闭环控制或信号监测。例如,可以用OPA放大一个微弱的传感器信号,然后用ADC采样放大后的结果。

这种高度的内部互联性,减少了外部元件需求,提高了系统集成度和可靠性,但同时也对PCB布局布线和软件配置时序提出了更高要求。

3. 内置温度传感器深度解析与校准实战

很多工程师对MCU内置温度传感器的第一印象是“不准,只能看个趋势”。对于CH32F20x系列,如果使用得当,它完全能满足大多数工业控制、环境监测中对温度监控的需求(例如,监测芯片自身温升以防过热降频),关键在于理解和实施校准。

3.1 工作原理与核心参数

该温度传感器本质上是一个基于半导体PN结温度特性的电压源。其输出电压V_TS与芯片结温T_J近似呈线性负相关关系。数据手册会给出几个关键参数:

  • 典型电压:在某个特定温度(如25°C或30°C)下的输出电压值。例如,V_TS@30°C = 1.34V。
  • 平均斜率:温度每变化1摄氏度,输出电压的变化量,单位通常是mV/°C。例如,典型斜率 -4.3 mV/°C。注意这个值是负的,意味着温度升高,电压下降。
  • 精度:数据手册通常会给出一个未校准情况下的误差范围,例如±2°C @ 25°C。这个误差主要来源于半导体制造的公差。

重要提示:这个传感器测量的是芯片的结温(Junction Temperature),而非环境温度。结温通常比环境温度高,其差值取决于芯片的功耗(运行频率、外设开启情况)和散热条件。因此,它最适合用于监控芯片自身的工作状态。

3.2 高精度测温软件实现步骤

直接读取ADC值并套用公式计算,误差可能很大。以下是经过实践验证的校准与计算流程:

  1. ADC配置:启用ADC1,将采样通道设置为温度传感器对应的内部通道(如ADC_Channel_16)。建议将采样时间设置得足够长(例如ADC_SampleTime_239Cycles5),以提高采样精度,降低噪声。禁用其他可能引入噪声的模拟外设(如DAC、OPA),除非你正在使用它们。

  2. 两点校准法(关键步骤): 这是提升精度的核心。需要在两个已知的、稳定的温度点(T1, T2)下,分别读取对应的ADC原始值(AD1, AD2)。

    • 如何获取已知温度点?
      • 方法A(推荐,较准):将MCU与一个高精度的数字温度计(如DS18B20)置于同一个温控环境(如恒温箱)中。分别记录在低温点(如25°C)和高温点(如60°C)下,MCU温度传感器的ADC读数。此时数字温度计的值作为“真实温度”参考。
      • 方法B(简便,精度尚可):利用室温(用可靠的室内温度计测量)作为第一个点(T1)。然后,用手轻轻捏住芯片(注意防静电)使其升温,稳定几十秒后,用温度计测量芯片表面温度作为第二个点(T2)。此法便捷,但T2的准确性稍差。
    • 计算斜率与截距: 得到(T1, AD1)和(T2, AD2)后,假设ADC值与温度呈线性关系(在一般范围内容易成立),则:斜率k = (T2 - T1) / (AD2 - AD1)截距b = T1 - k * AD1将k和b存储在Flash中(如某个固定地址),作为本次校准的系数。
  3. 实时温度计算: 在后续应用中,读取ADC原始值ADx,则计算出的温度Temp为:Temp = k * ADx + b单位是摄氏度。

  4. 软件滤波: 由于ADC读数存在噪声,单次采样结果会跳动。必须采用软件滤波。

    • 移动平均滤波:连续采样N次(如64次),求和后取平均值。实现简单,效果明显。
    • 中值滤波:采样N次,取大小居中的那个值。对脉冲噪声抑制效果好。
    • 一阶低通滤波(惯性滤波)Temp_filtered = α * Temp_new + (1-α) * Temp_filtered_old,其中α为滤波系数(0<α<1)。这种方法能平滑数据且占用资源少。

实操避坑指南

注意:温度传感器在芯片上电后需要一段稳定时间(数据手册中称为“唤醒时间”,可能几十微秒)。在启动ADC转换前,务必确保已使能温度传感器并等待足够时间。一个常见的错误是使能后立即采样,导致前几次读数严重不准。注意:ADC的参考电压(VREF+)的稳定性直接决定测温精度。如果使用VDDA作为参考电压,请确保电源干净、稳定。对于高精度要求,建议使用外部精密基准电压源。心得:校准系数会因芯片个体、供电电压、ADC参考源的不同而略有差异。对于批量生产,如果条件允许,可以对每个板子进行单独校准,并将系数写入芯片。如果做不到,可以抽样校准一批,取平均系数,这样也能将误差控制在±1°C以内,远优于未校准状态。

4. 12位DAC特性详解与波形生成实战

DAC是将数字控制字转换为模拟电压的桥梁。CH32F20x的DAC是12位分辨率,意味着其输出有2^12=4096个离散的电压等级。

4.1 DAC核心功能模式

  1. 基本模式:软件直接向DAC数据保持寄存器(DAC_DHRx)写入12位数字值,DAC即输出对应的电压。输出电压公式为:Vout = (VREF+ * DOR) / 4095,其中DOR是数据输出寄存器的值(0-4095)。这是最常用的模式。
  2. 触发模式:DAC转换可以由定时器(TIMx)、外部中断线等事件触发。这对于需要精确定时更新DAC输出(如生成特定频率的波形)至关重要。配置好触发源后,只需在触发事件发生时更新DAC_DHRx,转换会自动进行。
  3. DMA模式:这是生成连续波形的“神器”。可以将一个存储了波形数据点(数组)的缓冲区与DAC关联,并启用DMA。DMA会在每次触发事件(如定时器更新)发生时,自动将下一个数据点从内存搬运到DAC_DHRx,无需CPU干预。这样可以高效、无抖动地生成任意波形。

4.2 实战:使用DAC+DMA生成三角波

生成一个频率为1kHz,幅度为0-3V的三角波。

  1. 计算参数

    • 假设DAC参考电压VREF+ = 3.3V。
    • 幅度对应DAC值:0V对应0, 3V对应(3.0 / 3.3) * 4095 ≈ 3723
    • 波形一个周期包含上升沿和下降沿。假设我们使用200个点来描绘一个周期。
    • 定时器触发频率 = 波形频率 * 每周期点数 = 1000Hz * 200 = 200kHz。
    • 定时器ARR(自动重载值) = 系统时钟 / 定时器触发频率 - 1。若系统时钟72MHz,则ARR = 72000000/200000 - 1 = 359。
  2. 生成波形数组

    #define WAVE_POINTS 200 #define DAC_MAX_VALUE 3723 uint16_t triangle_wave[WAVE_POINTS]; for(int i=0; i<WAVE_POINTS; i++) { if(i < WAVE_POINTS/2) { // 上升沿 triangle_wave[i] = (DAC_MAX_VALUE * 2 * i) / WAVE_POINTS; } else { // 下降沿 triangle_wave[i] = DAC_MAX_VALUE * 2 * (WAVE_POINTS - i) / WAVE_POINTS; } }
  3. 硬件与软件配置

    • DAC:使能DAC时钟,配置对应引脚(PA4/DAC_OUT1或PA5/DAC_OUT2)为模拟模式。初始化DAC,使能输出缓冲(DAC_OutputBuffer)以增强驱动能力(驱动负载>5kΩ时建议开启)。
    • 定时器:配置一个定时器(如TIM6)工作在更新模式,ARR设置为359,PSC设置为0,产生200kHz的更新事件。
    • DMA:配置DMA通道,将内存地址(triangle_wave数组)传输到外设地址(DAC_DHR12R1寄存器)。设置传输数据宽度为半字(16位),循环模式,外设到内存禁止,内存到外设允许。
    • 联动:将DAC的触发源设置为该定时器(TIM6 TRGO),并使能DAC的DMA请求。
  4. 启动:使能定时器,使能DAC的DMA传输。此时,DAC便会以1kHz的频率循环输出三角波。

注意事项

注意:DAC的输出缓冲器虽然能增强驱动能力,但会引入一定的失调电压和非线性,并且有带宽限制。对于需要极高直流精度或高频信号的应用,可以考虑关闭缓冲器,但必须确保负载阻抗足够大(例如>100kΩ),否则输出会因负载效应而不准。心得:DAC的输出在刚上电或使能时可能是不确定的。一个好的做法是,在初始化完成后,先向DAC数据寄存器写入一个明确的初始值(如0),然后再启用输出或触发。这样可以避免系统启动时出现一个电压毛刺。

5. 片内运算放大器(OPA)应用全攻略

片内集成OPA极大地扩展了MCU的模拟前端处理能力,可以用于信号放大、滤波、电压跟随、比较等,无需外部分立运放,节省成本和空间。

5.1 OPA工作模式配置

CH32F20x的每个OPA通常支持多种模式,通过配置寄存器选择:

  • 通用模式(GP):作为独立的运算放大器使用,同相、反相输入端和输出端都连接到外部引脚。可以搭建各种经典运放电路。
  • 跟随器模式(Follower):输出内部连接到反相输入端,构成单位增益缓冲器。此时,反相输入引脚可能不可用。用于高阻抗信号源与低阻抗负载之间的隔离。
  • 可编程增益放大器模式(PGA):配合内部电阻网络,可以设置几个固定的闭环增益(如2倍, 4倍, 8倍, 16倍)。这种模式下,外部电路最简单,但增益选项有限。
  • 与ADC相连的模式:OPA的输出可以直接连接到ADC的特定输入通道,构成一个完整的信号调理和采集链。

5.2 典型应用电路与软件配置

应用一:电压跟随器(缓冲器)

  • 场景:传感器输出阻抗高(如光电二极管、某些分压网络),直接接ADC会导致采样误差。
  • 硬件连接:将信号源接至OPA的同相输入端(OPAx_INP)。反相输入端(OPAx_INN)与输出端(OPAx_OUT)短接(如果是跟随器模式,此连接可能在内部完成)。输出端接ADC输入通道。
  • 软件配置:将OPA配置为跟随器模式,使能即可。无需复杂计算。

应用二:同相放大器

  • 场景:放大一个微弱的单端信号,例如热电偶信号。
  • 硬件连接:信号接OPAx_INP。在OPAx_OUT和OPAx_INN之间连接反馈电阻Rf,在OPAx_INN和地之间连接输入电阻Rin。增益G = 1 + Rf/Rin

    重要提醒:片内OPA通常不提供这些外部电阻,你需要自己在PCB上连接。务必选择精度高、温漂小的电阻(如1%精度,25ppm/°C)。

  • 软件配置:将OPA配置为通用模式。使能OPA时钟,初始化OPA,设置工作模式为独立运放。ADC配置为采样OPA输出对应的引脚。

应用三:有源低通滤波器

  • 场景:对DAC生成的信号或传感器信号进行滤波,消除高频噪声。
  • 硬件连接:这是一个同相放大器电路的变体。在反馈通路(Rf)上并联一个电容Cf到地,构成一阶有源低通滤波器。截止频率fc = 1 / (2π * Rf * Cf)
  • 软件配置:同应用二,OPA配置为通用模式。

5.3 OPA使用中的关键陷阱与对策

  1. 电源与地噪声:OPA对电源噪声非常敏感。必须确保给OPA供电的模拟电源(VDDA)极其干净。在VDDA和地(VSSA)之间,尽可能靠近OPA电源引脚放置一个0.1μF和一个10μF的电容进行去耦。模拟地和数字地单点连接。
  2. 输入输出范围:OPA不是“理想运放”,其输入电压和输出电压范围是有限的,通常无法达到电源轨(Rail-to-Rail)。数据手册会给出“共模输入电压范围”和“输出电压摆幅”参数。例如,在3.3V供电下,输入范围可能是0.1V到2.9V,输出范围是0.05V到3.0V。设计电路时,必须保证信号始终在这个“窗口”内,否则会产生严重失真。
  3. 带宽与压摆率限制:OPA有有限的增益带宽积(GBW)和压摆率(Slew Rate)。GBW决定了放大器在特定增益下能处理多高频率的信号而不衰减。压摆率决定了输出电压变化的最大速度。如果你用OPA放大一个高频信号,或者希望输出一个高速方波,必须核算这些参数是否满足要求。例如,输出一个1V/us的边沿,OPA的压摆率必须大于1V/us。
  4. 稳定性问题:当OPA驱动容性负载(如长的导线、ADC的采样电容)时,可能发生振荡。解决方法是在输出端串联一个小的电阻(如10-100Ω)后再接容性负载。

调试心得:当OPA电路行为异常时,首先用示波器查看电源引脚是否有噪声。然后,断开反馈网络,将OPA接成电压跟随器模式,输入一个已知的直流电压(如用DAC产生),看输出是否跟随。这可以快速判断OPA本身是否工作正常。如果跟随器正常,但加上反馈网络后异常,问题很可能出在外部电阻、电容的取值或布局上。

6. 系统集成:构建一个完整的温度监控与报警系统

现在,我们将温度传感器、DAC和OPA组合起来,实现一个简单的系统:监控芯片温度,当温度超过阈值时,用DAC生成一个可听的警报音,并通过OPA驱动一个小喇叭。

6.1 系统架构设计

  1. 信号链
    • 感知:片内温度传感器 -> ADC1 通道16。
    • 处理:MCU核心读取ADC值,计算温度,进行软件滤波,与阈值比较。
    • 输出:若超温,MCU核心通过查表法生成一个正弦波数据数组,通过DAC1(触发+DMA模式)输出。
    • 驱动:DAC输出接至OPA1构成的同相放大器(增益约10倍),OPA1输出驱动一个压电蜂鸣器或小功率喇叭。

6.2 关键代码与配置片段

// 1. 温度读取与判断 (简化) float get_chip_temperature(void) { // ... 实现ADC采样、软件滤波、利用校准系数k,b计算温度 ... return current_temp; } // 2. 生成1kHz正弦波数据(用于警报音) #define SINE_POINTS 100 uint16_t sine_wave[SINE_POINTS]; void generate_sine_wave(void) { for(int i=0; i<SINE_POINTS; i++) { // 生成幅值为Vref/2, 直流偏置为Vref/2的正弦波,使输出在0-Vref之间摆动 float val = 2047.5 * sin(2 * 3.14159 * i / SINE_POINTS) + 2047.5; sine_wave[i] = (uint16_t)val; } } // 3. 主循环逻辑 int main(void) { // 初始化系统时钟、GPIO... init_adc_and_temp_sensor(); init_dac_for_dma(); // 配置DAC,定时器触发,DMA传输数据 init_opa_as_amplifier(gain_10); // 配置OPA1为10倍同相放大 generate_sine_wave(); float temp_threshold = 70.0f; // 设置温度阈值 while(1) { float temp = get_chip_temperature(); if(temp >= temp_threshold) { // 超温,启动警报音 start_dac_dma((uint32_t)sine_wave, SINE_POINTS); delay_ms(500); // 响0.5秒 stop_dac_dma(); delay_ms(500); // 停0.5秒,形成断续音 } else { // 温度正常,DAC输出0V(可选) set_dac_quiet(); delay_ms(1000); // 每秒检查一次 } } }

6.3 系统调试与优化要点

  • 优先级管理:温度采样和警报音生成可能涉及中断(ADC采样完成中断、DMA传输完成中断)。要合理设置中断优先级,确保温度监控的实时性不被DMA中断过度打断。
  • 功耗考量:在温度正常时,可以关闭OPA的电源以节能。许多MCU的模拟外设有独立的使能位。
  • PCB布局:这是模拟系统成败的关键。必须遵循严格的模拟-数字分区布局。模拟部分(VDDA, VSSA, 温度传感器、DAC、OPA、相关阻容)应集中在一起,并远离数字噪声源(如时钟线、高速数据线、开关电源)。使用完整的接地平面,并确保模拟地路径干净。

通过这样一个完整的项目实践,你不仅能掌握CH32F20x各个模拟外设的独立用法,更能理解如何将它们有机组合,解决实际的工程问题。模拟电路的设计和调试往往比数字电路更考验耐心和经验,希望本文提供的这些细节和“踩坑”经验,能让你在项目中少走弯路。

← 返回列表