Wednesday, August 19, 2020

ATMega32 SN74HC164 Three-Digit Multiplexing Display

Multiplexing Display could be driven form controller digital output pins without any additional memory chips. However it needs at least one digital output port. In this example, I use two SN74HC164 shift register chip to store seven-segment display data, and drive each commons. It makes a multiplexing 7-Segment display that use only three micro-controller digital output pins.

For more example of using SN74HC164 chip you can check these links:

  1. ATMega32 Interfaces To SN74HC164 Shift Registers
  2. ATMega32 SPI Interfaces To SN74HC164 And LED 
  3. ATMega32 SPI Interfaces To SN74HC164 And LCD Using 3 Pins
  4. ATMega32 SN74HC164 Seven Segments Display And Switch Interfacing
  5. ATMega32 And SN74HC164 Serial Seven Segment Display

There's an input button to count the number of input pulse. It's active low input. Optionally, I use a signal source with the frequency around 5Hz as an input signal instead of push button.

ATMega32 SN74HC164 Three-Digit Multiplexing Display

Simulating Program

Controller's clock frequency is 4Mhz. It's the internal RC oscillator without additional components.

The program activate each digits before it reset the registers to refresh display data without conflicting the display output.

  1. /*
  2.  * SN74HC164MUX.c
  3.  *
  4.  * Created: 7/10/2023 2:01:24 PM
  5.  * Author : Admin
  6.  */
  7.  
  8. #include <avr/io.h>
  9.  
  10. #define F_CPU 4000000UL
  11. #include <util/delay.h>
  12.  
  13. #define SW4 4
  14. #define nRST 5
  15. #define SDAT 7
  16. #define SCLK 6
  17.  
  18. void send74hc164(unsigned char data){
  19. for(int i=0; i<8;i++){
  20. if ((data&(1<<7))==0)
  21. {
  22. PORTC&=~(1<<SDAT);
  23. }
  24. else PORTC|=(1<<SDAT);
  25. PORTC|=(1<<SCLK);
  26. for(int i=0;i<=25;i++);
  27. PORTC&=~(1<<SCLK);
  28. for(int i=0;i<=25;i++);
  29. data<<=1;
  30. }
  31. }
  32.  
  33. void nMr(void){
  34. PORTC&=~(1<<nRST);
  35. //for(int i=0;i<10;i++);
  36. PORTC|=(1<<nRST);
  37. //for(int i=0;i<10;i++);
  38. }
  39.  
  40. unsigned char cCathode[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,
  41. 0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
  42. //unsigned char cAnode[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,
  43. //0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
  44.  
  45. int main(void)
  46. {
  47. unsigned char count = 0;
  48. DDRC|=(1<<SDAT)|(1<<SCLK)|(1<<nRST);
  49. DDRC&=~(1<<SW4);
  50. PORTC|=(1<<nRST)|(1<<SW4);
  51. while (1)
  52. {
  53. if ((PINC&(1<<SW4))==0)
  54. {
  55. _delay_ms(50);
  56. count++;
  57. }
  58. send74hc164(0b11111110);
  59. send74hc164(cCathode[count/100]);
  60. _delay_ms(10);
  61. nMr();
  62.  
  63. send74hc164(0b11111101);
  64. send74hc164(cCathode[(count%100)/10]);
  65. _delay_ms(10);
  66. nMr();
  67.  
  68. send74hc164(0b11111011);
  69. send74hc164(cCathode[count%10]);
  70. _delay_ms(10);
  71. nMr();
  72. }
  73. }
  74.  
  75.  

 Click here to download its source file.



ATMega32 And SN74HC164 Serial Seven Segment Display

We can cascade the SN74HC164 chip to make a serial display with any numbers of digit. There are some more example of using this type of shift registers chip,

  1. ATMega32 Interfaces To SN74HC164 Shift Registers
  2. ATMega32 SPI Interfaces To SN74HC164 And LED 
  3. ATMega32 SPI Interfaces To SN74HC164 And LCD Using 3 Pins
  4. ATMega32 SN74HC164 Seven Segments Display And Switch Interfacing.

In this example, I use three registers connecting with individual seven-segment display. I use an input connects to PC5 to count external pulse.

ATMega32 And SN74HC164 Serial Seven Segment Display
Simulating Program

 I wrote a C program to make software bit-banging that send serial data to shift registers. 

  1. /*
  2.  * SN74HC164SerialSD.c
  3.  *
  4.  * Created: 7/9/2023 1:20:09 PM
  5.  * Author : Admin
  6.  */
  7.  
  8. #include <avr/io.h>
  9.  
  10. #define SW1 5
  11. #define SDAT 7
  12. #define SCLK 6
  13.  
  14. void send74hc164(unsigned char data){
  15. for(int i=0; i<8;i++){
  16. if ((data&(1<<7))==0)
  17. {
  18. PORTC&=~(1<<SDAT);
  19. }
  20. else PORTC|=(1<<SDAT);
  21. PORTC|=(1<<SCLK);
  22. for(int i=0;i<=50;i++);
  23. PORTC&=~(1<<SCLK);
  24. for(int i=0;i<=50;i++);
  25. data<<=1;
  26. }
  27. }
  28.  
  29. const unsigned char cCathode[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,
  30. 0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
  31. /*
  32. unsigned char cAnode[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,
  33. 0x83,0xC6,0xA1,0x86,0x8E};
  34. */
  35. int main(void)
  36. {
  37. unsigned int newData = 0, oldData = 0xFF;
  38. /*SW1 For Input Button*/
  39. DDRC&=~(1<<SW1);
  40. /*Set SW1 Pin High*/
  41. PORTC|=(1<<SW1);
  42. /*Serial Data And Serial Clock Output To SN74HC164*/
  43. DDRC|=(1<<SDAT)|(1<<SCLK);
  44. while (1)
  45. {
  46. if((PINC&(1<<SW1)) == 0){
  47. newData++;
  48. //while((PINC&(1<<SW1))==0);
  49. for(int i = 0; i <= 150; i++)
  50. for(int i = 0; i <= 1000; i++);
  51. if(newData > 999) newData = 0;
  52. }
  53.  
  54. if (newData != oldData)
  55. {
  56. send74hc164(cCathode[newData%10]);
  57. send74hc164(cCathode[(newData%100)/10]);
  58. send74hc164(cCathode[newData/100]);
  59. oldData = newData;
  60. }
  61. }
  62. }
  63.  
  64.   

Click here to download zip file of this example.



Monday, August 17, 2020

ATMega32 SN74HC164 Seven Segments Display And Switch Interfacing

In previous post I made some example of interfacing with the SN74HC164 parallel output shift registers chip. They are,

  1. ATMega32 Interfaces To SN74HC164 Shift Registers
  2. ATMega32 SPI Interfaces To SN74HC164 And LED 
  3. ATMega32 SPI Interfaces To SN74HC164 And LCD Using 3 Pins.

In this example, I will use this chip to drive a single common cathode seven-segment display. I will use an additional input button to increase counting variable. It will count up to 0x0F before it rolls down.

ATMega32 SN74HC164 Seven Segments Display And Switch Interfacing
Some 7-Segment Display

ATMega32 SN74HC164 Seven Segments Display And Switch Interfacing

Simulating Program

 

I use software bit-banging to make serial data transmission to the SN74HC164 chip.

  1. /*
  2.  * SN74HC164SD.c
  3.  *
  4.  * Created: 7/8/2023 6:44:00 PM
  5.  * Author : Admin
  6.  */
  7.  
  8. #include <avr/io.h>
  9.  
  10. #define SW1 5
  11. #define SDAT 7
  12. #define SCLK 6
  13.  
  14. void send74hc164(unsigned char data){
  15. for(int i=0; i<8;i++){
  16. if ((data&(1<<7))==0)
  17. {
  18. PORTC&=~(1<<SDAT);
  19. }
  20. else PORTC|=(1<<SDAT);
  21. PORTC|=(1<<SCLK);
  22. for(int i=0;i<=50;i++);
  23. PORTC&=~(1<<SCLK);
  24. for(int i=0;i<=50;i++);
  25. data<<=1;
  26. }
  27. }
  28.  
  29. unsigned char cCathode[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
  30. 0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
  31. //unsigned char cAnode[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
  32. //0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
  33. int main(void)
  34. {
  35. unsigned char newData = 0, oldData = 0xFF;
  36. /*SW1 For Input Button*/
  37. DDRC&=~(1<<SW1);
  38. /*Set SW1 Pin High*/
  39. PORTC|=(1<<SW1);
  40. /*Serial Data And Serial Clock Output To SN74HC164*/
  41. DDRC|=(1<<SDAT)|(1<<SCLK);
  42. while (1)
  43. {
  44. if((PINC&(1<<SW1)) == 0){
  45. newData++;
  46. //while((PINC&(1<<SW1))==0);
  47. for(int i = 0; i <= 150; i++)
  48. for(int i = 0; i <= 1000; i++);
  49. if(newData > 0x0F) newData = 0;
  50. }
  51.  
  52. if (newData != oldData)
  53. {
  54. send74hc164(cCathode[newData]);
  55. oldData = newData;
  56. }
  57. }
  58. }
  59.  
  60.  

 

Click here to download zip file of this example.