Размер видео: 1280 X 720853 X 480640 X 360
Показать панель управления
Автовоспроизведение
Автоповтор
#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 11LiquidCrystal 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 8const String menuText[] = {"X1Hz ", "X10Hz ", "X100Hz ","X1kHz ", "X10kHz ", "X100kHz", "X1MHz ", "Waveform "};const String waveText[] = {"SIN", "TRI", "SQR"};#define EEPROM_ADDRESS 0#define EEPROM_MAGIC 0x0BAD0DADtypedef 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 11000000volatile 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 }
#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
}