Sign in Join
Wiki copytemporary

AVR Embedded Tutorial - Shiftregister: what changed

Revision 2 to 3. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11# Shift Registers
22
33The sample code is for an [ATtiny44](https://upload.chipdatas.com/root/pdf/Atmel-7701_Automotive-Microcontrollers-ATtiny24-44-84_Datasheet_eXTunT.pdf) and the shift registers used are the 74HC165 for reading and the 74HC595 for writing.
44
55> **Warning:** The read routine is **not** compatible with Arduino **shiftIn (...**! The Arduino read function is for other shift registers. The clock must be controlled differently.
66
77If you want to swap **MSB** to **LSB**, you simply have to swap **downto** to **to**.
88
99# Port access
1010
1111For how the shift register commands access the ports, see here: [[AVR Embedded Tutorial - Simple GPIO on and off output|GPIO output]].
1212
1313Do not forget to set the outputs as outputs (**DDRx**).
1414
1515# Port constants
1616
1717The pins used for the ATtiny44 and the shift register. With the AVR you can use any pins. I have declared the ports, except the data port, globally, so access from the shift registers is a little faster. If you declared them locally, everything would be more complicated because we use direct port access. Arduino does this differently, but it is about 10 times slower.
1818
19-<thead>
20-
21-</thead>
22-<tbody>
23-
24-</tbody>
19+| IC | Attiny44 | | 74HC165 | | 74HC595 | |
20+|---|---|---|---|---|---|---|
21+| | Pin No. | Description | Pin No. | Description | Pin No. | Description |
22+| dataOutPin | 13 | PA0 | | | 14 | DS |
23+| dataInPin | 12 | PA1 | 10 | DS | | |
24+| latchPin | 11 | PA2 | 1 | PL | 12 | ST_CP |
25+| clockPin | 10 | PA3 | 2 | CP | 11 | SH_CP |
2526
2627A variable is declared for the port, this has the advantage that you do not have to change all ports in the shift register functions.
2728
2829``` pascal
2930 var
3031 shiftPORT : byte absolute PORTA;
3132 shiftDDR : byte absolute DDRA;
3233 shiftPIN : byte absolute PINA;
3334 const
3435 dataOutPin = 0;
3536 dataInPin = 1;
3637 latchPin = 2;
3738 clockPin = 3;
3839```
3940
4041# Shift register write 74HC595
4142
4243``` pascal
4344procedure shiftOut595(val : byte);
4445 var
4546 i : byte;
4647begin
4748 for i : = 7 downto 0 do // MSB FIRST
4849 begin
4950 if(val and (1 shl i)) <> 0 then
5051 begin
5152 shiftPORT := shiftPORT or (1 shl dataOutPin);
5253 end
5354 else
5455 begin
5556 shiftPORT := shiftPORT and not (1 shl dataOutPin);
5657 end;
5758
5859 shiftPORT := shiftPORT or (1 shl clockPin);
5960 shiftPORT := shiftPORT and not (1 shl clockPin);
6061 end;
6162end;
6263```
6364
6465# Shift register read 74HC165
6566
6667``` pascal
6768function ShiftIn165 : byte;
6869 var
6970 i : byte;
7071 begin
7172 Result := 0;
7273
7374 for i := 0 to 7 do // LSB FIRST
7475 begin
7576 Result := (Result shl 1) or ((shiftPIN and (1 shl dataInPin)) shr dataInPin);
7677 shiftPORT := shiftPORT or (1 shl clockPin);
7778 shiftPORT := shiftPORT and not (1 shl clockPin);
7879 end;
7980 end ;
8081```
8182
8283# Arduino shift register
8384
8485This version corresponds to Arduino's **shiftIn**.
8586
8687``` pascal
8788function ShiftIn : byte;
8889 var
8990 i : byte;
9091begin
9192 Result := 0;
9293
9394 for i := 0 to 7 do // LSB FIRST
9495 begin
9596 shiftPORT := shiftPORT or (1 shl clockPin);
9697 Result := (Result shl 1) or ((shiftPIN and (1 shl dataInPin)) shr dataInPin);
9798 shiftPORT := shiftPORT and not (1 shl clockPin);
9899 end;
99100end;
100101```
101102
102103# Shift register examples
103104
104105## Read from a shift register
105106
106107Before the shift register can be read out, the port status must be written to the latch register, this is done via the LatchPin.
107108
108109### Example for a 74HC165
109110
110111``` pascal
111112 var
112113 b : byte;
113114 begin
114115
115116 // Latch data
116117 shiftPORT := shiftPORT and not (1 shl latchPin);
117118 shiftPORT := shiftPORT or (1 shl latchPin);
118119
119120 // Read shift register
120121 b := ShiftIn74HC165;
121122```
122123
123124### Example for cascaded 74HC165
124125
125126``` pascal
126127 var
127128 b0, bn : byte;
128129 begin
129130
130131 // Latch data
131132 shiftPORT := shiftPORT and not (1 shl latchPin);
132133 shiftPORT := shiftPORT or (1 shl latchPin);
133134
134135 // Read shift register
135136 b0 := ShiftIn74HC165;
136137
137138 // ...
138139
139140 bn := ShiftIn74HC165;
140141```
141142
142143## Write to a shift register
143144
144145If the data is written into the shift register, you have to add the latch clock that the current outputs become active.
145146
146147### Example for a 74HC595
147148
148149``` pascal
149150 var
150151 b : byte;
151152 begin
152153 b := 123;
153154
154155 // Write shift register
155156 shiftOut595(b);
156157
157158 // Latch data
158159 shiftPORT := shiftPORT and not (1 shl latchPin);
159160 shiftPORT := shiftPORT or (1 shl latchPin);
160161```
161162
162163### Example for cascaded 74HC595
163164
164165``` pascal
165166 var
166167 b0, bn : byte;
167168 begin
168169 b0 := 123;
169170
170171 // ...
171172
172173 bn := 789;
173174
174175 // Write shift register
175176 shiftOut595(b0);
176177
177178 // ...
178179
179180 shiftOut595(bn);
180181
181182 // Latch data
182183 shiftPORT := shiftPORT and not (1 shl latchPin);
183184 shiftPORT := shiftPORT or (1 shl latchPin);
184185```
185186
186187# See also
187188
188189- [[AVR Embedded Tutorial|AVR Embedded Tutorials]] - Overview
189190- [[AVR Embedded Tutorial - SPI Shiftregister|SPI shift register]] - control shift register 74HC595 via SPI (very fast).
190191
191192---
192193*From the Free Pascal wiki, page "AVR Embedded Tutorial - Shiftregister", as it stood on 2023-08-02 after a change by Zave2023, 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).*
193194Category: AVR
194195Category: Arduino
195196Category: Embedded
196197Category: Tutorials

Back to history