728x90

Sunday, June 19, 2022

Making a Simple Free Running Timer with Multiplexing Display using Atmega32

In previous post, I made a simple multiplexing display example using a two-digit SSD. In this example, I gonna make a free running timer two a two-digit multiplexing seven-segment display. It will start counting from 0 to 999 seconds before it reset by itself.

Making a Simple Free Running Timer with Multiplexing Display using Atmega32
Program simulation

The display is driven by delay function. Each digits are activated for only 5ms. I use Timer/Counter 0 to create timing tick.

The CPU clock is 4MHz. Clock period is,

1/4000000MHz =  250 nano seconds, or 0.00000025 second.

Timer 0 prescaler is Fosc/1024. So its Timer/Counter 0 period is,

0.00000025 second * 1024 = 256 micro seconds, or 0.000256 second.

The 8-bit TCNT0 register can store counting value up to 256. So the TOV0 occurs every,

256*0.000256 second = 0.065536 second.

To get a one second timing, I need to make a calculation of one second count. That is,

1 second count = (1 second)/(0.065536 second) = 15 counts.

Finally after the 15 counts, I will get a one-second time. Then I will need to reset the counter variable.

  1. /*
  2.  * m32Mux2Counting.c
  3.  *
  4.  * Created: 6/19/2022 3:36:14 PM
  5.  * Author : aki-technical
  6.  */
  7.  
  8. #include <avr/io.h>
  9.  
  10. /*Delay function*/
  11. #define F_CPU 4000000UL
  12. #include <util/delay.h>
  13.  
  14. int main(void)
  15. {
  16. unsigned char temp=0,cnt=0;
  17. /*Common Cathode Display*/
  18. unsigned char displayData[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
  19. /*PortB and PortD Output*/
  20. DDRC=0xFF;
  21. DDRD=0xFF;
  22. /*Select Fclk/1024*/
  23. TCCR0|=(1<<CS02)|(1<<CS00);
  24. /*Clear TOV0 flag*/
  25. TIFR|=(1<<TOV0);
  26. /*Clear Counter*/
  27. TCNT0=0;
  28. while (1)
  29. {
  30. /*Multiplexing Display Process*/
  31. PORTD=0x00;
  32. PORTC=displayData[temp/10];
  33. /*Turn On Digit 1*/
  34. PORTD=0x01;
  35. /*Activate for 5ms*/
  36. _delay_ms(5);
  37.  
  38. PORTD=0x00;
  39. PORTC=displayData[temp%10];
  40. /*Turn On Digit 2*/
  41. PORTD=0x02;
  42. /*Activate for 5ms*/
  43. _delay_ms(5);
  44.  
  45. /*TOV0 occurs for every 0.065536 second*/
  46. if ((TIFR)&&(1<<TOV0))
  47. {
  48. cnt++;
  49. TIFR|=(1<<TOV0);
  50. }
  51.  
  52. /*One second is equal to 15 counts*/
  53. if (cnt>=15)
  54. {
  55. temp++;
  56. cnt=0;
  57. }
  58. /*Check if it is greater than 99 seconds*/
  59. if (temp>99)
  60. {
  61. temp=0;
  62. }
  63. }
  64. }
  65.  
  66.  

Click here to download its source file.

Making a Simple Free Running Timer with Multiplexing Display using Atmega32
Schematic Diagram
 

Tuesday, May 31, 2022

ATMega32 Simple Multiplexing Display Example

In this programming example, I will show a very simple display multiplexing using a two-digit seven-segment display. It will show a value that read from the lower nibble of PortB.

ATMega32 Simple Multiplexing Display Example
Program Simulation

The display is common cathode type. I use a resistor network to cut down its forward current. The 74HC04 chip replace driving transistors, due to simulation difficulty. The lower nibble of PortB reads the digital inputs from a DIP switch. We will not need additional resistors because all input pins are turned high via software.

  1. /*
  2.  * muxDisplayDigitalRead.c
  3.  *
  4.  * Created: 5/30/2022 6:19:32 PM
  5.  * Author : dell
  6.  */
  7.  
  8. #include <avr/io.h>
  9.  
  10. #define F_CPU 4000000UL
  11. #include <util/delay.h>
  12.  
  13. int main(void)
  14. {
  15. unsigned char temp;
  16. /*Common Cathode Display*/
  17. unsigned char displayData[10]={0x3F,0x06,0x5B,0x4F, 
    0x66,0x6D,0x7D,0x07,0x7F,0x6F};
  18. /*PortB Input*/
  19. DDRB=0x00;
  20. /*Turn on PD0...3 of PortB*/
  21. PORTB=0x0F;
  22. /*PortB and PortD Output*/
  23. DDRC=0xFF;
  24. DDRD=0xFF;
  25. while (1)
  26. {
  27. /*Read PortB*/
  28. temp=PINB&0x0F;
  29. /*Multiplexing Display Process*/
  30. PORTD=0x00;
  31. PORTC=displayData[temp/10];
  32. /*Turn On Digit 1*/
  33. PORTD=0x01;
  34. /*Activate for 5ms*/
  35. _delay_ms(5);
  36.  
  37. PORTD=0x00;
  38. PORTC=displayData[temp%10];
  39. /*Turn On Digit 2*/
  40. PORTD=0x02;
  41. /*Activate for 5ms*/
  42. _delay_ms(5);
  43. }
  44. }
  45.  
  46.  

 Click here to download its source file.

ATMega32 Simple Multiplexing Display Example
Schematic Diagram

We can multiplex multi-digit 7-Segment display using the SN74HC168 serial to parallel shift registers chip.

Sunday, April 24, 2022

Using Timer0 Overflow Interrupt of PIC16F877A to Drive Multiplexing Display

I have showed an example of Timer 0 interrupt programming of PIC16F877A  in an earlier post. Here I use timer 0 interrupt to drive a multiplexing seven-segments display. This method is very effective in any application that contain many tasks polling.

In this example, timer 0 overflow interrupt will create a timer tick around 2.56 milliseconds. This timer tick regularly activate each digits of the multiplexing seven-segment display. 

Using Timer0 Overflow Interrupt of PIC16F877A to Drive Multiplexing Display
Sample program

In main program loop, the program just check whenever the button is press. It will need to wait until the button is released until it increase the press counter. 

The display shows the counting content up to 60 before it reset to 0. The display show the counting content with any flickering due to the long-time button pressing.

Source Code:

  1. /*
  2.  * PIC16F877A Timer0 Interrupt and multiplexing
  3.  * display example
  4.  */
  5. #include <xc.h>
  6. #include "config.h"
  7.  
  8. //RB0 input button
  9. #define SW1 RB0
  10.  
  11. unsigned int cnt=0,cntPress=0;
  12. //Common cathode display pattern
  13. char cCathode[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
  14.  
  15. int main(void){
  16. //Clear PortD
  17. PORTD=0x00;
  18. //Clear PortC
  19. PORTC=0x00;
  20. //Clear PortB
  21. PORTB=0x00;
  22. //PortD output
  23. TRISD=0x00;
  24. //PortC output
  25. TRISC=0x00;
  26. //RB0 is input
  27. TRISB0=1;
  28. //Turn on PortB Pullup resistors
  29. nRBPU=0;
  30. //select internal instruction cycle clock
  31. T0CS=0;
  32. //Select timer 0 prescaler
  33. PSA=0;
  34. //select 1:256 prescaler
  35. OPTION_REGbits.PS=0x07;
  36. //Enable timer0 interrupt
  37. T0IE=1;
  38. //Enable interrupt
  39. GIE=1;
  40. T0IF=0;
  41. //Clear Timer 0
  42. TMR0=0;
  43. while(1){
  44. //Switch pressing count
  45. if(SW1==0){
  46. //Wait until it's release
  47. while(SW1==0);
  48. cntPress+=1;
  49. }
  50. if(cntPress>=60) cntPress=0;
  51. }
  52. }
  53.  
  54. //Timer0 Interrupt Service Routine - ISR
  55. void interrupt _T0_ISR(void){
  56. if(T0IF){
  57. //increase counter
  58. cnt+=1;
  59. //make a 10 mS time
  60. TMR0=-50;
  61. //Clear Flag
  62. T0IF=0;
  63. }
  64.  
  65. switch(cnt){
  66. case 1:
  67. PORTC=0x00;
  68. PORTD=cCathode[cntPress/10];
  69. RC0=1;
  70. break;
  71.  
  72. case 2:
  73. PORTC=0x00;
  74. PORTD=cCathode[cntPress%10];
  75. RC1=1;
  76. break;
  77.  
  78. case 3:
  79. cnt=0;
  80. break;
  81. }
  82. }

Configuration bits:

  1.  
  2. // PIC16F877A Configuration Bit Settings
  3.  
  4. // CONFIG
  5. // Oscillator Selection bits (HS oscillator)
  6. #pragma config FOSC = HS
  7. // Watchdog Timer Enable bit (WDT disabled)
  8. #pragma config WDTE = OFF
  9. // Power-up Timer Enable bit (PWRT disabled)
  10. #pragma config PWRTE = OFF
  11. // Brown-out Reset Enable bit (BOR enabled)
  12. #pragma config BOREN = ON
  13. /*
  14.  * Low-Voltage (Single-Supply) In-Circuit Serial
  15.  * Programming Enable bit (RB3 is digital I/O,
  16.  * HV on MCLR must be used for programming)
  17.  */
  18. #pragma config LVP = OFF
  19. /*
  20.  * Data EEPROM Memory Code Protection bit
  21.  * (Data EEPROM code protection off)
  22.  */
  23. #pragma config CPD = OFF
  24. /*
  25.  * Flash Program Memory Write Enable bits
  26.  * (Write protection off; all program memory
  27.  * may be written to by EECON control)
  28.  */
  29. #pragma config WRT = OFF
  30. /*
  31.  * Flash Program Memory Code Protection bit
  32.  * (Code protection off)
  33.  */
  34. #pragma config CP = OFF
  35.  
  36.  
  37.  

Schematic:

Using Timer0 Overflow Interrupt of PIC16F877A to Drive Multiplexing Display
Using Timer0 Overflow Interrupt of PIC16F877A to Drive Multiplexing Display

Click here to download source file.


Search This Blog