Was ist ein bisschen hämmern

26

Ich bin neu in der Mikrocontroller-Programmierung. Ich verwende ATmega32-A-Controller und CodeVisionAVR-Compiler. Ich benutze den Wellenformgenerator (AD9833), um ein Sinussignal mit SPI-Kommunikation zu erzeugen. Ich kann die Sinuswelle erfolgreich erzeugen. Jetzt leite ich das Signal an den Sensor weiter. Der Sensorausgang wird über den Multiplexer ausgewählt und an den ADC gesendet. Jetzt möchte ich ADC-Werte über SPI-Kommunikation lesen. Ich habe viel versucht, um die Register von ADC einzurichten. Es funktioniert immer noch nicht. Um den SPI-Kommunikationscode zu sehen, werfen Sie einen Blick auf meinen vorherigen Beitrag. ADC registriert die Einrichtung mithilfe von SPI-Kommunikation . Ich verwende die USART (RS232) -Kommunikation, um Werte auf dem PC (PuTTY) auszudrucken.

Jemand hat mir geraten, Bit-Banging zu verwenden. Ich bin neu in diesem Konzept. Kann mir jemand einen Beispielcode für das Bit-Banging der SPI-Kommunikation geben? Wie fange ich an? Kann mir jemand ein gutes Material liefern. Benötige ich externe Hardware?

Ich habe folgendes geschrieben, einschließlich der Stiftverbindungen:

#define ADC_CS PORTB.3
#define MOSI PORTB.5
#define MISO PINB.6
#define SCK PORTB.7

void send_8bit_serial_data(unsigned char data)
{
    int i;  
    ADC_CS=0;
    for (i = 0; i < 8; i++)
    {
        // consider leftmost bit
        // set line high if bit is 1, low if bit is 0
        if (data & 0x80)
            output_high(PORTB.5);
        else
            output_low(PORTB.5);

        // pulse clock to indicate that bit value should be read
        output_low(PORTB.7);
        output_high(PORTB.7);

        // shift byte left so next bit will be leftmost
        data <<= 1;
    }

    // deselect device
    ADC_CS=1;
}
verendra
quelle
Ihr Code sieht in Ordnung aus, abgesehen davon, dass der niedrige Takt vor der Biteinstellung und Verzögerung liegen sollte. Sie benötigen einige Verzögerungen, um das Timing zu korrigieren (so dass die niedrigen / hohen Takte ungefähr die gleiche Zeitspanne sind). Schauen Sie sich noch einmal den Code von Steven an. Wenn Sie auch lesen möchten, müssen Sie den Code auch dafür hinzufügen.
Oli Glaser
@OliGlaser Kann ich diesen Code direkt anstelle des normalen SPI-Codes verwenden, um Register einzurichten?
Verendra
@verendra - nicht sicher, was du mit "normalem SPI-Code" meinst. Wenn Sie anstelle von Hardware-SPI meinen, ist es dem ADC egal, wie die Impulse erzeugt werden, solange sie mit dem Protokoll und dem Timing übereinstimmen.
Oli Glaser

Antworten:

25

Bit Banging erzeugt die gesamte Reihe von Impulsen in der Software, anstatt sich auf ein Teil der Hardware im Mikrocontroller zu verlassen.

Viele Mikrocontroller verfügen über einen Hardware-SPI. Anschließend müssen Sie nur noch ein Byte in das Ausgangsregister schreiben. Der SPI-Controller verschiebt die Daten nach außen und empfängt gleichzeitig Daten vom Slave. Sie können eine Unterbrechung erhalten, wenn die Übertragung abgeschlossen ist, und dann die empfangenen Daten lesen.

Bei einigen Mikrocontrollern ist die SPI-Hardware jedoch nicht vorhanden, und Sie müssen sie simulieren, indem Sie alles manuell ausführen. SPI hat eine Reihe von verschiedenen Modi, ich werde dieses Impulsdiagramm als Beispiel verwenden:

Bildbeschreibung hier eingeben

Während sich ein dedizierter SPI-Controller um alle Impulse, die Datenverschiebung und das Timing kümmert, müssen Sie beim Bit-Banging jede Aktion selbst ausführen:

Make Slave Select low  
Short delay
Do 8 times
  Make the SCK (Serial Clock) pin low 
  Make the MOSI (Master-Out-Slave-In) pin high or low depending on bit 7 of the data  
  Add brief delay  
  Make the SCK output high
  Read MISO (Master-In-Slave-Out) pin
  Shift received data left, and shift the bit just read in as bit 0   
  Add brief delay  
  Shift the data byte 1 bit left
Make Slave Select high again  

Bit-Banging-SPI ist relativ einfach, der Code für Bit-Banging-I2C ist beispielsweise komplexer, und Sie benötigen einen Timer, wenn Sie das UART-Protokoll bit-bangen möchten.

Stevenvh
quelle
2
Können Sie einen Beispiel-C-Code bereitstellen?
Verendra
1
@verendra - Ich habe ein Pseudocode-Beispiel hinzugefügt, das Sie problemlos in C.
stevenvh 15.10.12
Ich generiere erfolgreich Wavefrom mit SPI-Kommunikation. Ich habe Probleme beim Lesen von ADC-Werten nur mit SPI. Ich muss Bit Banging für beide oder nur zum Lesen von ADC-Werten verwenden. Kannst du dir meinen Code ansehen, um 8 Bit zu senden, ist es zu schreiben. aber ich bin verwirrend, wie man es benutzt. Kann ich diesen Code direkt anstelle meines SPI-Codes zum Einrichten registrieren.
Verendra
@Steven - das Diagramm, das Sie zeigen, ist MSB zuerst, also müssen Sie von 7 nach links verschieben und von 0 nach links verschieben. Ich weiß, dass es keinen Standard gibt, also kann es LSB zuerst sein, aber ich denke, die meisten SPI-Peripheriegeräte tun es auf diese Weise .
Oli Glaser
2
@Oli - guter Punkt, das habe ich verpasst. Ich werde es reparieren, danke für das Feedback. Der Grund, warum es keinen Standard gibt, ist, dass es keine Rolle spielt, solange die Anzahl der übertragenen Bits der Länge des Schieberegisters entspricht. In letzter Zeit haben einige Mikrocontroller (wie NXP Cortec-M3) ein Schieberegister mit variabler Länge, und dann kann die Richtung eine Rolle spielen. IIRC im AVR können Sie zuerst MSB oder zuerst LSB auswählen.
Stevenvh
6

Bit-Banging bezieht sich auf das Konzept, dass die Signale, die von einem Gerät ausgehen oder in ein Gerät gelangen, eher von Software als von Hardware erzeugt / abgetastet werden. Natürlich ist etwas Hardware erforderlich, aber wenn Bit-Banging verwendet wird, ist die einzige Hardware für jeden Ausgang ein Latch, das von der Software explizit gesetzt oder gelöscht werden kann, und die einzige Hardware für jeden Eingang ist eine Schnittstelle, über die die Software testen kann, ob dies der Fall ist high oder low (und führen normalerweise eine bedingte Verzweigung für einen Zustand aus, jedoch nicht für den anderen).

Die maximale Geschwindigkeit, die mit Bit-Banging erreicht werden kann, ist im Allgemeinen ein Bruchteil dessen, was mit speziell entwickelter Hardware erreicht werden könnte. Außerhalb der durch die Prozessorgeschwindigkeit auferlegten Einschränkungen ist Bit-Banging jedoch viel vielseitiger und kann unter bestimmten Umständen verwendet werden wo Universalhardware nicht ganz geeignet ist und Spezialhardware nicht kostengünstig wäre.

Beispielsweise haben viele Steuerungen einen "SPI-artigen" Port, der sich im wesentlichen wie folgt verhält: Wenn ein Byte in ein bestimmtes Register geschrieben wird, erzeugt die Hardware eine gewisse Anzahl von Taktimpulsen (typischerweise acht), die ein Datenbit auf dem austakten Vorderflanke jedes Taktimpulses und Abtasten eines ankommenden Datenbits auf der Hinterflanke. Im Allgemeinen ermöglichen die SPI-Ports der Controller die Konfiguration einer Vielzahl von Funktionen. In einigen Fällen kann es jedoch erforderlich sein, einen Prozessor an ein Gerät anzuschließen, das ungewöhnliche Aktionen ausführt. Ein Gerät kann erfordern, dass Datenbits in Vielfachen anders als acht verarbeitet werden, oder es kann erfordern, dass Daten an derselben Taktflanke ausgegeben und abgetastet werden, oder es kann eine andere ungewöhnliche Anforderung haben. Wenn die spezielle Hardware auf dem Controller, den Sie verwenden, Ihre genauen Anforderungen erfüllen kann, großartig (einige bieten eine konfigurierbare Anzahl von Bits, separat konfigurierbare Sende- und Empfangszeiten usw.) Wenn nicht, kann Bit-Banging hilfreich sein. Abhängig vom Controller dauert das Bit-Banging einer SPI-Schnittstelle oft 2-10-mal so lange, bis die Hardware damit fertig ist. Wenn die Anforderungen jedoch nicht mit der Hardware übereinstimmen, ist der langsamere Datenaustausch möglicherweise besser als überhaupt nicht in der Lage zu sein.

Bei Bit-Banged-Designs ist zu beachten, dass sie am einfachsten und robustesten sind, wenn entweder die Geräte, mit denen kommuniziert wird, auf den Bit-Banging-Controller warten, um ihr gesamtes Timing zu generieren, oder wenn der Controller dies zulässt Warten Sie ohne Ablenkung, bis ein Ereignis eintrifft, und stellen Sie sicher, dass es in der Lage ist, alles zu tun, was für dieses Ereignis erforderlich ist, bevor ein anderes Ereignis eintrifft, auf das es reagieren muss. Sie sind viel weniger robust, wenn ein Gerät in einem relativ kurzen Zeitraum auf externe Reize reagieren muss, aber nicht 100% seiner Energie auf solche Reize ausgeben kann.

Angenommen, ein Prozessor soll Daten im UART-Stil seriell mit einer Rate übertragen, die im Verhältnis zu seiner Taktgeschwindigkeit sehr hoch ist (z. B. möchte ein PIC, der 8.192 Anweisungen pro Sekunde ausführt, Daten mit 1200 bps ausgeben). Wenn keine Interrupts aktiviert sind, ist eine solche Übertragung nicht schwierig (ein Bit alle sieben Befehlszyklen takten). Wenn ein PIC nichts anderes tut, als auf ein eingehendes 1200-Bit / s-Datenbyte zu warten, kann er eine 3-Zyklus-Schleife ausführen, die auf das Startbit wartet, und dann fortfahren, die Daten in Intervallen von sieben Zyklen einzutakten. In der Tat, wenn ein PIC ein Datenbyte zum Senden bereit hätte, wenn ein eingehendes Datenbyte ankommt, würden sieben Zyklen pro Bit ausreichen, damit der PIC sein Datenbyte gleichzeitig mit dem Lesen des eingehenden Bytes sendet. Gleichfalls,wenn eine solche Antwort einen festen Zeitpunkt in Bezug auf die ursprüngliche Übertragung hätte . Auf der anderen Seite würde es für PICs, die so schnell arbeiten, keine Möglichkeit geben, Bit-Bang-Kommunikationen so abzuwickeln, dass jedes Gerät zu einem Zeitpunkt senden kann, zu dem es passt (im Gegensatz zu einem Gerät, das senden kann, wenn es sieht) fit sein und tun, was immer es will, wenn es nicht sendet, und ein Gerät, das den größten Teil seiner Zeit damit verbringen müsste, nichts anderes zu tun, als auf Übertragungen vom ersten Gerät zu warten).

Superkatze
quelle