基于 TMS320F28335 的 DA 输出三角波

一、一个关键点

F28335 没有真正的 DAC(数模转换器)

正确做法:
使用 ePWM + 影子寄存器 + 软件三角波算法 + 外部 RC 滤波
→ 用 PWM 占空比 模拟 DA 输出

这是 F28335 做 DA 输出的唯一官方推荐方式


二、总体实现方案

┌──────────────────────────────────────┐
│         TMS320F28335                │
│                                      │
│  CPU 计算三角波数值(0~1500)         │
│              │                       │
│              ▼                       │
│  EPwm1Regs.CMPA.half.CMPA = value   │
│              │                       │
│              ▼                       │
│  ePWM1A ──────► GPIO0 (PWM 输出)     │
│                                      │
└──────────────────────────────────────┘
                  │
                  ▼
           RC 低通滤波器
                  │
                  ▼
           模拟三角波电压

三、三角波算法(核心)

1、三角波数学模型

三角波周期 = 2 × N × T_pwm
参数 含义
N 三角波点数
T_pwm PWM 周期

2、三角波数值生成(推荐)

#define TRIANGLE_POINTS 100
#define PWM_PERIOD      1500

static Uint16 triangle_table[TRIANGLE_POINTS];
static Uint16 index = 0;

void TriangleWave_Init(void)
{
    int i;
    for (i = 0; i < TRIANGLE_POINTS/2; i++)
    {
        triangle_table[i] = (PWM_PERIOD * i) / (TRIANGLE_POINTS/2);
    }
    for (; i < TRIANGLE_POINTS; i++)
    {
        triangle_table[i] = PWM_PERIOD -
            (PWM_PERIOD * (i - TRIANGLE_POINTS/2)) / (TRIANGLE_POINTS/2);
    }
}

四、ePWM 配置(F28335 关键)

1、PWM 初始化(向上计数)

#include "DSP28x_Project.h"

void EPwm1_Init(void)
{
    EALLOW;

    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
    EDIS;

    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // 向上计数
    EPwm1Regs.TBPRD = 1500;                    // PWM 周期
    EPwm1Regs.TBPHS.all = 0;
    EPwm1Regs.TBCTR = 0;

    EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;

    EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET;         // 零点置高
    EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;       // CMPA 清零

    EPwm1Regs.CMPA.half.CMPA = 0;

    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
    EDIS;
}

五、主循环 / 定时器更新 PWM

推荐:用 CPU Timer 0 更新

interrupt void cpu_timer0_isr(void)
{
    EPwm1Regs.CMPA.half.CMPA = triangle_table[index];

    index++;
    if (index >= TRIANGLE_POINTS)
        index = 0;

    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

或直接在 while(1) 中更新

void main(void)
{
    InitSysCtrl();
    InitPieCtrl();
    InitPieVectTable();

    InitEPwm1Gpio();
    EPwm1_Init();
    TriangleWave_Init();

    ConfigCpuTimer(&CpuTimer0, 150, 100); // 100us 更新
    StartCpuTimer0();

    EINT;
    ERTM;

    while (1)
    {
        EPwm1Regs.CMPA.half.CMPA = triangle_table[index];
        index = (index + 1) % TRIANGLE_POINTS;
        DELAY_US(100);
    }
}

六、RC 滤波设计(决定波形质量)

1、推荐参数

参数
PWM 频率 50 kHz
截止频率 fc ≤ 1 kHz
R 1 kΩ
C 0.1 µF
PWM ── R ──┬── Vout
           │
           C
           │
          GND

2、频率估算

fc = 1 / (2πRC) ≈ 1.6 kHz

三角波频率建议 ≤ 500 Hz
纹波 < 20 mV


七、示例(可烧录)

#include "DSP28x_Project.h"

#define PWM_PERIOD 1500
#define POINTS 100

Uint16 tri[POINTS];
Uint16 idx = 0;

void InitTriangle(void)
{
    int i;
    for (i = 0; i < POINTS/2; i++)
        tri[i] = (PWM_PERIOD * i) / (POINTS/2);
    for (; i < POINTS; i++)
        tri[i] = PWM_PERIOD - (PWM_PERIOD * (i - POINTS/2)) / (POINTS/2);
}

interrupt void Timer0_ISR(void)
{
    EPwm1Regs.CMPA.half.CMPA = tri[idx++];
    if (idx >= POINTS) idx = 0;

    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

void main(void)
{
    InitSysCtrl();
    InitPieCtrl();
    InitPieVectTable();

    EALLOW;
    PieVectTable.TINT0 = &Timer0_ISR;
    EDIS;

    InitEPwm1Gpio();
    EPwm1_Init();
    InitTriangle();

    ConfigCpuTimer(&CpuTimer0, 150, 100);
    StartCpuTimer0();

    IER |= M_INT1;
    EINT; ERTM;

    while (1);
}

参考代码 基于F28335的DA输出三角波 www.youwenfan.com/contentcnv/72688.html

八、精度与限制

项目 说明
分辨率 11-bit(1500 级)
线性度 中等
纹波 依赖 RC
带宽 < 1 kHz
温漂 中等

适合:电源 ramp、偏置、测试信号
不适合:精密仪器、音频、计量级 DA

posted @ 2026-05-27 16:13  吴逸杨  阅读(27)  评论(0)    收藏  举报