void init_port(void);
void outport(char);
void RS_Enable_pin(char);
void delay1(int);
void lcd_control_write(void);
void init_lcd(void);
void write_data(char);
void write_string(char *ptr);
void init_ADC(void);
void start_ADC(void);
uint16_t read_ADC(void);
void print_ADC_value(uint16_t value);
void set_cursor(uint8_t row, uint8_t column); // Function to set cursor at a specific position
void setup() {
init_port();
init_lcd();
// Initialize ADC
init_ADC();
// Display the static label "ADC Value :-" on the first line
set_cursor(0, 0); // Set cursor to the beginning of the first line
write_string("ADC Value :- ");
}
void loop() {
// Start ADC conversion
start_ADC();
// Read ADC result
uint16_t x = read_ADC();
// Set the cursor to the second line where the ADC value will be displayed
set_cursor(1, 0); // Second line, first position
// Display the updated ADC value
print_ADC_value(x);
delay1(500); // Small delay to refresh the value every 500 ms
}
void write_string(char *ptr) {
while (*ptr != 0) {
write_data(*ptr);
ptr++;
}
}
void print_ADC_value(uint16_t value) {
char buffer[6]; // Buffer to store the converted value as a string (5 digits + null terminator)
sprintf(buffer, "%u", value); // Convert the ADC value to a string
write_string(buffer); // Display the string on the LCD
}
void set_cursor(uint8_t row, uint8_t column) {
// Calculate the DDRAM address for the specified position
uint8_t address = (row == 0) ? (0x80 + column) : (0xC0 + column);
// Set the cursor to the calculated position
outport(address);
lcd_control_write();
}
void init_port() {
volatile char *portb_dir = (volatile char *)0x24;
volatile char *portd_dir = (volatile char *)0x2A;
volatile char *portc_dir = (volatile char *)0x27;
*portb_dir = 0x30; // Set PB5 and PB4 (pins 13 and 12) for output
*portd_dir = 0xF0; // Set higher nibble of PORTD for output
*portc_dir = 0x03; // Set lower bits of PORTC for output
}
void outport(char out_data) {
volatile char *portb_data = (volatile char *)0x25;
volatile char *portd_data = (volatile char *)0x2B;
*portb_data = out_data >> 4; // Send high nibble
*portd_data = out_data << 4; // Send low nibble
}
void RS_Enable_pin(char out_data) {
volatile char *portb_data = (volatile char *)0x25;
// Control RS (PB5) and Enable (PB4) based on out_data
if (out_data & 0x01) {
*portb_data |= (1 << PB5); // Set RS high
} else {
*portb_data &= ~(1 << PB5); // Set RS low
}
if (out_data & 0x02) {
*portb_data |= (1 << PB4); // Set Enable high
} else {
*portb_data &= ~(1 << PB4); // Set Enable low
}
}
void init_lcd(void) {
outport(0x38); // 8-bit, 2 lines
lcd_control_write();
delay1(2); // Delay for stability
outport(0x0F); // Display on, Cursor Blinking
lcd_control_write();
delay1(2); // Delay for stability
outport(0x01); // Clear Display
lcd_control_write();
delay1(2); // Delay for clearing the display
outport(0x06); // Auto Increment
lcd_control_write();
delay1(2); // Delay for stability
}
void write_data(char wr_data) {
outport(wr_data);
RS_Enable_pin(0x01); // RS high for data, Enable low
delay1(1);
RS_Enable_pin(0x03); // Enable high
delay1(1);
RS_Enable_pin(0x01); // Enable low
delay1(2); // Delay for data to be processed
}
void lcd_control_write(void) {
RS_Enable_pin(0x00); // RS low for command, Enable low
delay1(1);
RS_Enable_pin(0x02); // Enable high
delay1(1);
RS_Enable_pin(0x00); // Enable low
delay1(2); // Delay for command to be processed
}
void delay1(int count) {
volatile long i;
while (count) {
for (i = 0; i < 1000; i++);
count--;
}
}
void init_ADC() {
volatile char *admux = (volatile char *)0x7C;
volatile char *adcsra = (volatile char *)0x7A;
*admux = 0x40; // Reference voltage: AVCC, ADC0 selected
*adcsra = 0x87; // ADC Enable, Prescaler = 128 (16 MHz / 128 = 125 KHz)
}
void start_ADC() {
volatile unsigned char *adcsra = (volatile unsigned char *)0x7A;
*adcsra = *adcsra | 0x40; // Start conversion by setting ADSC bit
}
uint16_t read_ADC() {
volatile char *adcsra = (volatile char *)0x7A;
volatile unsigned char *L = (volatile unsigned char *)0x78;
volatile unsigned char *H = (volatile unsigned char *)0x79;
uint16_t value;
while ((*adcsra & 0x10) == 0); // Wait for conversion to complete (ADIF flag)
value = (*H << 8) | *L; // Combine the upper and lower bits to get the 10-bit result
*adcsra = *adcsra | 0x10; // Clear the ADIF flag by writing a 1 to it
return value;
}