728x90

728x90

Sunday, February 15, 2026

ATMega644P SPI and SN74HC165 Shift Registers Example

Overview

The SNx4HC165 devices are 8-bit parallel-load shift registers that, when clocked, shift the data toward a serial (QH) output. Parallel-in access to each stage is provided by eight individual direct data (A-H) inputs that are enabled by a low level at the shift/load (SH/LD) input. The SNx4HC165 devices also feature a clock-inhibit (CLK INH) function and a complementary serial (QH) output. Clocking is accomplished by a low-to-high transition of the clock (CLK) input while SH/LD is held high and CLK INH is held low. The functions of CLK and CLK INH are interchangeable. Because a low CLK and a low-to-high transition of CLK INH also accomplish clocking, CLK INH must be changed to the high level only while CLK is high. Parallel loading is inhibited when SH/LD is held high. While SH/LD is low, the parallel inputs to the register are enabled independently of the levels of the CLK, CLK INH, or serial (SER) inputs. 

ATMega644P SPI and SN74HC165 Shift Registers Example 

 

This input expansion chip can be used in Programmable Logic Controllers, Appliances, Video Display Systems, Keyboards etc. This old digital IC is very easy to use with a typical 8-bit MCU since it has a small footprint and its Dual In-Line Package version. It is widely available at very low cost.


16-pin (N) package image
A DIP-16 Sample

 It has DIP-16 footprint and various SMD packages.

 

ATMega644P SPI and SN74HC165 Shift Registers Example
Pin Configuration and Functions

 It made from some digital logic gates and flip-flops.

Logic Diagram Positive Logic
Logic Diagram Positive Logic

 To load parallel input data (H:A) take a look at the timing diagram below.

ATMega644P SPI and SN74HC165 Shift Registers Example
Load Shift Sequence

Typically the SI (Serial Data In) is ignored or wires it GND. The Clock Inhabit (CLK INH) must wired to GND. At the transition from logic low to logic high of SH/LD pin allows parallel data loading and serial data shifting out via Serial Data Out (SO) pin.

In this example the ATMega644P read parallel input data of an SN74HC165N and display it on PORTD.

Source Code "main.c":

  1. /*
  2. * 12-spi_sn74hc165.c
  3. *
  4. * Created: 2/16/2026 11:12:37 AM
  5. * Author : Admin
  6. */

  7. #include <avr/io.h>
  8. #include <util/delay.h>
  9. #define F_CPU 16000000UL

  10. #define DDR_SPI DDRB
  11. #define PRT_SPI PORTB

  12. #define DD_SS 4
  13. #define DD_MOSI 5
  14. #define DD_MISO 6
  15. #define DD_SCK 7


  16. void SPI_MasterInit(void)
  17. {
  18. /* Set MOSI and SCK output, all others input */
  19. DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK)|(1<<DD_SS);
  20. /* Enable SPI, Master, set clock rate fck/16 */
  21. SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
  22. }

  23. void SPI_MasterTransmit(char cData)
  24. {
  25. /* Start transmission */
  26. SPDR = cData;
  27. /* Wait for transmission complete */
  28. while(!(SPSR & (1<<SPIF)))
  29. ;
  30. }

  31. void SPI_SlaveInit(void)
  32. {
  33. /* Set MISO output, all others input */
  34. DDR_SPI = (1<<DD_MISO);
  35. /* Enable SPI */
  36. SPCR = (1<<SPE);
  37. }
  38. char SPI_SlaveReceive(void)
  39. {
  40. /* Wait for reception complete */
  41. while(!(SPSR & (1<<SPIF)))
  42. ;
  43. /* Return Data Register */
  44. return SPDR;
  45. }


  46. int main(void)
  47. {
  48. /* Replace with your application code */
  49. SPI_MasterInit();
  50. //PRT_SPI|=(1<<DD_SS);
  51. DDRD=0xFF;
  52. _delay_ms(1000);
  53. while (1)
  54. {
  55. PRT_SPI&=~(1<<DD_SS);
  56. PRT_SPI|=(1<<DD_SS);
  57. SPI_MasterTransmit(0x00);
  58. PORTD=SPI_SlaveReceive();
  59. _delay_ms(100);
  60. }
  61. }




I don't have this chip because local stores don't stock this part. So I can test it only in simulator. 

ATMega644P SPI and SN74HC165 Shift Registers Example 


ATMega644P SPI and SN74HC165 Shift Registers Example
SPI Transfer and Receive One Byte Of Data Waveform

We can connect multiple SN74HC165N chips using a daisy-chain configuration. Here I scan two input ports of two SN74HC165N. So the master MCU needs to shift 16 clock cycles (two bytes of data).

ATMega644P SPI and SN74HC165 Shift Registers Example
Using Two SN74HC165N chips (Daisy-Chain)
ATMega644P SPI and SN74HC165 Shift Registers Example
SPI Waveform

Source Code "main.c":

  1. /*
  2. * sn74hc165_2.c
  3. *
  4. * Created: 2/16/2026 12:49:13 PM
  5. * Author : Admin
  6. */

  7. #include <avr/io.h>
  8. #include <util/delay.h>
  9. #define F_CPU 16000000UL

  10. #define DDR_SPI DDRB
  11. #define PRT_SPI PORTB

  12. #define DD_SS 4
  13. #define DD_MOSI 5
  14. #define DD_MISO 6
  15. #define DD_SCK 7


  16. void SPI_MasterInit(void)
  17. {
  18. /* Set MOSI and SCK output, all others input */
  19. DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK)|(1<<DD_SS);
  20. /* Enable SPI, Master, set clock rate fck/16 */
  21. SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
  22. }

  23. void SPI_MasterTransmit(char cData)
  24. {
  25. /* Start transmission */
  26. SPDR = cData;
  27. /* Wait for transmission complete */
  28. while(!(SPSR & (1<<SPIF)))
  29. ;
  30. }

  31. void SPI_SlaveInit(void)
  32. {
  33. /* Set MISO output, all others input */
  34. DDR_SPI = (1<<DD_MISO);
  35. /* Enable SPI */
  36. SPCR = (1<<SPE);
  37. }
  38. char SPI_SlaveReceive(void)
  39. {
  40. /* Wait for reception complete */
  41. while(!(SPSR & (1<<SPIF)))
  42. ;
  43. /* Return Data Register */
  44. return SPDR;
  45. }


  46. int main(void)
  47. {
  48. /* Replace with your application code */
  49. SPI_MasterInit();
  50. //PRT_SPI|=(1<<DD_SS);
  51. DDRD=0xFF;
  52. DDRC=0xFF;
  53. while (1)
  54. {
  55. PRT_SPI&=~(1<<DD_SS);
  56. PRT_SPI|=(1<<DD_SS);
  57. SPI_MasterTransmit(0x00);
  58. PORTD=SPI_SlaveReceive();
  59. SPI_MasterTransmit(0x00);
  60. PORTC=SPI_SlaveReceive();
  61. _delay_ms(100);
  62. }
  63. }




For PIC Micro-controller users check this post:

For ATMega32 AVR micro-controller user check this post:



 

 

No comments:

Post a Comment

320x50

Search This Blog

tyro-728x90