Bagaimana saya bisa menghasilkan sinyal frekuensi / pulsa?


19

Saya mencari cara untuk menggunakan Raspberry Pi sebagai generator sinyal. Saat ini saya sedang mengerjakan pemasangan modul AD9850 murah dari ebay. Ini akan menghasilkan frekuensi yang cukup akurat hingga 40MHz (70MHz dengan AD9851).

masukkan deskripsi gambar di sini

Saya kira output audio juga dapat digunakan untuk bentuk gelombang yang sewenang-wenang hingga frekuensi yang sangat terbatas.

Apakah ada kemungkinan lain?

Jawaban:


13

Inilah cara saya menghubungkan modul AD9850 dan program Python sederhana untuk menunjukkan cara mengatur frekuensi ke 1000Hz.

AD9850 perlu dijalankan pada 5V agar bekerja dengan baik dengan kristal 125MHz. Ini akan mungkin ok untuk kawat 4 pin GPIO langsung ke modul karena mereka hanya masukan, tapi menghubungkan melalui MCP23017 efektif ternyata modul ke lain I²C perifer dan memastikan input RPI aman.

Catatan Penting Tentang + 5V
Pin + 5V pada GPIO tidak dapat benar-benar memasok arus yang cukup untuk memberi daya pada AD9850. Anda harus menggunakan persediaan 5V eksternal.

RPi terhubung ke modul AD9850 melalui MCP23017

from functools import partial

import smbus

def main():
    addr = 0x20
    bus = smbus.SMBus(0) # or SMBus(1) on newer pis

    # Helper functions    
    wr_dir = partial(bus.write_byte_data, addr, 0x01)
    wr = partial(bus.write_byte_data, addr, 0x13)

    # Set Pins B0-B4 of the MCP23017 to output
    wr_dir(0xF0)

    # Names of the Pins
    RST = 1 << 0
    DATA = 1 << 1
    FQ = 1 << 2
    CLK = 1 << 3

    def send_bit(bit):
        # send a single bit
        wr(DATA * bit)
        wr(CLK | DATA * bit)

    def fq():
        wr(FQ)
        wr(0)

    def init():
        wr(RST)
        wr(0)
        wr(CLK)
        wr(0)
        wr(FQ)
        wr(0) 

    freq = 1000  
    init()
    dphase = int(0.5 + (freq << 32) / 125000000.0)
    for x in range(32):
        send_bit((dphase >> x) & 1)

    # Phase bits can all be 0
for x in range(8):
    send_bit(0)

    fq()

if __name__ == "__main__":
    main()

Apakah itu simbol RPi GPIO Anda sendiri?
Alex Chamberlain

1
@AlexChamberlain, ya itu. Sejauh yang saya tahu RPF belum merilis sesuatu yang sangat berguna selain dari RPi itu sendiri :)
John La Rooy

Hmm, saya kira ini mungkin pertanyaan konyol, tapi apa itu simbol GPIO?
Steven Lu

@ SevenLu, persegi panjang besar di sebelah kanan skema. RPi lama memiliki 26 pin, yang lebih baru memiliki 40 pin. lihat elinux.org/...
John La Rooy

Oh baiklah. Sepertinya sangat alami. Saya rasa Anda tidak menggambar versi 40 pin karena Anda hanya membutuhkan 3 pin tersebut untuk diagram.
Steven Lu

11

Secara teori Anda bisa menghubungkan beberapa D / A converter ke pin GPIO tetapi ini tidak cocok untuk menghasilkan sinyal karena Anda tidak akan dapat mengendarainya dengan waktu yang tepat, terutama karena Linux bukan OS waktu nyata.

Juga, tidak mungkin ini bisa beroperasi pada frekuensi tinggi.

Jika 44 kHz sudah cukup, saya pikir jack audio mungkin cara paling sederhana untuk melakukannya.


4

John La Rooy memiliki solusi yang baik tetapi sirkuit mungkin lebih rumit daripada yang diinginkan beberapa orang. Ini menggambarkan solusi serupa yang dirancang oleh Tom Herbison hanya menggunakan AD9850, meskipun menggunakan 4 pin sinyal GPIO bukannya 2 seperti solusi John.

Tom terhubung ke GPIO seperti ini: diagram koneksi

Perhatikan dia menjalankan AD9850 pada 3.3V, bukannya 5V. Menurut diskusi ini , AD9850 dinilai berjalan pada 3.3V atau 5V, tetapi beberapa papan mungkin menggunakan komponen yang tidak dapat menangani 5V lama, jadi menjalankan pada 3.3V sebenarnya bisa menjadi solusi yang lebih baik, tergantung pada selera Anda pada papan AD9850 .

Papan AD9850 khusus saya memiliki sebagian besar label pin hanya di bawah papan, jadi saya mengambil gambar bagian bawah sebelum menekannya ke papan prototyping. Lokasi pin akhirnya identik dengan yang ada di papan Tom. Di papan tulis saya, FQdiberi label FU_UQ, CLKadalah W_CLK, dan RSTsedang RESET.

Tom menyediakan skrip Python 3 ini untuk mengontrol fungsi generator. Berikut adalah salinan v1.0 jika tautan unduhan terputus:

# RPi RF Signal Generator v1.0

# Copyright (C) 2013 Tom Herbison MI0IOU
# Email (hidden to discourage spammers - see original rpi_rfsiggen.py file)
# Web <http://www.asliceofraspberrypi.co.uk>

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# import GUI module
from tkinter import *

# import GPIO module
import RPi.GPIO as GPIO

# setup GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)

# Define GPIO pins
W_CLK = 15
FQ_UD = 16
DATA = 18
RESET = 22

# setup IO bits
GPIO.setup(W_CLK, GPIO.OUT)
GPIO.setup(FQ_UD, GPIO.OUT)
GPIO.setup(DATA, GPIO.OUT)
GPIO.setup(RESET, GPIO.OUT)

# initialize everything to zero
GPIO.output(W_CLK, False)
GPIO.output(FQ_UD, False)
GPIO.output(DATA, False)
GPIO.output(RESET, False)

# Function to send a pulse to GPIO pin
def pulseHigh(pin):
    GPIO.output(pin, True)
    GPIO.output(pin, True)
    GPIO.output(pin, False)
    return

# Function to send a byte to AD9850 module
def tfr_byte(data):
    for i in range (0,8):
        GPIO.output(DATA, data & 0x01)
        pulseHigh(W_CLK)
        data=data>>1
    return

# Function to send frequency (assumes 125MHz xtal) to AD9850 module
def sendFrequency(frequency):
    freq=int(frequency*4294967296/125000000)
    for b in range (0,4):
        tfr_byte(freq & 0xFF)
        freq=freq>>8
    tfr_byte(0x00)
    pulseHigh(FQ_UD)
    return


# Class definition for RPiRFSigGen application
class RPiRFSigGen:
        # Build Graphical User Interface
        def __init__(self, master):
                frame = Frame(master, bd=10)
                frame.pack(fill=BOTH,expand=1)
                # set output frequency
                frequencylabel = Label(frame, text='Frequency (Hz)', pady=10)
                frequencylabel.grid(row=0, column=0)
                self.frequency = StringVar()
                frequencyentry = Entry(frame, textvariable=self.frequency, width=10)
                frequencyentry.grid(row=0, column=1)
                # Start button
                startbutton = Button(frame, text='Start', command=self.start)
                startbutton.grid(row=1, column=0)
                # Stop button
                stopbutton = Button(frame, text='Stop', command=self.stop)
                stopbutton.grid(row=1, column=1)


        # start the DDS module
        def start(self):
                frequency = int(self.frequency.get())
                pulseHigh(RESET)
                pulseHigh(W_CLK)
                pulseHigh(FQ_UD)
                sendFrequency(frequency)

        # stop the DDS module
        def stop(self):
                pulseHigh(RESET)

# Assign TK to root
root = Tk()

# Set main window title
root.wm_title('RPi RFSigGen')

# Create instance of class RPiRFSigGen
app = RPiRFSigGen(root)

# Start main loop and wait for input from GUI
root.mainloop()

Karena setiap penggunaan pin GPIO pada pi membutuhkan berjalan sebagai root, Tom menjelaskan dua metode meluncurkan kode python-nya dengan hak akses root. Metode pertamanya adalah memodifikasi ikon desktop IDE Python agar selalu berjalan sebagai root, tetapi menurut saya itu tidak aman - Anda tidak ingin menjalankan semua program GUI python sebagai root jika Anda tidak perlu. Metode kedua adalah menjalankan sudo idle3_dari prompt perintah untuk meluncurkan Lingkungan Pengembangan Terpadu Python 3 dengan hak akses root setiap kali diperlukan hak akses root.

Tom tidak menyebutkan menginstal pustaka RPi.GPIO python 3 sehingga mungkin sudah tersedia pada beberapa versi Pi OS, tapi itu tidak tersedia pada Occidentalis v0.2 yang saya gunakan jadi saya berlari sudo apt-get install python3-rpi.gpio. Perhatikan bahwa Python 3 menggunakan lokasi berbeda untuk RPi.GPIO sehingga sudo apt-get install python-rpi.gpiohanya akan membuat perpustakaan dapat diakses oleh Python 2.

Setelah Python 3 IDE terbuka dengan hak akses root, buka file rpi_rfsiggen.py, lalu pilih Run -> Run Moduledari menu atau tekan F5.

Saya bisa mendapatkan gelombang sinus 18kHZ stabil yang bagus pada 1Vpp dari pin output SinB (diberi label ZOUT2di papan saya) pada percobaan pertama saya.


3

Jika Anda hanya ingin mengimplementasikan generator fungsi untuk audio dan Lf rf kemudian ambil modul AD9833 murah dari EBAY. Ini akan memberi Anda gelombang sinus, persegi dan segitiga ditambah fase variabel. Rupanya tidak banyak yang baik melewati 7 MHz ....

masukkan deskripsi gambar di sini


Pasti ada alasan mengapa modul-modul itu jauh lebih mahal daripada modul AD9850. Ada yang tahu kenapa?
John La Rooy
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.