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


19

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

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

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

Есть ли другие возможности?

Ответы:


13

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

AD9850 должен работать при 5 В для правильной работы с кристаллом 125 МГц. Было бы , вероятно , будет нормально провод 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 :)
John La Rooy

Хм, наверное, это глупый вопрос, но что за символ GPIO?
Стивен Лу

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

Ох, ну ладно. Это кажется очень естественным. Я считаю, что вы не нарисовали версию с 40 выводами, потому что вам все равно понадобилось только 3 из этих выводов для диаграммы.
Стивен Лу

11

Теоретически вы могли бы подключить некоторые цифро-аналоговые преобразователи к выводам 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, Том описывает два способа запуска своего кода Python с привилегиями root. Его первый метод - изменить иконку Python IDE на рабочем столе, чтобы она всегда работала с правами root, но это кажется мне небезопасным - вы не хотите запускать все программы Python GUI с правами 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.

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

Я смог получить хорошую стабильную синусоидальную волну с частотой 18 кГц при 1 Вpp от выходного контакта SinB (помеченного ZOUT2на моей плате) с первой попытки.


3

Если вы просто хотите реализовать генератор функций для аудио и Lf rf, тогда приобретите дешевый модуль AD9833 от EBAY. Это даст вам синусоидальные, квадратные и треугольные волны плюс переменную фазу. Видимо, не так много хороших последних 7 МГц ....

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


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