基于 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

浙公网安备 33010602011771号