- DDS 함수 생성기 란 무엇입니까?
- AD9833 함수 발생기 IC의 작동 이해
- AD9833 기반 함수 발생기를 구축하는 데 필요한 구성 요소
- AD9833 기반 함수 발생기-회로도
- AD9833 기반 함수 발생기-Arduino 코드
- AD9833 기반 함수 발생기 테스트
- 추가 향상
다른 전자 회로를 사용하고 싶은 저와 같은 전자 애호가라면 적절한 함수 생성기가 때때로 필수가됩니다. 그러나 이러한 기본 장비는 많은 비용이들 수 있기 때문에 하나를 소유하는 것은 문제입니다. 자신의 테스트 장비를 구축하는 것은 더 저렴할뿐만 아니라 지식을 향상시키는 좋은 방법이기도합니다.
따라서이 기사에서는 출력에서 최대 주파수가 12MHz 인 사인파, 사각 파 및 삼각파를 생성 할 수 있는 Arduino 및 AD9833 DDS 함수 생성기 모듈 로 간단한 신호 생성기 를 구축 할 것 입니다. 마지막으로 오실로스코프를 사용하여 출력 주파수를 테스트 할 것입니다.
우리는 이전에 기본 아날로그 회로를 사용하여 단순 사인파 생성기, 구형파 생성기 및 삼각파 생성기를 구축했습니다. 기본적인 파형 발생기 회로를 찾고 있다면이를 확인할 수 있습니다. 또한 AD9833 모듈을 사용하지 않고 더 저렴한 Arduino 함수 생성기를 구축하려면 DIY Arduino Waveform Generator Project를 확인할 수 있습니다.
DDS 함수 생성기 란 무엇입니까?
이름에서 알 수 있듯이 함수 발생기는 설정시 특정 주파수로 특정 파형을 출력 할 수있는 장치입니다. 예를 들어, 출력 주파수 응답을 테스트하려는 LC 필터가 있다고 가정하면 함수 발생기를 사용하여 쉽게 수행 할 수 있습니다. 원하는 출력 주파수와 파형을 설정하기 만하면 응답을 테스트하기 위해 크랭크를 내리거나 올릴 수 있습니다. 이것은 하나의 예일 뿐이며 목록이 진행됨에 따라 더 많은 작업을 수행 할 수 있습니다.
DDS는 Direct Digital Synthesis의 약자입니다. 디지털-아날로그 변환기 (DAC)를 사용하여 처음부터 신호를 생성 하는 파형 발생기 유형입니다. 이 방법은 특히 사인파를 생성하는 데 사용됩니다. 그러나 우리가 사용하는 IC는 사각 파 또는 삼각파 신호를 생성 할 수 있습니다. DDS 칩 내부에서 발생하는 작업은 디지털이므로 주파수를 매우 빠르게 전환하거나 한 신호에서 다른 신호로 매우 빠르게 전환 할 수 있습니다. 이 장치는 주파수 스펙트럼이 넓은 미세 주파수 분해능을 가지고 있습니다.
AD9833 함수 발생기 IC의 작동 이해
프로젝트의 핵심은 아날로그 장치로 설계 및 개발 된 AD9833 프로그래밍 가능 파형 발생기 IC입니다. 최대 주파수가 12MHz 인 사인파, 삼각파 및 구형파를 생성 할 수있는 저전력, 프로그래밍 가능 파형 발생기 입니다. 소프트웨어 프로그램만으로 출력 주파수와 위상을 변경할 수있는 매우 독특한 IC입니다. 3 선 SPI 인터페이스가 있기 때문에이 IC와의 통신이 매우 간단하고 쉬워집니다. 이 IC의 기능 블록 다이어그램은 다음과 같습니다.
이 IC의 작동은 매우 간단합니다. 위의 기능 블록 다이어그램을 살펴보면 0에서 2π까지 사인파의 가능한 모든 디지털 값을 저장하는 역할을하는 위상 누산기가 있음을 알 수 있습니다. 다음으로, 나중에 직접 진폭으로 매핑 할 수있는 위상 정보를 변환하는 역할을하는 SIN ROM이 있습니다. SIN ROM은 디지털 위상 정보를 룩업 테이블에 대한 주소로 사용하고 위상 정보를 진폭으로 변환합니다. 마지막으로, SIN ROM에서 디지털 데이터를 수신하고이를 해당 아날로그 전압으로 변환하는 역할을하는 10 비트 디지털-아날로그 변환기가 있습니다. 즉, 출력에서 얻은 것입니다. 출력에는 약간의 소프트웨어 코드로 켜거나 끌 수있는 스위치도 있습니다. 이에 대해서는 기사 뒷부분에서 설명하겠습니다.위에 표시된 세부 정보는 IC 내부에서 발생하는 일을 매우 잘려진 버전이며, 위에서 보는 대부분의 세부 정보는 AD9833 데이터 시트에서 가져온 것이므로 추가 정보를 확인할 수도 있습니다.
AD9833 기반 함수 발생기를 구축하는 데 필요한 구성 요소
AD9833 기반 함수 발생기를 구축하는 데 필요한 구성 요소는 다음과 같습니다. 우리는이 회로를 매우 일반적인 구성 요소로 설계하여 복제 프로세스를 매우 쉽게 만듭니다.
- Arduino Nano-1
- AD9833 DDS 함수 발생기-1
- 128 X 64 OLED 디스플레이-1
- 일반 로터리 엔코더-1
- DC 배럴 잭-1
- LM7809 전압 레귤레이터-1
- 470uF 커패시터-1
- 220uF 커패시터-1
- 104pF 커패시터-1
- 10K 저항-6
- 택 타일 스위치-4
- 나사 고정 터미널 5.04mm-1
- 암 헤더-1
- 12V 전원-1
AD9833 기반 함수 발생기-회로도
AD9833 및 Arduino 기반 함수 발생기에 대한 전체 회로도 가 아래에 나와 있습니다.
우리는 원하는 주파수를 생성하기 위해 Arduino와 함께 AD9833 을 사용할 것 입니다. 이 섹션에서는 회로도의 도움으로 모든 세부 사항을 설명합니다. 회로에서 일어나는 일에 대한 간략한 개요를 제공하겠습니다. AD9833 모듈 부터 시작하겠습니다.. AD9833 모듈은 함수 발생기 모듈이며 회로도에 따라 Arduino와 연결됩니다. 회로에 전원을 공급하기 위해 적절한 디커플링 커패시터가있는 LM7809 전압 레귤레이터 IC를 사용하고 있습니다. 이는 공급 노이즈가 출력 신호를 방해하여 원하지 않는 출력을 초래할 수 있기 때문에 필요합니다. 늘 그렇듯이 Arduino는이 프로젝트의 두뇌 역할을합니다. 설정된 주파수 및 기타 중요한 정보를 표시하기 위해 128 X 64 OLED 디스플레이 모듈을 연결했습니다. 주파수 범위를 변경하기 위해 세 개의 스위치를 사용하고 있습니다. 첫 번째는 주파수를 Hz로 설정하고 두 번째는 출력 주파수를 KHz로 설정하고 세 번째는 주파수를 MHz로 설정합니다. 또한 출력을 활성화하거나 비활성화하는 데 사용할 수있는 또 다른 버튼이 있습니다. 마지막으로 로터리 엔코더가 있습니다.풀업 저항을 연결해야합니다. 그렇지 않으면 풀링 방법에서 버튼 누름 이벤트를 확인하기 때문에 해당 스위치가 작동하지 않습니다. 로터리 엔코더는 주파수를 변경하는 데 사용되며 로터리 엔코더 내부의 촉각 스위치는 설정된 파형을 선택하는 데 사용됩니다.
AD9833 기반 함수 발생기-Arduino 코드
이 프로젝트에 사용 된 전체 코드는이 페이지 하단에서 찾을 수 있습니다. 필요한 헤더 파일과 소스 파일을 추가 한 후 Arduino 파일을 직접 컴파일 할 수 있습니다. 아래 링크에서 ad9833 Arduino 라이브러리 및 기타 라이브러리를 다운로드 하거나 보드 관리자 방법을 사용하여 라이브러리를 설치할 수 있습니다.
- Bill Williams의 AD9833 라이브러리 다운로드
- Adafruit의 SSD1306 OLED 라이브러리 다운로드
- Adafruit GFX 라이브러리 다운로드
ino 의 코드에 대한 설명입니다 . 파일 은 다음과 같습니다. 먼저 필요한 모든 라이브러리를 포함하여 시작합니다. AD9833 DDS 모듈 용 라이브러리 는 먼저 OLED 용 라이브러리가 이어지며 일부 계산에는 수학 라이브러리가 필요합니다.
#include // AD9833 모듈 용 라이브러리 #include
다음으로 버튼, 스위치, 로터리 인코더 및 OLED에 필요한 모든 입력 및 출력 핀을 정의합니다.
#define SCREEN_WIDATA_PINH 128 // OLED 디스플레이 너비 (픽셀) #define SCREEN_HEIGHT 64 // OLED 디스플레이 높이 (픽셀) #define SET_FREQUENCY_HZ A2 // 주파수를 Hz로 설정하는 푸시 버튼 #define SET_FREQUENCY_KHZ A3 // 주파수를 Khz로 설정하는 푸시 버튼 #define SET_FREQUENCY_MHZ A6 // 주파수를 Mhz 단위로 설정하는 푸시 버튼 #define ENABLE_DISABLE_OUTPUT_PIN A7 // 출력을 활성화 / 비활성화하는 푸시 버튼 #define FNC_PIN 4 // AD9833 모듈에 필요한 Fsync #define CLK_PIN 8 // 인코더의 클록 핀 #define DATA_PIN 7 / / 인코더의 데이터 핀 #define BTN_PIN 9 // 인코더의 내부 푸시 버튼
그 후이 코드에서 필요한 모든 필수 변수를 정의합니다. 먼저 로터리 엔코더 값을 저장할 정수 변수 카운터 를 정의합니다. 다음 두 변수 인 clockPin 및 clockPinState 는 인코더 방향을 이해하는 데 필요한 핀 동상을 저장합니다. 현재 타이머 카운터 값을 보유 하는 시간 변수가 있습니다.이 변수는 버튼 디 바운싱에 사용됩니다. 다음 으로 적용 할 계산 된 주파수를 보유 하는 부호없는 긴 변수 moduleFrequency 가 있습니다. 다음으로 디 바운스 지연이 있습니다. 이 지연은 필요에 따라 조정할 수 있습니다. 다음으로, 3 개의 부울 변수 set_frequency_hz가 있습니다.set_frequency_Khz 및 set_frequency_Mhz 이 세 가지 변수는 모듈의 현재 설정을 결정하는 데 사용됩니다. 이 기사의 뒷부분에서 자세히 설명하겠습니다. 다음으로 출력 파형의 상태를 저장하는 변수가 있으며 기본 출력 파형은 사인파입니다. 마지막으로 출력 파형을 설정하는 데 사용되는 인코더 버튼 카운트를 보유 하는 encoder_btn_count 변수가 있습니다.
int 카운터 = 1; //이 카운터 값은 로터리 인코더가 켜지면 증가하거나 감소합니다. int clockPin; // 로터리 엔코더에서 사용하는 핀 상태에 대한 자리 표시 자 int clockPinState; // 로터리 인코더가 사용하는 핀 상태에 대한 자리 표시 자 unsigned long time = 0; // unsigned long moduleFrequency를 디 바운싱하는 데 사용됩니다. // 출력 주파수 설정에 사용 long debounce = 220; // 디 바운스 지연 bool btn_state; // AD98333 모듈의 출력 비활성화를 활성화하는 데 사용됩니다. bool set_frequency_hz = 1; // AD9833 모듈의 낮은 주파수 bool set_frequency_khz; bool set_frequency_mhz; 문자열 waveSelect = "SIN"; // 모듈의 시작 파형 int encoder_btn_count = 0; // 인코더 버튼 누름을 확인하는 데 사용됨 다음으로, 하나는 OLED 디스플레이 용이고 다른 하나는 AD9833 모듈 용입니다.Adafruit_SSD1306 디스플레이 (SCREEN_WIDATA_PINH, SCREEN_HEIGHT, & Wire, -1); AD9833 gen (FNC_PIN);
다음으로 setup () 함수가 있습니다. 해당 설정 함수에서 디버깅을 위해 직렬을 활성화하는 것으로 시작합니다. begin () 메서드를 사용 하여 AD9833 모듈을 초기화합니다. 다음으로 할당 된 모든 로터리 인코더 핀을 입력으로 설정합니다. 그리고 클럭 핀의 값을 clockPinState 변수에 저장 합니다. 이것은 로터리 인코더에 필요한 단계입니다.
다음으로 모든 버튼 핀을 입력으로 설정하고 display.begin () 메서드를 사용하여 OLED 디스플레이를 활성화하고 if 문으로 오류를 확인합니다 . 이 작업이 완료되면 디스플레이를 지우고 시작 스플래시 화면을 인쇄하고 스플래시 화면의 지연이기도 한 2 초 지연을 추가하고 마지막으로 화면을 지우고 업데이트하는 update_display () 함수를 호출 합니다. 다시 한 번 표시됩니다. 의 세부 사항 update_display () 메소드는 문서의 뒷부분에서 논의 될 것이다.
void setup () {Serial.begin (9600); // 직렬 @ 9600 보오 gen.Begin (); // AD9833 개체를 선언 한 후 첫 번째 명령이어야합니다. pinMode (CLK_PIN, INPUT); // 핀을 입력으로 설정 pinMode (DATA_PIN, INPUT); pinMode (BTN_PIN, INPUT_PULLUP); clockPinState = digitalRead (CLK_PIN); pinMode (SET_FREQUENCY_HZ, INPUT); // 핀을 입력으로 설정 pinMode (SET_FREQUENCY_KHZ, INPUT); pinMode (SET_FREQUENCY_MHZ, INPUT); pinMode (ENABLE_DISABLE_OUTPUT_PIN, INPUT); if (! display.begin (SSD1306_SWITCHCAPVCC, 0x3C)) {// 128x64에 대한 주소 0x3D Serial.println (F ("SSD1306 할당 실패")); for (;;); } display.clearDisplay (); // 화면 지우기 display.setTextSize (2); // 텍스트 크기 설정 display.setTextColor (WHITE); // LCD 색상 설정 display.setCursor (30, 0); // 커서 위치 설정 display.println ("AD9833"); //이 텍스트 디스플레이를 인쇄합니다.setCursor (17, 20); // 커서 위치 설정 display.println ("Function"); //이 텍스트를 인쇄합니다. display.setCursor (13, 40); // 커서 위치 설정 display.println ("Generator"); //이 텍스트를 인쇄합니다. display.display (); // 디스플레이 업데이트 delay (2000); // 2 초 지연 update_display (); // update_display 함수 호출}
다음으로 loop () 함수가 있으며 모든 주요 기능은 루프 섹션에 작성됩니다.
먼저 로터리 인코더의 Clock 핀을 읽어 앞에서 선언 한 clockPin 변수에 저장합니다. 다음으로 if 문에서 이전 핀 값과 현재 핀 값이 비슷한 지 확인하고 핀의 현재 값도 확인합니다. 모두 참이면 데이터 핀을 확인하고 참이면 엔코더가 시계 반대 방향 으로 회전 하고 counter-- 명령을 사용하여 카운터 값을 감소시킵니다. 그렇지 않으면 counter ++ 명령으로 카운터 값을 증가시킵니다. 마지막으로 최소값을 1로 설정하는 또 다른 if 문을 추가 합니다 . 다음으로 clockPinState 를 현재 clockPin으로 업데이트합니다.향후 사용을위한 가치.
void loop () {clockPin = digitalRead (CLK_PIN); if (clockPin! = clockPinState && clockPin == 1) {if (digitalRead (DATA_PIN)! = clockPin) {counter-; } else {counter ++; // 인코더가 CW를 회전하므로 증가} if (counter <1) counter = 1; Serial.println (카운터); update_display (); }
다음으로 버튼 누름을 감지하는 코드가 있습니다. 이 섹션에서는 중첩 된 if 문을 사용하여 인코더 내부의 버튼을 감지했습니다. if (digitalRead (BTN_PIN) == LOW && millis ()-time> denounce), 이 문에서 먼저 버튼이 핀이 낮거나 낮 으면 눌러집니다. 그런 다음 다시 디 바운스 지연을 사용하여 타이머 값을 확인합니다. 두 명령문이 모두 참이면 성공적인 버튼 누름 동작으로 선언합니다. 그러면 encoder_btn_count 값이 증가합니다. 다음으로 최대 카운터 값을 2로 설정하는 또 다른 if 문을 선언 합니다. 출력 파형 을 설정하는 데 사용하고 있기 때문에 필요합니다 .연속 된 세 개의 if 문은 값이 0이면 사인 파형이 선택되고 1이면 구형파이고 값이 2이면 삼각파입니다. 이 세 가지 if 문 모두에서 update_display () 함수로 디스플레이를 업데이트합니다. 마지막으로 현재 타이머 카운터 값으로 시간 변수를 업데이트합니다.
// LOW 신호를 감지하면 버튼을 누릅니다. if (digitalRead (BTN_PIN) == LOW && millis ()-time> debounce) {encoder_btn_count ++; // 값 증가 if (encoder_btn_count> 2) // 값이 2보다 크면 0으로 재설정 {encoder_btn_count = 0; } if (encoder_btn_count == 0) {// 값이 0이면 사인파가 선택됨 waveSelect = "SIN"; // sin 값으로 문자열 변수 업데이트 update_display (); // 디스플레이 업데이트} if (encoder_btn_count == 1) {// 값이 1 인 경우 구형파 선택 waveSelect = "SQR"; // SQR 값으로 문자열 변수 업데이트 update_display (); // 디스플레이 업데이트} if (encoder_btn_count == 2) {// 값이 1 인 경우 삼각파가 선택됨 waveSelect = "TRI"; // TRI 값으로 문자열 변수 업데이트 update_display ();// 디스플레이 업데이트} time = millis (); // 시간 변수 업데이트}
다음으로, 디 바운스 지연으로 모든 버튼을 설정하는 데 필요한 모든 코드를 정의합니다. 버튼이 Arduino의 아날로그 핀에 연결되어 있으므로 아날로그 읽기 명령을 사용하여 아날로그 읽기 값이 30 미만에 도달하면 버튼 누름을 식별하고 성공적인 버튼 누름을 감지하고 200ms를 기다립니다. 실제 버튼 누름인지 또는 소음인지 확인하십시오. 이 문이 참이면 함수 발생기의 Hz, Khz 및 Mhz 값을 설정하는 데 사용되는 값으로 부울 변수를 할당합니다. 다음으로 디스플레이를 업데이트하고 시간 변수를 업데이트합니다. Arduino와 연결된 4 개의 버튼 모두에 대해 수행합니다.
if (analogRead (SET_FREQUENCY_HZ) <30 && millis ()-시간> 디 바운스) {set_frequency_hz = 1; // 부울 값 업데이트 set_frequency_khz = 0; set_frequency_mhz = 0; update_display (); // 디스플레이 시간 업데이트 = millis (); // 시간 변수 업데이트} if (analogRead (SET_FREQUENCY_KHZ) <30 && millis ()-time> debounce) {set_frequency_hz = 0; // 부울 값 업데이트 set_frequency_khz = 1; set_frequency_mhz = 0; moduleFrequency = 카운터 * 1000; update_display (); // 디스플레이 시간 업데이트 = millis (); // 시간 변수 업데이트} if (analogRead (SET_FREQUENCY_MHZ) <30 && millis ()-time> debounce) {// 디 바운스 지연으로 아날로그 핀 확인 set_frequency_hz = 0; // 부울 값 업데이트 set_frequency_khz = 0; set_frequency_mhz = 1; moduleFrequency = 카운터 * 1000000; update_display ();// 디스플레이 시간 업데이트 = millis (); // 시간 변수 업데이트} if (analogRead (ENABLE_DISABLE_OUTPUT_PIN) <30 && millis ()-time> debounce) {// 디 바운스 지연으로 아날로그 핀 확인 btn_state =! btn_state; // 버튼 상태 반전 gen.EnableOutput (btn_state); // 버튼 상태에 따라 함수 발생기의 출력 활성화 / 비활성화 update_display (); // 디스플레이 시간 업데이트 = millis (); // 시간 변수 업데이트}}// 시간 변수 업데이트}}// 시간 변수 업데이트}}
마지막으로 update_display () 함수가 있습니다. 이 기능에서는 디스플레이의 특정 부분을 OLED에서 업데이트 할 수 없기 때문에 단순히이 디스플레이를 업데이트하는 것 이상을 수행했습니다. 업데이트하려면 새 값으로 다시 그려야합니다. 이것은 코딩 과정을 훨씬 더 어렵게 만듭니다.
이 기능 내에서 디스플레이를 지우는 것으로 시작합니다. 다음으로 필요한 텍스트 크기를 설정합니다. 그 후 커서를 설정하고 display.println ("Function Function");을 사용하여 함수 생성기를 인쇄했습니다 . 명령. display.setCursor (0, 20) 함수를 사용하여 텍스트 크기를 다시 2로 설정하고 커서를 (0,20)으로 설정합니다.
이것이 어떤 웨이브인지에 대한 정보를 인쇄하는 곳입니다.
display.clearDisplay (); // 먼저 디스플레이를 지 웁니다. display.setTextSize (1); // 텍스트 크기 설정 display.setCursor (10, 0); // 커서 위치 설정 display.println ("Function Generator"); // 텍스트 인쇄 display.setTextSize (2); // 텍스트 크기 설정 display.setCursor (0, 20); // 커서 위치 설정
다음으로 부울 변수에서 빈도 세부 정보를 확인하고 moduleFrequency 변수 의 값을 업데이트합니다. Hz, kHz 및 MHz 값에 대해이 작업을 수행합니다. 다음으로 waveSelect 변수를 확인하고 어떤 웨이브가 선택되었는지 식별합니다. 이제 웨이브 유형과 주파수를 설정하는 값이 있습니다.
if (set_frequency_hz == 1 && set_frequency_khz == 0 && set_frequency_mhz == 0) {// Hz 단위로 주파수 설정 버튼을 눌렀는지 확인 moduleFrequency = counter; // 현재 카운터 값으로 moduleFrequency 변수 업데이트} if (set_frequency_hz == 0 && set_frequency_khz == 1 && set_frequency_mhz == 0) {// KHz 단위로 주파수 설정 버튼을 눌렀는지 확인 moduleFrequency = counter * 1000; // moduleFrequency 변수를 현재 카운터 값으로 업데이트하지만 1000을 곱하여 KHZ로 설정} if (set_frequency_hz == 0 && set_frequency_khz == 0 && set_frequency_mhz == 1) {// MHz 단위의 주파수 설정 버튼이 눌 렸는지 확인 moduleFrequency = 카운터 * 1000000; if (moduleFrequency> 12000000) {moduleFrequency = 12000000;// 주파수가 12Mhz 카운터 = 12가되도록하지 마십시오. }} if (waveSelect == "SIN") {// 사인파가 선택됨 display.println ("SIN"); gen.ApplySignal (SINE_WAVE, REG0, moduleFrequency); Serial.println (moduleFrequency); } if (waveSelect == "SQR") {// Sqr 파형이 선택됨 display.println ("SQR"); gen.ApplySignal (SQUARE_WAVE, REG0, moduleFrequency); Serial.println (moduleFrequency); } if (waveSelect == "TRI") {// Tri wave가 선택되었습니다. display.println ("TRI"); gen.ApplySignal (TRIANGLE_WAVE, REG0, moduleFrequency); // AD9833 모듈을 업데이트합니다. Serial.println (moduleFrequency); }} if (waveSelect == "SQR") {// Sqr 파형이 선택되었습니다. display.println ("SQR"); gen.ApplySignal (SQUARE_WAVE, REG0, moduleFrequency); Serial.println (moduleFrequency); } if (waveSelect == "TRI") {// Tri wave가 선택되었습니다. display.println ("TRI"); gen.ApplySignal (TRIANGLE_WAVE, REG0, moduleFrequency); // AD9833 모듈을 업데이트합니다. Serial.println (moduleFrequency); }} if (waveSelect == "SQR") {// Sqr 파형이 선택됨 display.println ("SQR"); gen.ApplySignal (SQUARE_WAVE, REG0, moduleFrequency); Serial.println (moduleFrequency); } if (waveSelect == "TRI") {// Tri wave가 선택되었습니다. display.println ("TRI"); gen.ApplySignal (TRIANGLE_WAVE, REG0, moduleFrequency); // AD9833 모듈을 업데이트합니다. Serial.println (moduleFrequency); }
커서를 다시 설정하고 카운터 값을 업데이트합니다. 다시 디스플레이의 주파수 범위를 업데이트하기 위해 부울을 확인합니다. OLED의 작동 원리가 매우 이상하기 때문에이를 수행해야합니다.
display.setCursor (45, 20); display.println (카운터); // 디스플레이에 카운터 정보를 인쇄합니다. if (set_frequency_hz == 1 && set_frequency_khz == 0 && set_frequency_mhz == 0) {display.setCursor (90, 20); display.println ("Hz"); // 디스플레이에 Hz를 출력합니다. display.display (); // 모든 세트가 디스플레이를 업데이트 할 때} if (set_frequency_hz == 0 && set_frequency_khz == 1 && set_frequency_mhz == 0) {display.setCursor (90, 20); display.println ("Khz"); display.display (); // 모든 세트가 디스플레이를 업데이트 할 때} if (set_frequency_hz == 0 && set_frequency_khz == 0 && set_frequency_mhz == 1) {display.setCursor (90, 20); display.println ("Mhz"); display.display (); // 모든 세트가 디스플레이를 업데이트 할 때}
다음으로 버튼 누름 변수를 확인하여 출력을 OLED에 출력 / 출력합니다. 다시 말하지만 이것은 OLED 모듈로 인해 수행되어야합니다.
if (btn_state) {display.setTextSize (1); display.setCursor (65, 45); display.print ("출력 ON"); // 디스플레이에 출력을 인쇄합니다. display.display (); display.setTextSize (2); } else {display.setTextSize (1); display.setCursor (65, 45); display.print ("출력 OFF"); // 디스플레이에 출력을 출력합니다. display.display (); display.setTextSize (2); }
이것으로 코딩 과정이 끝났습니다. 이 시점에서 혼란 스러우면 코드의 주석을 확인하여 더 자세히 이해할 수 있습니다.
AD9833 기반 함수 발생기 테스트
회로를 테스트하기 위해 위의 설정이 사용됩니다. 보시다시피 12V DC 전원 어댑터를 DC 배럴 잭에 연결하고 Hantek 오실로스코프를 회로 출력에 연결했습니다. 또한 출력 주파수를 시각화하고 측정하기 위해 오실로스코프를 노트북에 연결했습니다.
이 작업이 완료되면 로터리 인코더를 사용하여 출력 주파수를 5Khz로 설정하고 출력 사인파를 테스트하고 출력에서 5Khz 사인파입니다.
다음으로 출력 파형을 삼각파로 변경했지만 주파수는 동일하게 유지되었으며 출력 파형은 아래와 같습니다.
그런 다음 출력을 구형파로 변경하고 출력을 관찰했는데 이는 완벽한 구형파였습니다.
우리는 또한 주파수 범위를 변경하고 출력을 테스트했으며 잘 작동했습니다.
추가 향상
이 회로는 개념 증명 일 뿐이며 추가 개선이 필요합니다. 첫째, 출력을 위해 좋은 품질의 PCB와 좋은 품질의 BNC 커넥터가 필요합니다. 그렇지 않으면 더 높은 주파수를 얻을 수 없습니다. 모듈의 진폭은 매우 낮으므로이를 향상시키기 위해 출력 전압을 증폭하기위한 연산 증폭기 회로가 필요합니다. 출력 진폭을 변경하기 위해 전위차계를 연결할 수 있습니다. 신호 오프셋을위한 스위치를 연결할 수 있습니다. 이것은 또한 필수 기능입니다. 또한 코드는 약간 버그가 많기 때문에 많은 개선이 필요합니다. 마지막으로 OLED 디스플레이를 변경해야합니다. 그렇지 않으면 쉽게 이해할 수있는 코드를 작성하는 것이 불가능합니다.
이것으로이 튜토리얼이 끝났습니다. 기사를 좋아하고 새로운 것을 배웠기를 바랍니다. 기사에 대한 질문이 있으시면 아래 댓글 섹션에 남기거나 전자 포럼을 사용할 수 있습니다.