Générateur de fonction avec un module AD9833

Поделиться
HTML-код
  • Опубликовано: 9 янв 2025

Комментарии • 1

  • @ve2ydq345
    @ve2ydq345  7 месяцев назад +4

    #include
    #include
    #include "AD9833.h"
    #include "Rotary.h"
    #define R_A 2
    #define R_B 3
    #define SWITCH 4
    #define AD9833_FSYNC 10
    #define AD9833_SCLK 13
    #define AD9833_SDATA 11
    LiquidCrystal lcd(A0, 9, 8, 7, 6, 5);
    AD9833 sigGen(AD9833_FSYNC, 25010000);
    Rotary encoder(R_A, R_B);
    enum MenuEnum { X1, X10, X100, X1K, X10K, X100K, X1M, WAVEFORM };
    enum WaveEnum { SINE, TRANGLE, SQUARE };
    #define MENU_TEXT_LEN 8
    const String menuText[] = {"X1Hz ", "X10Hz ", "X100Hz ","X1kHz ", "X10kHz ", "X100kHz", "X1MHz ", "Waveform "};
    const String waveText[] = {"SIN", "TRI", "SQR"};
    #define EEPROM_ADDRESS 0
    #define EEPROM_MAGIC 0x0BAD0DAD
    typedef struct {
    uint32_t magic;
    MenuEnum menuState;
    WaveEnum waveState;
    long frequency;
    } EEPROM_DATA;
    EEPROM_DATA EepromData;
    #define EEPROM_UPDATE_TIME 10000
    unsigned long eepromTimeout = 0;
    bool eepromUpdate = false;
    #define FREQ_MAX 11000000
    volatile bool updateDisplay = false;
    void setup()
    {
    pinMode(R_A, INPUT_PULLUP);
    pinMode(R_B, INPUT_PULLUP);
    pinMode(SWITCH, INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(R_A), encChange, CHANGE);
    attachInterrupt(digitalPinToInterrupt(R_B), encChange, CHANGE);
    readEepromData();
    displayFrequency();
    displayMenu();
    displayWaveform();
    sigGen.reset(1);
    sigGen.setFreq(EepromData.frequency);
    sigGen.setPhase(0);
    sigGen.setFPRegister(1);
    sigGen.setFreq(EepromData.frequency);
    sigGen.setPhase(0);
    sigGen.setFPRegister(0);
    sigGen.mode((int)EepromData.waveState);
    sigGen.reset(0);
    eepromTimeout = millis() + EEPROM_UPDATE_TIME;
    }
    void loop()
    {
    if (testButton(true))
    {
    EepromData.menuState = (EepromData.menuState == WAVEFORM) ? X1 : (MenuEnum)((int)EepromData.menuState + 1);
    eepromUpdate = true;
    updateDisplay = true;
    }
    {
    displayFrequency();
    displayMenu();
    displayWaveform();
    updateDisplay = false;
    }
    if (millis() > eepromTimeout)
    {
    if (eepromUpdate)
    {
    writeEepromData();
    eepromUpdate = false;
    }
    eepromTimeout = millis() + EEPROM_UPDATE_TIME;
    }
    }
    bool testButton(bool waitForRelease)
    {
    bool pressed = false;
    if (digitalRead(SWITCH) == LOW)
    {
    delay(100);
    pressed = true;
    while (waitForRelease && digitalRead(SWITCH) == LOW)
    {
    yield();
    }
    }
    return pressed;
    }
    void encChange()
    {
    unsigned char state = encoder.process();
    delay(50);
    if (state != DIR_NONE)
    {
    switch (EepromData.menuState)
    {
    case X1: updateFrequency(state,1); break;
    case X10: updateFrequency(state,10); break;
    case X100: updateFrequency(state,100); break;
    case X1K: updateFrequency(state,1000); break;
    case X10K: updateFrequency(state,10000); break;
    case X100K: updateFrequency(state,100000); break;
    case X1M: updateFrequency(state,1000000); break;
    case WAVEFORM: updateWaveform(state); break;
    }
    }
    }
    void updateFrequency(unsigned char state, long stepValue)
    {
    bool update = false;
    long old = EepromData.frequency;
    if (state == DIR_CW)
    {
    EepromData.frequency = min(EepromData.frequency + stepValue,FREQ_MAX);
    }
    else
    {
    EepromData.frequency = max(EepromData.frequency - stepValue,0);
    }
    if (old != EepromData.frequency)
    {
    sigGen.setFreq(EepromData.frequency);
    eepromUpdate = true;
    updateDisplay = true;
    }
    }
    void updateWaveform(unsigned char state)
    {
    if (state == DIR_CW)
    {
    EepromData.waveState = (EepromData.waveState == SQUARE) ? SINE : (WaveEnum)((int)EepromData.waveState + 1);
    }
    else
    {
    EepromData.waveState = (EepromData.waveState == SINE) ? SQUARE : (WaveEnum)((int)EepromData.waveState - 1);
    }
    sigGen.mode((int)EepromData.waveState);
    eepromUpdate = true;
    updateDisplay = true;
    }
    void displayFrequency()
    {
    lcd.setCursor(0, 0);
    lcd.print(formatNumber(EepromData.frequency,"F=","Hz",16));
    }
    void displayMenu()
    {
    lcd.setCursor(0, 1);
    lcd.print(padString(menuText[(int)EepromData.menuState],MENU_TEXT_LEN));
    }
    void displayWaveform()
    {
    lcd.setCursor(13, 1);
    lcd.print(waveText[(int)EepromData.waveState]);
    }
    String formatNumber(long number, String prefix, String postfix, int pad)
    {
    String s = "";
    bool space = true;
    for (uint8_t i = 0; i < 8; i++)
    {
    if ((i==3 || i==6) && !space && number > 0)
    {
    s = String(',') + s;
    }
    if (number > 0 || i == 0)
    {
    s = String((char)((number % 10) + 48)) + s;
    space = false;
    }
    else
    {
    space = true;
    }
    number = number / 10;
    }
    s = prefix + s + postfix;
    return padString(s, pad);
    }
    String padString(String s, int pad)
    {
    String sOut = String(s);
    int len = pad - s.length();
    for (uint8_t i = 0; i < len; i++)
    {
    sOut += ' ';
    }
    return sOut;
    }
    void writeEepromData(void)
    {
    EEPROM.put(EEPROM_ADDRESS,EepromData);
    }
    void readEepromData(void)
    {
    #ifndef RESET_EEPROM
    EEPROM.get(EEPROM_ADDRESS,EepromData);
    if (EepromData.magic != EEPROM_MAGIC)
    {
    #endif
    EepromData.magic = EEPROM_MAGIC;
    EepromData.menuState = WAVEFORM;
    EepromData.waveState = SINE;
    EepromData.frequency = 1000;
    writeEepromData();
    #ifndef RESET_EEPROM
    }
    #endif
    }