|
|
View previous topic :: View next topic |
Author |
Message |
sshahryiar
Joined: 05 May 2010 Posts: 94 Location: Dhaka, Bangladesh
|
Calculator Project |
Posted: Sat Feb 20, 2016 9:35 pm |
|
|
This is a simple calculator made with 7 segment display and a 4x4 keypad. Currently only integral calculations are supported.
keypad.h
Code: |
#define col1 pin_A1
#define col2 pin_A2
#define col3 pin_A3
#define col4 pin_A5
#define col5 pin_E0
#define col6 pin_E1
#define col7 pin_E2
#define col8 pin_C0
#define sw0 !input(pin_B0)
#define sw1 !input(pin_B2)
#define sw2 !input(pin_B4)
#define sw3 !input(pin_B5)
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)
const unsigned char num[0x0A] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};
unsigned char buffer[0x08] = {0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40};
unsigned char pos = 0x00;
unsigned char key = 0xFF;
short key_pressed = FALSE;
void segmented_display_init();
void clear_buffer(); |
keypad.c
Code: | #include "keypad_display.h"
void display_keypad_init()
{
set_TRIS_A(0xD1);
set_TRIS_B(0xFF);
set_TRIS_C(0xFE);
set_TRIS_D(0x00);
set_TRIS_E(0xF0);
output_D(0x00);
setup_comparator(NC_NC_NC_NC);
setup_SPI(SPI_disabled | SPI_SS_disabled);
setup_ADC(ADC_off);
setup_ADC_ports(no_analogs);
port_B_pullups(FALSE);
setup_timer_0(T0_internal | T0_div_64 | T0_8_bit);
set_timer0(0xD8);
enable_interrupts(GLOBAL);
enable_interrupts(INT_RTCC);
}
#int_RTCC
void scan_display()
{
set_timer0(0xD8);
output_D(buffer[pos]);
switch(pos)
{
case 7:
{
output_high(col1);
output_low(col2);
output_low(col3);
output_low(col4);
output_low(col5);
output_low(col6);
output_low(col7);
output_low(col8);
if(sw0)
{
key_pressed = TRUE;
key = 0x01;
}
if(sw1)
{
key_pressed = TRUE;
key = 0x02;
}
if(sw2)
{
key_pressed = TRUE;
key = 0x03;
}
if(sw3)
{
key_pressed = TRUE;
key = 0x0A;
}
break;
}
case 6:
{
output_high(col2);
output_low(col1);
output_low(col3);
output_low(col4);
output_low(col5);
output_low(col6);
output_low(col7);
output_low(col8);
if(sw0)
{
key_pressed = TRUE;
key = 0x04;
}
if(sw1)
{
key_pressed = TRUE;
key = 0x05;
}
if(sw2)
{
key_pressed = TRUE;
key = 0x06;
}
if(sw3)
{
key_pressed = TRUE;
key = 0x0B;
}
break;
}
case 5:
{
output_high(col3);
output_low(col1);
output_low(col2);
output_low(col4);
output_low(col5);
output_low(col6);
output_low(col7);
output_low(col8);
if(sw0)
{
key_pressed = TRUE;
key = 0x07;
}
if(sw1)
{
key_pressed = TRUE;
key = 0x08;
}
if(sw2)
{
key_pressed = TRUE;
key = 0x09;
}
if(sw3)
{
key_pressed = TRUE;
key = 0x0C;
}
break;
}
case 4:
{
output_high(col4);
output_low(col1);
output_��428col2);
output_low(col3);
output_low(col5);
output_low(col6);
output_low(col7);
output_low(col8);
if(sw0)
{
key_pressed = TRUE;
key = 0x0F;
}
if(sw1)
{
key_pressed = TRUE;
key = 0x00;
}
if(sw2)
{
key_pressed = TRUE;
key = 0x0E;
}
if(sw3)
{
key_pressed = TRUE;
key = 0x0D;
}
break;
}
case 3:
{
output_high(col5);
output_low(col1);
output_low(col2);
output_low(col3);
output_low(col4);
output_low(col6);
output_low(col7);
output_low(col8);
break;
}
case 2:
{
output_high(col6);
output_low(col1);
output_low(col2);
output_low(col3);
output_low(col4);
output_low(col5);
output_low(col7);
output_low(col8);
break;
}
case 1:
{
output_high(col7);
output_low(col1);
output_low(col2);
output_low(col3);
output_low(col4);
output_low(col5);
output_low(col6);
output_low(col8);
break;
}
case 0:
{
output_high(col8);
output_low(col1);
output_low(col2);
output_low(col3);
output_low(col4);
output_low(col5);
output_low(col6);
output_low(col7);
break;
}
}
pos++;
if(pos >= 8)
{
pos = 0;
}
}
void clear_buffer()
{
memset(buffer, 0x00, sizeof(buffer));
}
|
Main code
Code: | #include <16F877A.h>
#device *= 16
#fuses HS, PUT, PROTECT, CPD, NODEBUG, NOLVP, NOWDT, NOWRT, BROWNOUT
#use delay (clock = 10MHz)
#include "keypad_display.c"
#define no_op 0x0E
#define add 0x0A
#define sub 0x0B
#define mul 0x0C
#define div 0x0D
unsigned char operation = 0x00;
void setup();
unsigned long long get_number(short num_sel);
void show_value(signed long long value);
unsigned long long power(unsigned char value);
void main()
{
signed long long num1 = 0;
signed long long num2 = 0;
setup();
while(TRUE)
{
while(key != 0x0F);
num1 = get_number(TRUE);
show_value(num1);
delay_ms(1000);
num2 = get_number(FALSE);
show_value(num2);
delay_ms(1000);
switch(operation)
{
case add:
{
show_value((num1 + num2));
break;
}
case sub:
{
show_value((num1 - num2));
break;
}
case mul:
{
show_value((num1 * num2));
break;
}
case div:
{
show_value((num1 / num2));
break;
}
case no_op:
{
show_value(19999999);
break;
}
}
};
}
void setup()
{
disable_interrupts(GLOBAL);
setup_timer_1(T1_disabled);
setup_timer_2(T2_disabled, 255, 1);
set_timer1(0x0000);
set_timer2(0x00);
setup_CCP1(CCP_off);
setup_CCP2(CCP_off);
display_keypad_init();
delay_ms(100);
}
unsigned long long get_number(short num_sel)
{
unsigned char n = 0x00;
unsigned char digits = 0x00;
unsigned long long number = 0;
unsigned char value[8];
memset(value, 0x00, sizeof(value));
clear_buffer();
while(TRUE)
{
if(key_pressed)
{
if((key >= 0) && (key <= 9))
{
buffer[n] = num[key];
value[n] = key;
n++;
digits++;
}
delay_ms(400);
key_pressed = FALSE;
if((n >= 7) || ((key >= 0x0A) && (key <= 0x0E)))
{
if(num_sel == TRUE)
{
operation = key;
}
break;
}
}
};
for(n = 1; n <= digits; n++)
{
number += value[(n - 1)] * power(digits - n);
}
return number;
}
void show_value(signed long long value)
{
unsigned char ch = 0;
clear_buffer();
if(value < 0)
{
value = -value;
buffer[0] = 0x40;
}
if((value >= 0) && (value <= 9))
{
ch = value;
buffer[7] = num[ch];
}
else if((value > 9) && (value <= 99))
{
ch = (value / 10);
buffer[6] = num[ch];
ch = (value % 10);
buffer[7] = num[ch];
}
else if((value > 99) && (value <= 999))
{
ch = (value / 100);
buffer[5] = num[ch];
ch = ((value / 10) % 10);
buffer[6] = num[ch];
ch = (value % 10);
buffer[7] = num[ch];
}
else if((value > 999) && (value <= 9999))
{
ch = (value / 1000);
buffer[4] = num[ch];
ch = ((value / 100) % 10);
buffer[5] = num[ch];
ch = ((value / 10) % 10);
buffer[6] = num[ch];
ch = (value % 10);
buffer[7] = num[ch];
}
else if((value > 9999) && (value <= 99999))
{
ch = (value / 10000);
buffer[3] = num[ch];
ch = ((value / 1000) % 10);
buffer[4] = num[ch];
ch = ((value / 100) % 10);
buffer[5] = num[ch];
ch = ((value / 10) % 10);
buffer[6] = num[ch];
ch = (value % 10);
buffer[7] = num[ch];
}
else if((value > 99999) && (value <= 999999))
{
ch = (value / 100000);
buffer[2] = num[ch];
ch = ((value / 10000) % 10);
buffer[3] = num[ch];
ch = ((value / 1000) % 10);
buffer[4] = num[ch];
ch = ((value / 100) % 10);
buffer[5] = num[ch];
ch = ((value / 10) % 10);
buffer[6] = num[ch];
ch = (value % 10);
buffer[7] = num[ch];
}
else if((value > 999999) && (value <= 9999999))
{
ch = (value / 1000000);
buffer[1] = num[ch];
ch = ((value / 100000) % 10);
buffer[2] = num[ch];
ch = ((value / 10000) % 10);
buffer[3] = num[ch];
ch = ((value / 1000) % 10);
buffer[4] = num[ch];
ch = ((value / 100) % 10);
buffer[5] = num[ch];
ch = ((value / 10) % 10);
buffer[6] = num[ch];
ch = (value % 10);
buffer[7] = num[ch];
}
else
{
memset(buffer, 0x40, sizeof(buffer));
}
}
unsigned long long power(unsigned char value)
{
unsigned char p = 0;
unsigned long long temp = 1;
for(p = 0; p < value; p++)
{
temp *= 10;
}
return temp;
} |
Project demo video
https://www.youtube.com/watch?v=ZrfTvYYNqcA _________________ https://www.facebook.com/MicroArena
SShahryiar |
|
|
Jerson
Joined: 31 Jul 2009 Posts: 125 Location: Bombay, India
|
|
Posted: Sun Feb 21, 2016 1:02 am |
|
|
There is ghosting in your numbers. I suggest you do the scan this way.
Example for only one digit is shown here.
Code: | void scan_display()
{
set_timer0(0xD8);
output_D(0x00); // 0x00 turns off the segments by looking at your numtable
switch(pos)
{
case 7:
{
output_high(col1);
output_low(col2);
output_low(col3);
output_low(col4);
output_low(col5);
output_low(col6);
output_low(col7);
output_low(col8);
.......
} // end of switch
output_D(buffer[pos]); // now turn on the segments
|
|
|
|
sshahryiar
Joined: 05 May 2010 Posts: 94 Location: Dhaka, Bangladesh
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|