去年我第一次接触了 CW32 的 MCU,当时的感觉就是眼前一亮,虽然也是 ARM M0+的核心,但是 IP 却比其它友商有特点,他们的发布频率也是可以的从 L010 到 L011,再到现在的 L012,也是让人有了陪伴的感觉。比较有趣的一点是,其实产品线上面不止有 L 系列的:
但是一直推低功耗的,可能这块的市场也是比较被重视的。
因为现在的外设都强大,所以我的选型办法是先看封装,然后看其它内容,(现在发现官网也是有全部信息下载的功能,可以快速选型了)
仔细聊聊L012
第一感觉就是东西太方便了,就感觉小小一颗应有尽有,下面就跟着我的脚步来盘点一点有哪些让人眼前一亮的 future!
电源范围这些不必说,看一下 ISP,ICP,IAP 这些方便的功能:
|
|
|
|
|
|
|---|---|---|---|---|
| ICP |
|
|
|
|
| ISP |
|
|
|
|
| IAP |
|
|
|
|
实际推荐方案
-
初次烧录 → ICP 方式(SWD 烧录 BootLoader + 主程序)。 -
后续维护 → ISP 模式(UART1 接 PC 工具)。 -
在线 OTA / 模块升级 → IAP 机制(主程序通过通信口接收数据并写入备用区)。
可以看到做到了实验,工程,以及日后的升级的全流程,总之给的是很全的。
终于来到的DMA
可以先看一下框图:
AHB 和 APB 兵分俩路,至于 DMA 是又设计了一个单独的总线,说起这个 DMA,那真的很好了,因为之前有用户就问有没有这个东西;原因是假如没有,那所有的数据处理都是需要 CPU 唤醒的,就算低功耗再好,Core 运行也还是在耗能,如果是 DMA 的话,完全就可以让低功耗这个事情再好一点,其次就是:
自带的外设是可以较高的速率运行的,那数据 IO 速度 这块也是瓶颈,分担一部分。
简配版DSP
外设强不一定是真的强,因为现在是一个算法主导的算法,然后对于一些高级的运算,其实MCU 来说是一个沉重的负担,那就有外挂独立 IP 的这种做法;也就是这次加入的两个新 IP:
EAU = 快速除法器 + 开方器
CORDIC = 硬件版三角函数 / 向量旋转机
两者结合,让 CW32L012 在 无 FPU 的 M0+ 核心 上具备“小型 DSP”的实时运算能力。
其中EAU 是一个简单的 硬件除法与平方根计算单元,能执行:有符号/无符号除法(DIV),平方根(SQRT);这些在 M0+ 内核中原本要靠软件算法实现,耗时几十到上百个周期,而 EAU 用硬件流水方式能在几微秒内完成。
常见用途有:控制算法(PID、位置环、矢量控制);几何距离、幅值、能量计算;快速归一化(如 sqrt(x²+y²))。
CORDIC迭代旋转算法
CORDIC 是一种经典的迭代旋转算法,通过一系列移位与加减操作实现三角函数、双曲函数、平方根与向量旋转等运算;它特别适合在无乘法器的 MCU 上实现 sin、cos、tan、atan、sinh、cosh 等;CW32L012 把这一算法固化为硬件协处理器,无需软件循环。
比如三角函数计算(PWM 调制、位置控制);坐标变换(笛卡尔 ↔ 极坐标);向量旋转(如 Clarke/Park 变换)。
在没有 FPU 的 Cortex-M0+ 上,CORDIC+EAU 让 MCU 拥有接近 DSP 的实时算力。
两个小外设的引入可以比传统 math.h 快数十倍;不依赖浮点库,节省 Flash;精度可达 ±1 LSB;支持中断、DMA 联动(可硬件级流处理)。
实际案例
比如从两个直角坐标分量 → 得到极坐标(幅值 + 相位);也就是 “CORDIC + EAU 协处理器协同计算 √(x²+y²) 与 θ = atan(y/x)” 的硬件执行机制
总体目标与原理
假设我们有一个向量:
希望计算:
模块分工
|
|
|
|
|---|---|---|
| EAU |
|
|
| CORDIC |
|
|
二者的功能在结构上相互补充:
┌────────────┐
x → │ │
y → │ CORDIC │──► θ = atan(y/x)
│ │
└────┬───────┘
│
▼
(x²+y²)
│
┌────▼────┐
│ EAU │──► r = √(x²+y²)
└─────────┘
CORDIC 工作机制详解(旋转法)
CORDIC 的数学核心是“坐标旋转法”:
其中 控制旋转方向,经过 N 次迭代后: 接近旋转后的坐标; 即为所需角度或相位。
硬件意义:通过移位+加减替代乘法;每步迭代占一个时钟;固定系数 ,即幅值会略缩小,硬件已补偿。
EAU 工作机制
EAU 的平方根算法是逐次逼近法(牛顿迭代)或非恢复除法法:
在硬件中以并行移位 + 比较器链实现,因此平方根计算(32bit)仅需 16~32 周期。
协同运算(CORDIC + EAU)
假设:
x = 0.6
y = 0.8
目标:
r = sqrt(0.6² + 0.8²) = 1.0
θ = atan(0.8/0.6) ≈ 53.13°
计算角度 θ — 使用 CORDIC
CORDIC->X = float_to_q31(0.6);
CORDIC->Y = float_to_q31(0.8);
CORDIC->CSR = (MODE_VECTORING | FUNC_ATAN) | START;
while (CORDIC->CSR & BUSY);
theta = q31_to_deg(CORDIC->Z); // 输出角度(°)
结果:θ ≈ 53.1°
计算模长 r — 使用 EAU
EAU->DIVIDEND = x*x + y*y; // 输入平方和
EAU->CSR = SQRT_MODE | START;
while (EAU->CSR & BUSY);
r = EAU->QUOTIENT; // 输出 √(x²+y²)
结果:r = 1.000
输出结果
θ = 53.13° r = 1.000
数据流图(协同计算)
┌────────────────────────────────────────────┐
│ CORDIC 协处理器 │
│--------------------------------------------│
│ 输入:X=0.6, Y=0.8 │
│ 1. 迭代旋转法求 atan(Y/X) → θ=53.13° │
│ 2. 同时得出 cosθ=0.6, sinθ=0.8 │
└────────────────────────────────────────────┘
│
▼
┌────────────┐
│ EAU │
│------------│

│ 计算 X²+Y² │
│ 计算 √( ) → r │
└────────────┘
│
▼
极坐标结果 (r, θ)
=== Numerical Results ===
Input vector: (x0, y0) = (0.6, 0.8)
CORDIC iterations: N = 20, Gain K ≈ 0.6072529350
Estimated r (CORDIC) = 1.000000000
Reference r (hypot) = 1.000000000
Absolute error (r) = 9.204e-14
Estimated θ (CORDIC) = 0.927294789 rad = 53.130078°
Reference θ (atan2) = 0.927295218 rad = 53.130102°
Absolute error (θ) = 4.287e-07 rad
-
迭代索引 i → x_i -
迭代索引 i → y_i(可看到 y 被逐步压到 0) -
迭代索引 i → θ_i(度) -
(x_i, y_i) 在平面上的收敛轨迹(向 x 轴旋转并收敛)
上面打印了与 math.hypot / atan2 的数值对比,误差在 1e-7 rad 量级,说明实现正确且收敛良好。
新的定时器:霍尔传感器
除了一堆标配以外:
这个 **24 位递增计数霍尔传感器专用定时器(HALLTIM)**,专为电机霍尔信号测量与换向设计,可对三路霍尔信号进行捕获、滤波、异或组合、以及产生触发输出与 PWM 信号。
用途是:通过 3 路霍尔信号检测转子位置、速度、方向;输出同步 PWM 或换向触发脉冲;通过 DMA 实现自动数据搬运;应用于 BLDC、PMSM、步进电机控制等。
HALLTIM 的内部结构如下(来自功能框图):
CH1S ──┐ ┌─────► 一阶滤波 (FLT1)
CH2S ──┼──► XOR ├────► 二阶滤波 (FLT2)
CH3S ──┘ │
▼
┌──────────┐
│ 计数器CNT│──► HALLTIM_OUT(PWM/捕获/异或)
└──────────┘
│
┌──────────┐
│ 自动重载ARR│
└──────────┘
功能模块
|
|
|
|---|---|
| 三路输入通道 CH1~CH3 |
|
| 一级滤波(可开关) |
|
| 二级滤波(可设阈值) |
|
| 捕获逻辑 |
|
| XOR 逻辑 |
|
| 计数器(24 位) |
|
| PWM 输出比较 |
|
| 触发输出(TRGO) |
|
| DMA 支持 |
|
计数时钟源为 PCLK,可通过 CR 寄存器 DIV 位域设置 1/2/4/8 分频得到计数时钟。
IIC新变化
IIC 我之前也写过了,但是这次的外设加了不少新功能:IIC支持热拔插吗?(附有详细CW32 IIC协议解读)
支持系统管理总线(SMBus)协议第 3 版
这个搞电源的不会不熟悉,现在可以直接直接了,也就是说一颗小 MCU 就可以当电源的大脑了。
|
|
|
|
|---|---|---|
| 设计初衷 |
|
|
| 标准制定者 |
|
|
| 线数 |
|
|
| 电气层 |
|
|
| 协议层差异 |
|
|
主机FIFO
为什么要在 I²C 主机中加入 FIFO?
I²C 是一种严格时序的串行协议,数据一旦开始传输,主机必须在每个 SCL 周期内按时提供数据位或读取返回位—而 MCU 的 CPU 速度远高于总线,但 CPU 不能时时轮询等待每个字节,否则性能极差。
所以加入 FIFO 的根本目的就是:
让 I²C 模块具备“自我缓冲”能力,在不打断 CPU 的情况下连续完成传输。
FIFO 的作用机制(以主机为例)
|
|
|
|
|---|---|---|
| 命令/发送 FIFO |
|
|
| 接收 FIFO |
|
|
FIFO 是为了让 I²C 主机控制器具备“流式自动执行”的能力,减少 CPU 干预,提高可靠性与总线利用率(所有的 FIFO 都是这样的作用)。
新的模拟外设:DAC
可以与 ADC 联动(闭环/校准常用)
ADC 的内部通道包含 DAC_OUT1/2,可以直接读回 DAC 输出,做线性度/漂移/环路验证;配合 ADC 的序列模式与 DMA,能形成全片内自测链。
为了系统稳定而生的低电压检测器(LVD)模块
低电压检测器(LVD)用于监测 VDDA 电源电压或外部引脚输入电压,当被监测电压与 LVD 阈值的比较结果满 足触发条件时,将产生 LVD 中断或复位信号,通常用于处理一些紧急任务。
监测电压源 ─► 比较器 ─► 数字滤波 ─► 条件逻辑(LEVEL/RISE/FALL)
│
├─► LVD 中断(ACTION=0)
└─► 系统复位(ACTION=1)
我能想到的是设置低阈值 + 复位模式;在掉电边缘可安全停止 Flash 操作。
可能硬件设计要注意一下。
隆重欢迎我们的新小朋友:OPA
大家都知道我是摸这些东西的,看见 OP 还是蛮开心的,没想到 L012 走向了一颗混合的模拟信号 MCU,使用的边界又被扩宽不少。
还有设计放大倍数,小信号有福了
初始胡误差有点大,得好好补偿。
几个应用场合
DAC → OPA → ADC 闭环
用于内部自检或信号放大。
DAC_OUT → OPA_IN+ → OPA_OUT → ADC_INx
→ 实现可编程增益或滤波放大。
传感器放大器
外部传感器信号经 OPA 放大后输入 ADC,可设置 OPA 工作在缓冲或反相模式(由外部电阻反馈决定)。
比较器前级 / 滤波前置
将低噪声信号调理后送入 VC(Voltage Comparator)或 LVD。
两个ADC
差点忘了这个:
集成了 2 路独立的 12 位 ADC,其关键特性如下:
|
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
采样模式与触发机制
CW32L012 的 ADC 支持多种采样模式:
|
|
|
|---|---|
| 单次模式(Single) |
|
| 连续模式(Continuous) |
|
| 序列模式(Scan) |
|
| 差分/单端模式 |
|
外部触发源
ADC 可由多种 定时器事件 自动触发启动:
高级定时器 ATIM 的 TRGO、TRGO2 或 OC1–OC6 上升沿
通用定时器 GTIM1/2 的 OC1–OC4 或 TRGO 上升沿
触发控制寄存器字段示例:
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这种灵活性使得 ADC 能与 PWM、采样定时或同步控制任务实现硬件级对齐。
模拟看门狗功能
ADC 内置模拟看门狗比较逻辑,可监测一个或多个通道是否超出设定电压范围:
VLOW ≤ Vin ≤ VHIGH → 正常
Vin < VLOW 或 Vin > VHIGH → 触发中断 (AWDL/AWDH)
后记
想不到啊,就是一个 M0+的 MCU,这么多外设这对吗?外设增加的太快了,而且离一颗芯片就一个仪器的愿望更近了。对于一个纯靠编程的 MCU,自然少不了来自原厂强大的支持,那接下来就是 MCU 直播专场。