pia-468x60

pia-728x90

Saturday, May 28, 2022

A DIY Calculator Using PIC16F876A

I decide to make a simple digital calculator with my own components, seven-segment display. PIC16F876A, and push button, etc. However it's not useful in current application because a calculator presents in many electronics device such as a smart phone, tablet, and personal computer, etc.

A DIY Calculator Using PIC16F876A
A DIY Calculator Using PIC16F876A 

This calculator is able to handle up to 8 digits, including a negative sign. It can perform arithmetic addition, subtraction, multiplication, and division. The data type is only signed integer number. 

I use MikroC Pro for PIC to program this typical 8-bit controller. The total lines of code is quite high.

  1.  
  2.  
  3. #define GA (1<<3)
  4. char keypadPort at PORTB;
  5. char key_char[16]= {7,8,9,15,4,5,6,14,1,2,3,13,10,0,11,12};
  6. char send_key,dig[8];
  7. unsigned char cnt;
  8.  
  9. void interrupt(void){
  10. if(INTCON.TMR0IF)
  11. cnt++;
  12. INTCON.TMR0IF=0;
  13. }
  14.  
  15. void system_init();
  16. void ssd_out();
  17.  
  18. void main() {
  19. char key=0,old_key=0;
  20. char i=0,j=0;
  21. char CntKey=0;
  22. system_init();
  23. while(1){
  24. key=Keypad_Key_Click();
  25. if(key!=0&&CntKey<8){
  26. send_key=key-1;
  27. /*dig[5]=dig[4];
  28.   dig[4]=dig[3];
  29.   dig[3]=dig[2];
  30.   dig[2]=dig[1];
  31.   dig[1]=dig[0];*/
  32. for(i=7;i>0;i--) dig[i]=dig[i-1];
  33. dig[0]=key_char[send_key];
  34. CntKey++;
  35. }
  36.  
  37. ssd_out();
  38. }
  39. }
  40.  
  41. void system_init(){
  42. TRISC=0x00;
  43. TRISA=0x00;
  44. PORTA=0x00;
  45. PORTC=0x00;
  46. ADCON1=0x07;
  47. OPTION_REG=0x85;
  48. INTCON.GIE=1;
  49. INTCON.TMR0IE=1;
  50. INTCON.TMR0IF=0;
  51. Keypad_Init();
  52. cnt=0;
  53. send_key=0;
  54. }
  55.  
  56. void ssd_out(){
  57. const char sg[16]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,
  58. 0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71} ;
  59. // const char dg[6]={0x20,0x10,0x08,0x04,0x02,0x01};
  60. switch(cnt){
  61. case 1:
  62. PORTA=0x00;
  63. PORTC=sg[dig[7]];
  64. PORTA=0x00|GA;
  65. break;
  66.  
  67. case 2:
  68. PORTA=0x00;
  69. PORTC=sg[dig[6]];
  70. PORTA=0x01|GA;
  71. break;
  72.  
  73. case 3:
  74. PORTA=0x00;
  75. PORTC=sg[dig[5]];
  76. PORTA=0x02|GA;
  77. break;
  78.  
  79. case 4:
  80. PORTA=0x00;
  81. PORTC=sg[dig[4]];
  82. PORTA=0x03|GA;
  83. break;
  84.  
  85. case 5:
  86. PORTA=0x00;
  87. PORTC=sg[dig[3]];
  88. PORTA=0x04|GA;
  89. break;
  90.  
  91. case 6:
  92. PORTA=0x00;
  93. PORTC=sg[dig[2]];
  94. PORTA=0x05|GA;
  95. break;
  96.  
  97. case 7:
  98. PORTA=0x00;
  99. PORTC=sg[dig[1]];
  100. PORTA=0x06|GA;
  101. break;
  102.  
  103. case 8:
  104. PORTA=0x00;
  105. PORTC=sg[dig[0]];
  106. PORTA=0x07|GA;
  107. break;
  108.  
  109. case 9:
  110. cnt=1;
  111. PORTA=0x00;
  112. break;
  113. }
  114.  
  115. }

I use keypad library of this compiler to scan its 4x4 matrix keypad.

A DIY Calculator Using PIC16F876A
Schematic Diagram

The PCB is assumed to be a single side layer. It's easy to fabricate at home.

A DIY Calculator Using PIC16F876A
Bottom Layer copper normal no mirror

A DIY Calculator Using PIC16F876A
Top silk normal no mirror
A DIY Calculator Using PIC16F876A
A sample 3D design

A DIY Calculator Using PIC16F876A
Top side

A DIY Calculator Using PIC16F876A
Bottom side

Click here to download its source file.



Friday, April 29, 2022

ATMega16 two-digit multiplexing display and counting example

Display multiplexing is very common for most microcontroller programming and interfacing. In usual, a controller could drive up to 8 digits before we can see its display flickering. In this programming example, I use only two digits of 7-Segment display. Because it's easy to build the circuit with a  little of source codes.

ATMega16 two-digit multiplexing display example
Program simulation in Proteus

Controller keeps track of counting an external pulse generated by SW1 switch pressing. The maximum press counting is 60 before it rolls down to 0. The display will become flicker whenever the input switch has a longer press duration, but it's not longer than 250ms.

  1. /*
  2.  * mux2Ssd.c
  3.  *
  4.  * Created: 5/25/2022 7:20:40 PM
  5.  * Author : Admin
  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. //common cathode
  16. unsigned char SSD[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
  17. unsigned char cnt=0;
  18. //PortC output
  19. DDRC=0xFF;
  20. //PD7 input
  21. DDRD&=~(1<<7);
  22. //Turn on PD7
  23. PORTD|=(1<<7);
  24. while (1)
  25. {
  26. //Display processing
  27. PORTD&=~(1<<0);
  28. PORTD&=~(1<<1);
  29. PORTC=SSD[cnt/10];
  30. PORTD|=(1<<0);
  31. _delay_ms(3);
  32.  
  33. PORTD&=~(1<<0);
  34. PORTD&=~(1<<1);
  35. PORTC=SSD[cnt%10];
  36. PORTD|=(1<<1);
  37. _delay_ms(3);
  38.  
  39. //Input Testing
  40. if ((PIND&0x80)==0)
  41. {
  42. //while((PIND&0x80)==0);
  43. cnt++;
  44. _delay_ms(250);
  45. }
  46. if(cnt>=60) cnt=0;
  47. }
  48. }
  49.  
  50.  

Click here to download source file.

ATMega16 two-digit multiplexing display and counting example
Schematic diagram

Labels