#include<avr/io.h>
#include <util/delay.h>
//******************************16x02 LCD*********************************
/*
RS -> PD2
E -> PD3
D4-D7-> PD4-PD7
*/
#define RS 2
//#define RW 1
#define E 3
#define DDR_port DDRD
#define data_pins PORTD
#define control_pins PORTD
void lcd_cmd(unsigned char c);
void lcd_data(unsigned char d);
void lcd_string(unsigned char *s);
void lcd_setcursor(uint8_t row, uint8_t col);
void lcd_init();
void lcd_cmd(unsigned char c){
data_pins = (c&0xF0); //upper nibble
control_pins &=~(1<<RS); //RS =0
//control_pins &=~(1<<RW); // RW = 0
control_pins |=(1<<E); // E = 1
_delay_ms(1);
control_pins &=~(1<<E); //E = 0
data_pins = ((c<<4)&0xF0); //lower nibble
control_pins &=~(1<<RS); //RS =0
//control_pins &=~(1<<RW); // RW = 0
control_pins |=(1<<E); // E = 1
_delay_ms(1);
control_pins &=~(1<<E); //E = 0
}
void lcd_data(unsigned char d){
data_pins = (d&0xF0); //upper nibble
control_pins |=(1<<RS); //RS =1
//control_pins &=~(1<<RW); // RW = 0
control_pins |=(1<<E); // E = 1
_delay_ms(1);
control_pins &=~(1<<E); //E = 0
data_pins = ((d<<4)&0xF0); //lower nibble
control_pins |=(1<<RS); //RS =1
//control_pins &=~(1<<RW); // RW = 0
control_pins |=(1<<E); // E = 1
_delay_ms(1);
control_pins &=~(1<<E); //E = 0
}
void lcd_string(unsigned char *s){
while(*s!=0){
lcd_data(*s);
s++;
}
}
void lcd_setcursor(uint8_t row, uint8_t col) {
if (row == 0) {
lcd_cmd(0x80 + col);
} else if (row == 1) {
lcd_cmd(0xC0 + col);
}
}
void lcd_init(){
DDR_port = 0xFC; //set Port D as output b1111 1100
lcd_cmd(0x33);
lcd_cmd(0x32);
lcd_cmd(0x28);
lcd_cmd(0x06);
lcd_cmd(0x0C);
lcd_cmd(0x01);
}
//******************************Keypad******************************
/*
Rows connected to PC0 to PC3
Columns connected to PB0 to PB3
*/
// Keypad key map
const char keypad_keys[4][4] = {
{'1', '2', '3', '+'},
{'4', '5', '6', '-'},
{'7', '8', '9', '*'},
{'.', '0', '=', '/'}
};
void keypad_init(void) {
// Set rows as input (PC0-PC3),
DDRC &= 0xF0;
// Set columns as output (PB0-PB3)
DDRB |= 0x0F;
}
char keypad_scan(void) {
char key = 0;
for (uint8_t col = 0; col < 4; col++) {
//Set each col high
PORTB = (PORTB & 0xF0)|(1<<col);
for (uint8_t row = 0; row < 4; row++) {
// Check if the key is pressed (row is high)
if (PINC & (1 << row)) {
// Simple mapping, return character based on position
//return "123+456-789*.0=/"[row * 4 + col];
//return keypad_keys[row][col];
key = keypad_keys[row][col];
break;
}
}
}
//return 0; // No key pressed
return key;
}
//******************************main******************************
int main(void) {
// Initialize LCD and Keypad
lcd_init();
keypad_init();
char key = 0;
// Display welcome message
lcd_string("Welcome!");
_delay_ms(1000);
lcd_cmd(0x01); // Clear display
while (1) {
key = keypad_scan(); // Scan for keypress
lcd_cmd(0x01); // Clear display
if (key != 0) {
lcd_setcursor(0,0);
lcd_string("Key: ");
lcd_data(key); // Display key on LCD
}
_delay_ms(100);
//for (volatile int i = 0; i < 100000; i++); // Debounce delay
}
return 0;
}