Як я можу генерувати частотні / імпульсні сигнали?


19

Я розглядаю способи використання Raspberry Pi в якості генератора сигналів. В даний час я працюю над підключенням недорогого модуля AD9850 від ebay. Це створить досить точні частоти до 40 МГц (70 МГц з AD9851).

введіть тут опис зображення

Я здогадуюсь, що аудіо вихід може бути використаний для довільних форм хвиль до дуже обмеженої частоти.

Чи є інші можливості?

Відповіді:


13

Ось як я підключив модуль AD9850 і просту програму Python, щоб показати, як встановити частоту на 1000 ГГц.

Для правильної роботи з кристалом 125 МГц AD9850 повинен працювати на 5В. Було б , ймовірно , буде нормально провід 4 GPIO контактів безпосередньо до модуля , так як вони тільки входи, але підключення через MCP23017 ефективно перетворює модуль в інший I²C периферійного і переконується входи RPI безпечні.

Важлива примітка Про + 5
В Контакт + 5 В на GPIO не може реально подати достатній струм для живлення AD9850. Вам слід використовувати зовнішнє джерело живлення 5В.

RPI підключений до модуля AD9850 через 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()

Це ваш власний символ RPI GPIO?
Алекс Чемберлен

1
@AlexChamberlain, так. Наскільки я можу сказати, RPF не випустив нічого дуже корисного, крім самого RPi :)
Джон Ла Руй

Хм, я думаю, це може бути дурним питанням, але що таке символ GPIO?
Стівен Лу

@StevenLu, великий прямокутник праворуч від схеми. У старих RPi було 26 штифтів, у нових - 40 шпильок. дивіться elinux.org/…
Джон Ла Рой

О, гаразд. Це просто здається дуже природним. Я вважаю, що ви не намалювали 40-контактну версію, тому що для діаграми вам знадобилися лише 3 цих штифта.
Стівен Лу

11

Теоретично ви можете підключити деякий перетворювач D / A до штифтів GPIO, але це не підходить для генерації сигналу, оскільки ви не зможете керувати ним із точним тимчасовим часом, головним чином тому, що Linux не є ОС в режимі реального часу.

Крім того, немає ніякого способу, щоб це могло працювати на таких високих частотах.

Якщо 44 кГц або близько цього достатньо, я думаю, що аудіороз'єм може бути найпростішим способом зробити це.


4

Джон Ла Рой має гарне рішення, але схема може бути складнішою, ніж дехто вважає за краще. Це описує подібне рішення, розроблене Томом Гербісоном, використовуючи лише AD9850, хоча воно використовує 4 сигнальних штифта GPIO замість 2 подібних рішень Джона.

Том підключається до GPIO так: схема підключення

Зауважте, він працює на AD9850 на 3,3 В замість 5 В. Згідно з цією дискусією , AD9850 оцінюється на 3,3 В або 5 В, але деякі плати можуть використовувати компоненти, не здатні довго працювати з 5 В, тому робота на рівні 3,3 В може бути кращим рішенням, залежно від вашого смаку плати AD9850 .

Моя конкретна плата AD9850 мала більшість штифтових міток лише під дошкою, тому я сфотографував нижню сторону перед тим, як натиснути її на плату для складання прототипів. Місце розташування штифтів у будь-якому випадку було ідентичним тим, що знаходилися на дошці Тома. На моїй дошці FQрозміщено маркування FU_UQ, CLKє W_CLKі RSTє RESET.

Том надає цей сценарій Python 3 для управління генератором функцій. Ось копія v1.0 у випадку, якщо посилання на завантаження колись порушиться:

# 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()

Оскільки будь-яке використання штифтів GPIO на pi вимагає запуску як root, Том описує два способи запуску свого пітонного коду з привілеями root. Його перший метод полягає в тому, щоб змінити піктограму на робочому столі Python IDE, щоб вона завжди працювала як root, але це вражає мене як небезпечне - ви не хочете запускати всі програми графічного інтерфейсу python як root, якщо цього не потрібно. Другий метод полягає у запуску sudo idle3_з командного рядка для запуску інтегрованого середовища розробки Python 3 з привілеями root, коли йому потрібні привілеї root.

Том не згадує про встановлення бібліотеки RPi.GPIO python 3, тому вона вже може бути доступна в деяких версіях Pi OS, але вона не була доступна в Occidentalis v0.2, який я використовував, тому я запустив sudo apt-get install python3-rpi.gpio. Зверніть увагу, що Python 3 використовує інше місце для RPi.GPIO, тому sudo apt-get install python-rpi.gpioзробить доступною лише бібліотеку для Python 2.

Після відкриття програми IDE Python 3 з правами root, відкрийте файл rpi_rfsiggen.py, а потім виберіть Run -> Run Moduleіз меню або натисніть F5.

Мені вдалося отримати гарну стабільну синусоїду в 18 кГц на 1 Впп з вихідного штиря SinB (позначено ZOUT2на моїй дошці) під час моєї першої спроби.


3

Якщо ви просто хочете реалізувати генератор функцій для аудіо та Lf rf, тоді підберіть дешевий модуль AD9833 від EBAY. Це дасть вам хвилі синуса, квадрата та трикутника плюс змінну фазу. Мабуть, не дуже добре минулих 7 МГц….

введіть тут опис зображення


Має бути причина, що такі модулі набагато дорожчі, ніж модулі AD9850. Будь-яка ідея чому?
Джон Ла Рой
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.