Ich übertrage Daten von meinem PIC24H Mikrocontroller über 460Kbaud UART zu einem Bluetooth Funkmodul. Unter den meisten Bedingungen funktioniert dieser Fluss gut und das Bluetooth-Modul verwendet CTS- und RTS-Leitungen, um die Flusskontrolle zu verwalten, wenn die internen Datenpuffer voll sind. Es gibt jedoch einen Fehler in dem Bluetooth-Modul, der es zurücksetzt, wenn Daten kontinuierlich ohne Unterbrechungen an es gesendet werden, was passiert, wenn meine Daten in einem anderen Engpass gesichert werden.
Es wäre schön, wenn das Modul richtig funktioniert hätte, aber das liegt außerhalb meiner Kontrolle. So scheint es, dass meine einzige Option ist, einige Daten Drosselung an meinem Ende zu tun, um sicherzustellen, dass ich die Grenzen des Datendurchsatzes nicht überschreite (was ich ungefähr durch Experimente weiß).
Meine Frage ist, wie Sie die Drosselung der Datenrate implementieren können.
Meine aktuelle UART-Implementierung ist ein RAM-Ring-FIFO-Puffer mit 1024 Byte Länge, in den die Hauptschleife Daten schreibt. Ein Peripherie-Interrupt wird vom PIC ausgelöst, wenn das letzte Byte von der UART-Hardware gesendet wurde und mein ISR das nächste Byte aus dem Puffer liest und es an die UART-Hardware sendet.
Hier ist eine Idee des Quellcodes:
uart_isr.c
%Vor%uart_methods.c
%Vor% Bearbeiten
Es gibt zwei Möglichkeiten, wie die Drosselung implementiert werden könnte, wie ich es sehe:
Erzwingen Sie eine Zeitverzögerung zwischen dem zu schreibenden UART-Byte, das den Datendurchsatz begrenzt.
Halten Sie eine laufende Anzahl von Bytes, die über einen bestimmten Zeitraum übertragen werden, und wenn die maximale Anzahl von Bytes für diese Zeitspanne überschritten wird, erstellen Sie eine etwas längere Verzögerung, bevor Sie mit der Übertragung fortfahren.
Jede Option würde theoretisch funktionieren, es ist die Implementierung, über die ich mich wundere.
Vielleicht ist ein Quotenansatz das, was Sie wollen. Verwenden Sie einen periodischen Interrupt der relevanten Zeitskala, fügen Sie eine Quote von "Bytes, die übertragen werden sollen" zu einer globalen Variablen hinzu, bis zu einem Punkt, an dem Sie nicht über eine Ebene gehen, die für die entsprechende Überschwemmung angepasst wurde. Dann überprüfe einfach, ob es eine Quote gibt, bevor du ein Byte senden kannst. Bei einer neuen Übertragung wird es zu einer anfänglichen Überschwemmung kommen, aber später begrenzt die Quote die Übertragungsrate.
%Vor%Wenn Sie einen freien Timer haben oder wenn Sie einen vorhandenen verwenden können, könnten Sie eine Art "Entprellen" der gesendeten Bytes durchführen.
Stellen Sie sich vor, Sie hätten diese globale Variable, byte_interval
, und Sie haben einen Zeitgeber, der alle Mikrosekunden überläuft (und die ISR auslöst). Dann könnte es in etwa so aussehen:
Und dann könnten Sie in der "putchar" -Funktion Folgendes haben:
%Vor%Es tut mir leid, dass ich nicht viel in Ihren Code geschrieben habe, damit ich genauer darauf eingehen kann. Das ist nur eine Idee, ich weiß nicht, ob es für dich passt.
Erstens gibt es zwei Arten der seriellen Ablaufsteuerung, die häufig verwendet werden.
Sie sagen, CTS ist eingeschaltet, aber Sie möchten vielleicht sehen, ob XON / XOFF auf irgendeine Weise aktiviert werden kann.
Ein anderer Ansatz, wenn Sie es konfigurieren können, ist einfach eine niedrigere Baudrate zu verwenden. Dies hängt natürlich davon ab, was Sie am anderen Ende der Verbindung konfigurieren können, aber es ist normalerweise der einfachste Weg, um Probleme zu beheben, wenn Geräte nicht in der Lage sind, Übertragungen mit höherer Geschwindigkeit zu bewältigen.
Timer-Ansatz, der Tx zu einer bestimmten Zeit eine Verzögerung hinzufügt:
Tags und Links c embedded interrupt microcontroller