(→C-Code) |
K (→Funktionen) |
||
Zeile 23: | Zeile 23: | ||
;CLR (X): Setzt Ausgang X auf LOW (PORT-Register) | ;CLR (X): Setzt Ausgang X auf LOW (PORT-Register) | ||
− | ==Funktionen== | + | ==Makros,Datenstrukturen,Funktionen== |
;<tt>#define SERPA_SIZE</tt>: Define für Anzahl der auszugebenden Bytes | ;<tt>#define SERPA_SIZE</tt>: Define für Anzahl der auszugebenden Bytes | ||
;<tt>extern unsigned char serpa[SERPA_SIZE]</tt>: Das Array, dessen Bytes ausgegeben werden. <tt>serpa[0]</tt> landet in dem Portexpander-IC, das direkt am Controller sitzt. Bit0 erscheint jeweils an Ausgang QA, Bit7 erscheint am Ausgang QH, etc. | ;<tt>extern unsigned char serpa[SERPA_SIZE]</tt>: Das Array, dessen Bytes ausgegeben werden. <tt>serpa[0]</tt> landet in dem Portexpander-IC, das direkt am Controller sitzt. Bit0 erscheint jeweils an Ausgang QA, Bit7 erscheint am Ausgang QH, etc. |
Version vom 9. Januar 2006, 22:51 Uhr
An diesem Artikel arbeitet gerade Mitglied SprinterSB.
Am besten momentan noch keine gravierenden Ergänzungen / Änderungen vornehmen. Dieser Hinweis verschwindet wenn der Autor soweit ist. Sollte dieser Hinweis länger als drei Tage auf einer Seite sein, bitte beim Autor SprinterSB per PM / Mail oder Forum nachfragen ob er vergessen wurde. |
- Vorteile
- schnell
- preiswert
- einfach anzusteuern (auch ohne Hardware-Unterstützung)
- modular aufgebaut und erweiterbar
- alle Ports können gleichzeitig geschaltet werden, auch 100 Stück
- SPI-Interface und ISP-Pins können verwendet werden
- Bus hat nur 3 Leitungen, dadurch kein kompliziertes Layout mit vielen Leitungen
- Nachteile
- bei dieser Version nur Ausgabe möglich
Inhaltsverzeichnis
Schaltplan
C-Code
Der folgende C-Code ist Pseudocode, was Setzen der Ports angeht. Die entsprechenden Befehle sind durch die richtigen C-Befehle für diese Ports zu ersetzen.
- MAKE_OUT (X)
- Schaltet X als Ausgang (DDR-Register)
- SET (X)
- Setzt Ausgang X auf HIGH (PORT-Register)
- CLR (X)
- Setzt Ausgang X auf LOW (PORT-Register)
Makros,Datenstrukturen,Funktionen
- #define SERPA_SIZE
- Define für Anzahl der auszugebenden Bytes
- extern unsigned char serpa[SERPA_SIZE]
- Das Array, dessen Bytes ausgegeben werden. serpa[0] landet in dem Portexpander-IC, das direkt am Controller sitzt. Bit0 erscheint jeweils an Ausgang QA, Bit7 erscheint am Ausgang QH, etc.
- void serpa_init()
- Initialisiert die Schnittstelle bzw. die verwendeten Ports
- void serpa_out()
- Gibt die SERPA_SIZE Bytes aus dem Array serpa aus.
serpa.h
/* SERiell nach PArallel (serpa) im SPI-Protokoll */ #ifndef _SERPA_H_ #define _SERPA_H_ /* 4 Bytes (32 Ports) */ #define SERPA_SIZE 4 extern unsigned char serpa[]; extern void serpa_out(); extern void serpa_init(); #endif /* _SERPA_H_ */
Mit SPI-Hardware
serpa.c
/* SERiell nach PArallel (serpa) mit Hardware-Unterstützung */ #include <avr/io.h> #include "serpa.h" // Array für die Daten unsigned char serpa[SERPA_SIZE]; void serpa_init() { MAKE_OUT (PORT_MOSI); MAKE_OUT (PORT_SCK); MAKE_OUT (PORT_RCK); SET (PORT_RCK); // !!! SS muss OUT sein, damit SPI nicht in Slave-Mode wechselt !!! // entfällt, falls PORT_RCK = PORT_SS MAKE_OUT (PORT_SS); // SPI als Master // High-Bits zuerst // SCK ist HIGH wenn inaktiv SPCR = _BV(SPE) | _BV(MSTR) | _BV(CPOL); // pullup an MISO vermeidet Floaten SET (PORT_MISO); // maximale Geschwindigkeit: F_CPU / 2 SPSR |= _BV(SPI2X); } void serpa_out () { unsigned char anz = SERPA_SIZE; unsigned char* serp = serpa+SERPA_SIZE; do { unsigned char data = *--serp; // SPDR schreiben startet Übertragung SPDR = data; // warten auf Ende der Übertragung für dieses Byte while (!(SPSR & (1 << SPIF))); // clear SPIF data = SPDR; } while (--anz > 0); // Strobe an RCK bringt die Daten von den Schieberegistern in die Latches CLR (PORT_RCK); SET (PORT_RCK); }
Ohne SPI-Hardware
serpa.c
/* SERiell nach PArallel (serpa) via Software */ #include "serpa.h" // Array für die Daten unsigned char serpa[SERPA_SIZE]; void serpa_init () { // Verwendete Ports auf OUT MAKE_OUT (PORT_SER); MAKE_OUT (PORT_SCK); MAKE_OUT (PORT_RCK); // SCR und RCK auf definierten Level HIGH SET (PORT_SCK); SET (PORT_RCK); } void serpa_out () { unsigned char anz = SERPA_SIZE; unsigned char* serp = serpa+SERPA_SIZE; do { unsigned char bits; unsigned char data = *--serp; // 8 Bits pro Byte rausschieben for (bits = 8; bits > 0; bits--) { CLR (PORT_SER); if (data & 0x80) { SET (PORT_SER); } data <<= 1; // Strobe an SCK schiebt Daten im Gänsemarsch // um 1 Position weiter durch alle Schieberegister CLR (PORT_SCK); SET (PORT_SCK); } } while (--anz > 0); // Strobe an RCK bringt die Daten von den Schieberegistern in die Latches CLR (PORT_RCK); SET (PORT_RCK); }