Pytanie:
RPi GPIO jako szybki generator fal prostokątnych
Jeon
2014-06-30 09:54:43 UTC
view on stackexchange narkive permalink

Próbuję zmusić RPi do generowania szybkiej fali prostokątnej przez swój pin GPIO.

Mój kod kontrolujący wyjście GPIO jest oparty na tym artykule

Zasadnicza część mojego kodu jest następująca:

  speed = 1000000; // 1 MHz lub 0,5 MHz w każdym razie (zwróć uwagę na kolejność MHz) s2us = 1000000; // sekunda do mikrosekundy podczas (1) {GPIO_SET = 1<<7; // ustaw GPIO 07 HIGH usleep (1 / speed * s2us); // spanie dla 1 nas GPIO_CLR = 1<<7; // ustaw GPIO 07 LOW usleep (1 / speed * s2us); // sleep for 1 us}  

Kiedy uruchamiam kod, pokazuje on przebieg prostokątny z okresem 4,2 ms, co oznacza tylko około 240 Hz. To nie jest tolerowany błąd, ponieważ kolejność setek Hz i MHz.

Wyszukałem w Google ten problem i stwierdziłem, że usleep , nanosleep nie może działać poprawnie, jeśli czas uśpienia jest zbyt krótki od czasu jakiegoś rodzaju harmonogramu systemu Linux. Ale nie mam pomysłu na rozwiązanie tego problemu. Niektórzy sugerują użycie delay zamiast sleep , ale nie jestem pewien, czy zadziała, czy nie.

Używam RPi model B rev 2.0 i Raspbina wheezy 2014. Świeża instalacja i nic nie zostało zainstalowane.

Cztery odpowiedzi:
joan
2014-06-30 11:01:06 UTC
view on stackexchange narkive permalink

Moja biblioteka pigpio umożliwia generowanie powtarzających się przebiegów o rozdzielczości mikrosekund. Jeśli potrzebujesz mniej niż mikrosekund, musisz znaleźć inne rozwiązanie.

Python

  #! / Usr / bin / env pythonimport timeimport pigpioGPIO = 4square = [] # ON OFF MICROSsquare.append (pigpio.pulse (1<<GPIO, 0, 4)) square.append (pigpio.pulse (0, 1<Ailisbkipt), # 4) połącz się z lokalnym Pipi.set_mode (GPIO, pigpio.OUTPUT) pi.wave_add_generic (kwadrat) wid = pi.wave_create () if wid > = 0: pi.wave_send_repeat (wid) time.sleep (60) pi.wave_tx_stop () .wave_delete (wid) pi.stop ()  

C

  #include <stdio.h> # include <stdlib .h> # include <stdarg.h> # include <unistd.h> # include <string.h> # include <pigpiokiintd.h> # include <string. GPIO; static int on = ON; static int off = OFF; gpioPulse_t pulse [2]; void fatal (char * fmt, ...) {char buf [256]; va_list ap; va_start (ap, fmt); vsnprintf (buf, sizeof (buf), fmt, ap); va_end (ap); fprintf (stderr, "% s \ n", buf); exit (EXIT_FAILURE);} void usage () {fprintf (stderr, "\ n" \ "Usage: sudo ./square [OPCJA] ... \ n" \ "-f value, off micros, 1- (% d ) \ n "\" -g wartość, gpio, 0-31 (% d) \ n "\" -n wartość, na micros, 1- (% d) \ n "\" PRZYKŁAD \ n "\" sudo. / square -g 23 \ n "\" Generowanie fali prostokątnej na GPIO 23. \ n "\" \ n ", OFF, GPIO, ON);} static void initOpts (int argc, char * argv []) {int i , opt; while ((opt = getopt (argc, argv, "f: g: n:"))! = -1) {i = -1; switch (opt) {case 'f': i = atoi (optarg); if (i > = 1) off = i; else fatal ("nieprawidłowa opcja -f (% d)", i);
złamać; przypadek „g”: i = atoi (optarg); if ((i > = 1) && (i < = 31)) gpio = i; else fatal ("nieprawidłowa opcja -g (% d)", i); złamać; przypadek „n”: i = atoi (optarg); if (i > = 1) on = i; else fatal ("nieprawidłowa opcja -n (% d)", i); złamać; domyślna: /* '?' */            stosowanie(); exit (EXIT_FAILURE); }}} int main (int argc, char * argv []) {int wid; initOpts (argc, argv); printf ("gpio #% d, wł.% dus, wył.% dus \ n", gpio, wł, wył); if (gpioInitialise () <0) return -1; gpioSetMode (gpio, PI_OUTPUT); puls [0] .gpioOn = (1<<gpio); puls [0] .gpioOff = 0; puls [0] .usDelay = on; puls [1] .gpioOn = 0; puls [1] .gpioOff = (1<<gpio); pulse [1] .usDelay = off; gpioWaveClear (); gpioWaveAddGeneric (2, puls); wid = gpioWaveCreate (); if (wid > = 0) {gpioWaveTxSend (wid, PI_WAVE_MODE_REPEAT); podczas (1) snu (1); } gpioTerminate ();}  
Dzięki, zadziałało. Widzę falę prostokątną o okresie 10 us i cyklu pracy 50%. Chociaż istnieje pewne przeregulowanie i niedotrzymanie, gdy okres staje się coraz krótszy. Ale jest w porządku, ponieważ nie potrzebuję tak bardzo krótkiego okresu.
Jeśli chcesz tylko fali prostokątnej, możesz użyć zegara SPI lub wielokrotnie przesyłać UUUU na UART lub użyć gpio PWM. Przebiegi pigpio pozwalają na jednoczesne sterowanie wieloma gpios i były naprawdę przeznaczone do zastosowań typu CNC i IR.
Hunter Akins
2017-08-14 05:30:00 UTC
view on stackexchange narkive permalink

Udało mi się uzyskać wyjściowy przebieg prostokątny 1us okresu na pinach GPIO przy użyciu systemu operacyjnego czasu rzeczywistego ChibiOS ( http://chibios.sourceforge.net/html/index.html). artykuł zawierający odsyłacze do sterowników BCM2835 http://www.stevebate.net/chibios-rpi/GettingStarted.html

Postępuj zgodnie z instrukcjami, aby zainstalować system operacyjny, a następnie sprawdź folder do sterowania GPIO.

Milliways
2014-06-30 10:47:58 UTC
view on stackexchange narkive permalink

To, co próbujesz zrobić, jest niemożliwe przy użyciu Linuksa, ponieważ nie jest to system operacyjny czasu rzeczywistego.
To nie jest tylko problem z procedurami opóźnienia.

Wypróbuj swój kod, pomijając usleep połączeń, co może dać ci pojęcie, jaka może być maksymalna częstotliwość, ale nawet tutaj znajdziesz dość długie i nieprzewidywalne opóźnienia spowodowane obsługą przerwań.

Nie jest niemożliwe ustawienie sprzętu Pi tak, aby generował prostokątna, ale wymaga to zupełnie innego podejścia.

Masz na myśli nie Linux na RPi, ale jakieś niskopoziomowe podejście do RPi? Lubisz bezpośrednio manipulować ARM? A może możesz polecić inne systemy operacyjne lub urządzenia, które mogą zastąpić Linuksa lub RPi?
Sam tego nie próbowałem, ale przeczytanie „General Purpose GPIO Clocks” w arkuszach danych BMC wskazuje, że jest to możliwe i jest kilka projektów, które z tego korzystają. Spróbuj wyszukać „malinowy generator częstotliwości”
Cóż, niemożliwe to trudne słowo, na pewno jest coś możliwego z pewnymi ograniczeniami. Ale oczywiście nie użyłbym go w moim statku kosmicznym.
Anum Sheraz
2018-05-09 02:35:08 UTC
view on stackexchange narkive permalink

linux NIE jest systemem operacyjnym czasu rzeczywistego, więc nie możesz oczekiwać, że czas uśpienia będzie dokładny. To nie będzie dokładne, przez co NIE uzyskasz stałej melodii, zamiast tego melodia będzie zmieniać częstotliwość. Jeśli spróbujesz zrobić to samo w mikrokontrolerze (np. Arduino), częstotliwość nie będzie się zmieniać. Możesz użyć tego fragmentu, aby uzyskać sygnał dźwiękowy, dostosowując parametry czasowe. Ale nie możesz tworzyć pięknych melodii :(.

Aby wygenerować prostokątną falę na pinie GPIO;

  def beep (repeat): for i in range (0, repeat) : dla impulsu w zakresie (60): # pętla prostokątna GPIO.output (7, True) czas uśpienia (0,001) # wysoki dla 0,001 sekundy GPIO.output (7, False) czas uśpienia (0,001) # niski dla .001 sec time.sleep (0.02) # dodaj pauzę między każdym sygnałem cyklu (4)  


To pytanie i odpowiedź zostało automatycznie przetłumaczone z języka angielskiego.Oryginalna treść jest dostępna na stackexchange, za co dziękujemy za licencję cc by-sa 3.0, w ramach której jest rozpowszechniana.
Loading...