AVR Embedded Tutorial - Shiftregister/de: what changed
Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.
| Old | New | Line | |
|---|---|---|---|
| 1 | 1 | # Schieberegister | |
| 2 | 2 | ||
| 3 | 3 | Der Beispielcode ist für ein ATtiny44. | |
| 4 | 4 | ||
| 5 | 5 | Schieberegister werden folgende verwendet: | |
| 6 | 6 | ||
| 7 | 7 | - Lesen: 74HC165 | |
| 8 | 8 | - Schreiben: 74HC595. | |
| 9 | 9 | ||
| 10 | 10 | > **Warning:** Die Leseroutine ist **nicht** kompatibel mit Arduino **shiftIn(...** ! Die Arduino Lesefunktion ist für andere Schieberegister. Der Clock muss anders angesteuert werden. | |
| 11 | 11 | ||
| 12 | 12 | Will man **MSB** und **LSB** vertauschen, dann muss man dementsprechend einfach **to** mit **downto** austauschen. | |
| 13 | 13 | ||
| 14 | 14 | ## Portzugriffe | |
| 15 | 15 | ||
| 16 | 16 | Wie die Schieberegisterbefehle auf die Ports zugreifen, siehe hier: [[AVR Embedded Tutorial - Simple GPIO on and off output/de|GPIO-Ausgabe]].\ | |
| 17 | 17 | Nicht vergessen die Ausgänge auch als Ausgang einzustellen (DDRx). | |
| 18 | 18 | ||
| 19 | 19 | ## Port-Konstanten | |
| 20 | 20 | ||
| 21 | 21 | Die verwendeten Pins des ATtiny44 und der Shiftregister. Beim AVR kann man beliebige Pins nehmen. Ich habe die Ports, ausgenommen des Data-Ports, global deklariert, somit ist der Zugriff aus die Schiftregister ein wenig schneller. Wen man sie lokal übergeben würde, würde alles komplizierter werden, da wir direkten Portzugriff verwenden. Arduino macht dies anders, aber dafür ist es etwa um den Faktor 10x langsamer. | |
| 22 | 22 | ||
| 23 | - | ||
| 24 | 23 | <thead> | |
| 25 | - | ||
| 26 | - | ||
| 27 | - | ||
| 28 | - | ||
| 29 | - | ||
| 30 | - | ||
| 24 | + | ||
| 31 | 25 | </thead> | |
| 32 | 26 | <tbody> | |
| 33 | - | ||
| 34 | - | ||
| 35 | - | ||
| 36 | - | ||
| 37 | - | ||
| 38 | - | ||
| 39 | - | ||
| 40 | - | ||
| 41 | - | ||
| 42 | - | ||
| 43 | - | ||
| 44 | - | ||
| 45 | - | ||
| 46 | - | ||
| 47 | - | ||
| 48 | - | ||
| 49 | - | ||
| 50 | - | ||
| 51 | - | ||
| 52 | - | ||
| 53 | - | ||
| 54 | - | ||
| 55 | - | ||
| 56 | - | ||
| 57 | - | ||
| 58 | - | ||
| 59 | - | ||
| 60 | - | ||
| 61 | - | ||
| 62 | - | ||
| 63 | - | ||
| 64 | - | ||
| 65 | - | ||
| 66 | - | ||
| 67 | - | ||
| 68 | - | ||
| 69 | - | ||
| 70 | - | ||
| 71 | - | ||
| 72 | - | ||
| 73 | - | ||
| 74 | - | ||
| 75 | - | ||
| 76 | - | ||
| 77 | - | ||
| 27 | + | ||
| 78 | 28 | </tbody> | |
| 79 | - | ||
| 80 | 29 | ||
| 81 | 30 | Für den Port wird eine Variable deklariert, dies hat den Vorteil, das man nicht alle Ports in den Shiftregister-Funktionen ändern muss. | |
| 82 | 31 | ||
| 83 | 32 | ``` pascal | |
| 84 | 33 | var | |
| 85 | 34 | shiftPORT: byte absolute PORTA; | |
| 86 | 35 | shiftDDR: byte absolute DDRA; | |
| 87 | 36 | shiftPIN: byte absolute PINA; | |
| 88 | 37 | const | |
| 89 | 38 | dataOutPin = 0; | |
| 90 | 39 | dataInPin = 1; | |
| 91 | 40 | latchPin = 2; | |
| 92 | 41 | clockPin = 3; | |
| 93 | 42 | ``` | |
| 94 | 43 | ||
| 95 | 44 | ## Schieberegister schreiben 74HC595 | |
| 96 | 45 | ||
| 97 | 46 | ``` pascal | |
| 98 | 47 | procedure shiftOut595(val: Byte); | |
| 99 | 48 | var | |
| 100 | 49 | i: Byte; | |
| 101 | 50 | begin | |
| 102 | 51 | for i := 7 downto 0 do begin // MSBFIRST | |
| 103 | 52 | if (val and (1 shl i)) <> 0 then begin | |
| 104 | 53 | shiftPORT := shiftPORT or (1 shl dataOutPin); | |
| 105 | 54 | end else begin | |
| 106 | 55 | shiftPORT := shiftPORT and not (1 shl dataOutPin); | |
| 107 | 56 | end; | |
| 108 | 57 | shiftPORT := shiftPORT or (1 shl clockPin); | |
| 109 | 58 | shiftPORT := shiftPORT and not (1 shl clockPin); | |
| 110 | 59 | end; | |
| 111 | 60 | end; | |
| 112 | 61 | ``` | |
| 113 | 62 | ||
| 114 | 63 | ## Schieberegister lesen 74HC165 | |
| 115 | 64 | ||
| 116 | 65 | ``` pascal | |
| 117 | 66 | function ShiftIn165: Byte; | |
| 118 | 67 | var | |
| 119 | 68 | i: Byte; | |
| 120 | 69 | begin | |
| 121 | 70 | Result := 0; | |
| 122 | 71 | for i := 0 to 7 do begin // LSBFIRST | |
| 123 | 72 | Result := (Result shl 1) or ((shiftPIN and (1 shl dataInPin)) shr dataInPin); | |
| 124 | 73 | shiftPORT := shiftPORT or (1 shl clockPin); | |
| 125 | 74 | shiftPORT := shiftPORT and not (1 shl clockPin); | |
| 126 | 75 | end; | |
| 127 | 76 | end; | |
| 128 | 77 | ``` | |
| 129 | 78 | ||
| 130 | 79 | ## Schieberegister Arduino | |
| 131 | 80 | ||
| 132 | 81 | Diese Version entspricht dem **shiftIn** von Arduino. | |
| 133 | 82 | ||
| 134 | 83 | ``` pascal | |
| 135 | 84 | function ShiftIn: Byte; | |
| 136 | 85 | var | |
| 137 | 86 | i: Byte; | |
| 138 | 87 | begin | |
| 139 | 88 | Result := 0; | |
| 140 | 89 | for i := 0 to 7 do begin // LSBFIRST | |
| 141 | 90 | shiftPORT := shiftPORT or (1 shl clockPin); | |
| 142 | 91 | Result := (Result shl 1) or ((shiftPIN and (1 shl dataInPin)) shr dataInPin); | |
| 143 | 92 | shiftPORT := shiftPORT and not (1 shl clockPin); | |
| 144 | 93 | end; | |
| 145 | 94 | end; | |
| 146 | 95 | ``` | |
| 147 | 96 | ||
| 148 | 97 | ## Beispiel für die Verwendung der Schieberegister | |
| 149 | 98 | ||
| 150 | 99 | ### Lesen von einem Schieberegister | |
| 151 | 100 | ||
| 152 | 101 | Bevor man das Schieberegister auslesen kann, muss der Portzustand in das Latchregister geschrieben werden, dies geschieht über den LatchPin. | |
| 153 | 102 | ||
| 154 | 103 | #### Beispiel für ein 74HC165 | |
| 155 | 104 | ||
| 156 | 105 | ``` pascal | |
| 157 | 106 | var | |
| 158 | 107 | b: Byte; | |
| 159 | 108 | begin | |
| 160 | 109 | ||
| 161 | 110 | // Daten in Latch | |
| 162 | 111 | shiftPORT := shiftPORT and not (1 shl latchPin); | |
| 163 | 112 | shiftPORT := shiftPORT or (1 shl latchPin); | |
| 164 | 113 | ||
| 165 | 114 | // Schieberegister auslesen | |
| 166 | 115 | b := ShiftIn74HC165; | |
| 167 | 116 | ``` | |
| 168 | 117 | ||
| 169 | 118 | #### Beispiel für kaskadierte 74HC165 | |
| 170 | 119 | ||
| 171 | 120 | ``` pascal | |
| 172 | 121 | var | |
| 173 | 122 | b0, bn: Byte; | |
| 174 | 123 | begin | |
| 175 | 124 | ||
| 176 | 125 | // Daten in Latch | |
| 177 | 126 | shiftPORT := shiftPORT and not (1 shl latchPin); | |
| 178 | 127 | shiftPORT := shiftPORT or (1 shl latchPin); | |
| 179 | 128 | ||
| 180 | 129 | // Schieberegister auslesen | |
| 181 | 130 | b0 := ShiftIn74HC165; | |
| 182 | 131 | //... | |
| 183 | 132 | bn := ShiftIn74HC165; | |
| 184 | 133 | ``` | |
| 185 | 134 | ||
| 186 | 135 | ### Schreiben in ein Schieberegister | |
| 187 | 136 | ||
| 188 | 137 | Wen die Daten in das Schieberegister geschrieben sind, muss man noch den Latch Takten, das die aktuellen Ausgänge aktiv werden. | |
| 189 | 138 | ||
| 190 | 139 | #### Beispiel für ein 74HC595 | |
| 191 | 140 | ||
| 192 | 141 | ``` pascal | |
| 193 | 142 | var | |
| 194 | 143 | b: Byte; | |
| 195 | 144 | begin | |
| 196 | 145 | b := 123; | |
| 197 | 146 | ||
| 198 | 147 | // Schieberegister schreiben | |
| 199 | 148 | shiftOut595(b); | |
| 200 | 149 | ||
| 201 | 150 | // Daten in Latch | |
| 202 | 151 | shiftPORT := shiftPORT and not (1 shl latchPin); | |
| 203 | 152 | shiftPORT := shiftPORT or (1 shl latchPin); | |
| 204 | 153 | ``` | |
| 205 | 154 | ||
| 206 | 155 | #### Beispiel für kaskadierte 74HC595 | |
| 207 | 156 | ||
| 208 | 157 | ``` pascal | |
| 209 | 158 | var | |
| 210 | 159 | b0, bn: Byte; | |
| 211 | 160 | begin | |
| 212 | 161 | b0 := 123; | |
| 213 | 162 | //... | |
| 214 | 163 | bn := 789; | |
| 215 | 164 | ||
| 216 | 165 | // Schieberegister schreiben | |
| 217 | 166 | shiftOut595(b0); | |
| 218 | 167 | // ... | |
| 219 | 168 | shiftOut595(bn); | |
| 220 | 169 | ||
| 221 | 170 | // Daten in Latch | |
| 222 | 171 | shiftPORT := shiftPORT and not (1 shl latchPin); | |
| 223 | 172 | shiftPORT := shiftPORT or (1 shl latchPin); | |
| 224 | 173 | ``` | |
| 225 | 174 | ||
| 226 | 175 | # Siehe auch | |
| 227 | 176 | ||
| 228 | 177 | - Übersichtseite [[AVR Embedded Tutorial/de|AVR Embedded Tutorials]] | |
| 229 | 178 | - [[AVR Embedded Tutorial - SPI Shiftregister/de|SPI Schieberegister]] - Schieberegister 74HC595 über SPI ansteuern (starke Beschleunigung). | |
| 230 | 179 | ||
| 231 | 180 | Autor: Mathias | |
| 232 | 181 | ||
| 233 | 182 | --- | |
| 234 | 183 | *From the Free Pascal wiki, page "AVR Embedded Tutorial - Shiftregister/de", as it stood on 2023-08-03 after a change by Mathias, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).* | |
| 235 | 184 | Category: AVR/de | |
| 236 | 185 | Category: Arduino/de | |
| 237 | 186 | Category: Deutsch | |
| 238 | 187 | Category: Embedded/de | |
| 239 | 188 | Category: Tutorials/de |
