-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.c
More file actions
147 lines (130 loc) · 3.85 KB
/
main.c
File metadata and controls
147 lines (130 loc) · 3.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
* A4.c
*
* Created : 3/27/2025 5:34:04 PM
* Author : Jasvin Kaur
* V-Number: V01041632
// Assignment 4
// Digital Clock Program
// This program runs a digital clock on a 16x2 LCD using an AVR micro controller.
// It tracks hours, minutes, seconds, and milliseconds, updating the display accordingly.
// A timer interrupt increments time every 10ms, while button input toggles whether both lines update.
*/
#include "CSC230.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
// Time tracking variables
int hours = 0;
char hours_str[3]; // 2 chars + null terminator
int minutes = 0;
char minutes_str[3];
int seconds = 0;
char seconds_str[3];
int milliseconds = 0;
char milliseconds_str[4]; // 3 chars + null terminator
int disable_second_line = 0; // 0 is false.
int update_in_progress = 0;
// Synchronizes both lines of the LCD display with the current time.
void synchronize_display() {
update_in_progress = 1; // Indicate that sync is in progress to prevent simultaneous updates.
char time_buffer[13]; // Buffer to hold formatted time string.
sprintf(time_buffer, "%02d:%02d:%02d:%03d", hours, minutes, seconds, milliseconds);
lcd_xy(0,0);
lcd_puts(time_buffer);
lcd_xy(0,1);
lcd_puts(time_buffer);
update_in_progress = 0; // Sync complete.
}
// Updates the LCD display at a specific column with a given value.
void modify_display(int column, char value[]) {
if (!update_in_progress) {
lcd_xy(column, 0);
lcd_puts(value);
if (!disable_second_line) {
lcd_xy(column, 1);
lcd_puts(value);
}
}
}
// Initializes ADC for button input.
void initialize_lcd_buttons() {
ADCSRA = 0x87;
ADMUX = 0x40;
}
// Configures Timer1 to generate interrupts every 10ms.
void configure_timer1() {
TCCR1B |= (1 << WGM12); // Set to CTC (Clear Timer on Compare) mode.
TCCR1B |= (1 << CS11) | (1 << CS10); // Set prescaler to 64.
OCR1A = 2499; // Compare match after 10ms at 16MHz clock.
TIMSK1 |= (1 << OCIE1A); // Enable compare match interrupt.
sei(); // Enable global interrupts.
}
// Initializes all system components.
void system_initialize() {
lcd_init();
synchronize_display();
initialize_lcd_buttons();
configure_timer1();
}
// Checks button input and toggles second line display when 'SELECT' is pressed.
void monitor_buttons() {
ADCSRA |= 0x40; // Start ADC conversion.
while (ADCSRA & 0x40); // Wait for conversion.
unsigned int adc_value = ADCL;
unsigned int adc_value_high = ADCH;
adc_value += (adc_value_high << 8);
if (adc_value > 545 && adc_value < 800) {
disable_second_line = !disable_second_line;
synchronize_display();
}
}
// Increments hours and updates display.
void increment_hours() {
hours = (hours < 99) ? hours + 1 : 0;
if (hours == 0) {
synchronize_display();
} else {
sprintf(hours_str, "%02d", hours);
modify_display(0, hours_str);
}
}
// Increments minutes and updates display.
void increment_minutes() {
minutes = (minutes < 59) ? minutes + 1 : 0;
sprintf(minutes_str, "%02d", minutes);
modify_display(3, minutes_str);
if (minutes == 0) {
increment_hours();
}
}
// Increments seconds and updates display.
void increment_seconds() {
seconds = (seconds < 59) ? seconds + 1 : 0;
sprintf(seconds_str, "%02d", seconds);
modify_display(6, seconds_str);
if (seconds == 0) {
increment_minutes();
}
}
// Increments milliseconds by 10ms and updates display.
void increment_milliseconds() {
milliseconds = (milliseconds < 990) ? milliseconds + 10 : 0;
sprintf(milliseconds_str, "%03d", milliseconds);
modify_display(9, milliseconds_str);
if (milliseconds == 0) {
increment_seconds();
}
}
// Timer1 Interrupt Service Routine (ISR), triggered every 10ms.
ISR(TIMER1_COMPA_vect) {
increment_milliseconds();
}
// Main function - initializes system and enters infinite loop.
int main(void) {
system_initialize();
while(1) {
monitor_buttons();
_delay_ms(250); // delay to prevent multiple rapid button presses.
}
}