Skip to main content
added 666 characters in body
Source Link

CD4021 is a synchronous shift register. It requires a clock for both serial shifts and parallel loads. You're not clocking the load.

To latch parallel data:

  1. Set PAR/#SER to 1 (par).
  2. Toggle the clock (0, then 1) to latch.

To shift serial data:

  1. Set PAR/#SER to 0 (ser).
  2. Read Q7 and shift into the variable.
  3. Toggle the clock (0, then 1).
  4. Repeat 2-3 a total of 8 times.

Readable C code for that might look as follows:

#include <avr/cpufunc.h> static __attribute__((noinline)) void SR_DELAY(void) { _NOP(); _NOP(); _NOP(); _NOP(); } #define SR_PAR() do { PORTD |= 0x80; SR_DELAY(); } while (0) #define SR_SER() do { PORTD &= ~0x80; SR_DELAY(); } while (0) #define SR_CLK_PULSE() do { PORTD &= ~0x40; SR_DELAY(); PORTD |= 0x40; SR_DELAY(); } while (0) #define SR_BIT() (PIND & 0x10) uint8_t read_controller() { SR_PAR(); SR_CLK_PULSE(); SR_SER(); uint8_t result = 0; for (uint8_t i = 0; i < 8; ++i) { if (SR_BIT()) result |= 1; result <<= 1; SR_CLK_PULSE(); } return result; } ``` 

CD4021 is a synchronous shift register. It requires a clock for both serial shifts and parallel loads. You're not clocking the load.

To latch parallel data:

  1. Set PAR/#SER to 1 (par).
  2. Toggle the clock (0, then 1) to latch.

To shift serial data:

  1. Set PAR/#SER to 0 (ser).
  2. Read Q7 and shift into the variable.
  3. Toggle the clock (0, then 1).
  4. Repeat 2-3 a total of 8 times.

CD4021 is a synchronous shift register. It requires a clock for both serial shifts and parallel loads. You're not clocking the load.

To latch parallel data:

  1. Set PAR/#SER to 1 (par).
  2. Toggle the clock (0, then 1) to latch.

To shift serial data:

  1. Set PAR/#SER to 0 (ser).
  2. Read Q7 and shift into the variable.
  3. Toggle the clock (0, then 1).
  4. Repeat 2-3 a total of 8 times.

Readable C code for that might look as follows:

#include <avr/cpufunc.h> static __attribute__((noinline)) void SR_DELAY(void) { _NOP(); _NOP(); _NOP(); _NOP(); } #define SR_PAR() do { PORTD |= 0x80; SR_DELAY(); } while (0) #define SR_SER() do { PORTD &= ~0x80; SR_DELAY(); } while (0) #define SR_CLK_PULSE() do { PORTD &= ~0x40; SR_DELAY(); PORTD |= 0x40; SR_DELAY(); } while (0) #define SR_BIT() (PIND & 0x10) uint8_t read_controller() { SR_PAR(); SR_CLK_PULSE(); SR_SER(); uint8_t result = 0; for (uint8_t i = 0; i < 8; ++i) { if (SR_BIT()) result |= 1; result <<= 1; SR_CLK_PULSE(); } return result; } ``` 
Source Link

CD4021 is a synchronous shift register. It requires a clock for both serial shifts and parallel loads. You're not clocking the load.

To latch parallel data:

  1. Set PAR/#SER to 1 (par).
  2. Toggle the clock (0, then 1) to latch.

To shift serial data:

  1. Set PAR/#SER to 0 (ser).
  2. Read Q7 and shift into the variable.
  3. Toggle the clock (0, then 1).
  4. Repeat 2-3 a total of 8 times.