esp32简易信号发生器
·
目标
- 输出引脚:固定使用 GPIO25 输出信号
- 波形生成:支持正弦波、方波、三角波三种波形,输出频率范围 0.01Hz~55000Hz
- 交互方式:通过串口输入字符串 + 回车确认指令
- 直流电平输出:输入 dax(x 为 0~255),输出对应 0~3.3V 固定电平
- 参数独立性:波形类型设置与频率设置相互独立,互不影响
指令对照表
输入指令后回车确认生效
| 指令 | 功能说明 | 使用示例 |
|---|---|---|
| s | 切换为正弦波 | 输入s后回车 |
| a | 切换为三角波 | 输入a后回车 |
| q | 切换为方波 | 输入q后回车 |
| 数字 / 小数 | 设置输出频率 | 100、2500.5、0.01 |
| da+数值 | 输出直流固定电平(数值0~255) | da128、da 200 |
main.cpp
#include <Arduino.h>
#include "driver/dac.h"
#include "math.h"
// ================= DAC =================
#define DAC_CH DAC_CHANNEL_1
// ================= LUT =================
#define LUT_SIZE 256
uint8_t sine_lut[LUT_SIZE];
uint8_t tri_lut[LUT_SIZE];
//信号类型 正弦,三角,方波
enum WaveType { SINE, TRI, SQUARE };
//信号生成方式 DDS 生成 ,CW生成, 直流输出
enum Mode { MODE_DDS, MODE_CW, MODE_DC };
volatile WaveType wave = SINE;
volatile Mode mode = MODE_DDS;
volatile float current_freq = 1.0;
// ================= DC VALUE =================
volatile uint8_t dc_value = 0;
// ================= DDS =================
volatile uint32_t phase_acc = 0;
volatile uint32_t phase_inc = 0;
// ================= TIMER =================
hw_timer_t *timer = NULL;
bool timer_inited = false;
// ================= CW =================
// 定义DAC载波(CW)配置结构体变量cw_cfg
dac_cw_config_t cw_cfg = {
.en_ch = DAC_CHANNEL_1, // 选择输出通道:通道1(对应GPIO25)
.scale = DAC_CW_SCALE_1, // 输出幅度缩放:等级1(调节波形幅值大小)
.phase = DAC_CW_PHASE_0, // 波形初始相位:0°
.freq = 1000, // 波形输出频率:1000Hz(1kHz)
.offset = 4 // 波形直流偏移量:4个DAC单位
};
// ================= ISR =================
void IRAM_ATTR onTimer() {
if (mode != MODE_DDS) return;
phase_acc += phase_inc;
uint8_t idx = phase_acc >> 24;
uint8_t out = 0;
switch (wave) {
case SINE: out = sine_lut[idx]; break;
case TRI: out = tri_lut[idx]; break;
case SQUARE: out = (phase_acc & 0x80000000) ? 255 : 0; break;
}
dac_output_voltage(DAC_CH, out);
}
// ================= LUT =================
void buildLUT() {
for (int i = 0; i < LUT_SIZE; i++) {
sine_lut[i] = (sin(2 * PI * i / LUT_SIZE) + 1.0) * 127.5;
if (i < 128)
tri_lut[i] = i * 2;
else
tri_lut[i] = 255 - (i - 128) * 2;
}
}
// ================= TIMER =================
void initTimer() {
if (timer_inited) return;
timer = timerBegin(0, 80, true);
timerAttachInterrupt(timer, &onTimer, true);
timerAlarmWrite(timer, 125, true);
timer_inited = true;
}
// ================= STOP =================
void stopAll() {
dac_cw_generator_disable();
if (timer_inited) timerAlarmDisable(timer);
}
// ================= ENGINE =================
void restartEngine() {
stopAll();
if (mode == MODE_DDS) {
initTimer();
timerAlarmEnable(timer);
}
else if (mode == MODE_CW) {
dac_cw_generator_config(&cw_cfg);
dac_cw_generator_enable();
}
else if (mode == MODE_DC) {
dac_output_voltage(DAC_CH, dc_value);
}
}
// ================= DDS =================
void startDDS(float f) {
mode = MODE_DDS;
phase_inc = (uint32_t)((f * 4294967296.0) / 8000.0);
restartEngine();
}
// ================= CW =================
void startCW(float f) {
mode = MODE_CW;
cw_cfg.freq = (uint32_t)f;
restartEngine();
}
// ================= DC =================
void startDC(uint8_t v) {
mode = MODE_DC;
dc_value = v;
restartEngine();
Serial.printf("[DC] output = %d\n", dc_value);
}
// ================= ROUTER =================
void setFreq(float f) {
if (f < 0.01) f = 0.01;
if (f > 55000) f = 55000;
current_freq = f;
if (f < 130.0) startDDS(f);
else startCW(f);
}
// ================= WAVE =================
void setWave(char c) {
if (c == 's') wave = SINE;
else if (c == 'a') wave = TRI;
else if (c == 'q') wave = SQUARE;
if (current_freq < 130.0) {
mode = MODE_DDS;
restartEngine();
}
Serial.printf("[WAVE] %c | FREQ %.3f Hz\n", c, current_freq);
}
// ================= SERIAL PARSER =================
void handleInput(String s) {
s.trim();
// DC 模式:DA 100 或 DA100
if (s.startsWith("DA") || s.startsWith("da")) {
s.remove(0, 2);
s.trim();
int v = s.toInt();
if (v < 0) v = 0;
if (v > 255) v = 255;
startDC((uint8_t)v);
return;
}
// 单字符波形
if (s.length() == 1) {
char c = s[0];
if (c == 's' || c == 'a' || c == 'q') {
setWave(c);
return;
}
}
// 频率
float f = s.toFloat();
if (f > 0) {
setFreq(f);
Serial.printf("[FREQ] %.3f Hz\n", f);
}
}
// ================= SETUP =================
void setup() {
Serial.begin(115200);
dac_output_enable(DAC_CH);
buildLUT();
initTimer();
setFreq(10);
Serial.println("\n=== PRO FUNCTION GENERATOR ===");
Serial.println("s/a/q = waveform");
Serial.println("number = frequency");
Serial.println("da 100 = DC output");
}
// ================= LOOP =================
void loop() {
if (Serial.available()) {
String s = Serial.readStringUntil('\n');
handleInput(s);
}
}
更多推荐



所有评论(0)