#include <math.h>
#include <stdlib.h>
void init_port(void);
void outdata(char);
void outcontrol(char);
void init_lcd(void);
void lcd_control_write(void);
void write_data(char);
void write_string(char);
void set_cursor_second_row(void);
char str[50] = "CALCULATOR";
void setup() {
init_port();
init_lcd();
volatile char *dirF, *dirK;
dirF = 0x30, dirK = 0x10;
*dirF = 0xFF, *dirK = 0x00;
Serial.begin(9600);
write_string(str);
}
void write_string(char *ptr) {
volatile long count = 0;
while (*ptr != 0) {
if (count == 16) {
set_cursor_second_row();
lcd_control_write();
}
write_data(*ptr); // Write character to the LCD
ptr++;
count++;
}
}
void init_port(void) {
volatile char *portA_dir = (volatile char *)0x21;
volatile char *portC_dir = (volatile char *)0x27;
*portA_dir = 0xFF;
*portC_dir = 0x03;
}
void outdata(char out_data) {
volatile char *portA_data;
portA_data = 0x22;
*portA_data = out_data;
}
void outcontrol(char out_data) {
volatile char *portC_data;
portC_data = 0x28;
*portC_data = out_data;
}
void init_lcd(void) {
outdata(0x38); //function set: 8bit ,2line , 5*8
lcd_control_write(); //giving pulse to enable
outdata(0x0F); //display on ,cursor blinking
lcd_control_write();
outdata(0x01); //clear display
lcd_control_write();
outdata(0x06); //auto increment after writing 1 char; entry mode
lcd_control_write();
}
void lcd_control_write(void) {
outcontrol(0x01);
delay(1);
outcontrol(0x00);
delay(1);
}
void write_data(char wr_data) {
outdata(wr_data);
outcontrol(0x02); //giving pulse to enable and sending data
delay(1);
outcontrol(0x03);
delay(1);
outcontrol(0x02);
delay(1);
}
void set_cursor_second_row(void) {
outdata(0xC0); // Address of the second row in 16x2 LCD(DDRAM)
lcd_control_write();
}
void set_cursor_first_row(void) {
outdata(0x80); // Address of the first row in 16x2 LCD(DDRAM)
lcd_control_write();
}
void loop() {
// put your main code here, to run repeatedly:
volatile int col, row;
char keys[4][4] = {
{'1', '2', '3', '+'},
{'4', '5', '6', '-'},
{'7', '8', '9', '*'},
{'.', '0', '=', '/'}
};
volatile char *outF, *inK;
outF = 0x31, inK = 0x106 ;
volatile long i, j;
int num1 = -1, num2 = -1;
int num3 = -1, num4 = -1;
uint8_t sum;
bool firstNumberComplete = false;
bool inputComplete = false;
char *Operator;
int firstNumber;
int secondNumber;
int result;
while (1) {
for (i = 0; i < 4 ; i++) {
*outF = 1 << i;
if (*inK != 0) {
col = *inK;
row = 1 << i;
char key = keys[int(log(row) / log(2))][int(log(col) / log(2))];
if (key >= '0' && key <= '9') {
int digit = key - '0';
if (!firstNumberComplete) {
if (num1 == -1) {
num1 = digit;
sprintf(str, "%d", num1);
init_lcd();
write_string(" ");
write_string(str);
}
else {
num2 = digit;
sprintf(str, "%d", num2);
write_string(str);
firstNumber = num1 * 10 + num2;
firstNumberComplete = true;
num1 = -1;
num2 = -1;
}
} else {
// Getting the second two-digit number
if (num3 == -1) {
num3 = digit; // Store first digit of second number
sprintf(str, "%d", num3);
write_string(str);
}
else {
num4 = digit; // Store second digit of second number
sprintf(str, "%d", num4);
write_string(str);
secondNumber = num3 * 10 + num4;
num3 = -1;
num4 = -1;
firstNumberComplete = false;
inputComplete = true;
}
}
}
else if (key == '+' ) {
Operator = "add";
set_cursor_second_row();
lcd_control_write();
write_string("+");
}
else if (key == '-') {
Operator = "subtract";
set_cursor_second_row();
lcd_control_write();
write_string("-");
}
else if (key == '*') {
Operator = "multiply";
set_cursor_second_row();
lcd_control_write();
write_string("*");
}
else if (key == '/') {
Operator = "divide";
set_cursor_second_row();
lcd_control_write();
write_string("/");
}
else if (key == '=') {
if (Operator == "add") {
result = firstNumber + secondNumber;
}
else if (Operator == "subtract") {
result = firstNumber - secondNumber;
}
else if (Operator == "multiply") {
result = firstNumber * secondNumber;
}
else if (Operator == "divide") {
float result = (float)firstNumber / secondNumber;
dtostrf(result, 6, 2, str); // Convert float to string
init_lcd();
write_string("ANSWER: ");
write_string(str);
}
if(Operator != "divide"){
sprintf(str, "%d", result); // Convert float to string
init_lcd();
write_string("ANSWER: ");
write_string(str);
}
// Debounce delay
}
delay(50);
// Wait for key release
while (*inK != 0);
delay(10); // Short delay between each iteration
}
}
}
}