09:10 - 2/23 복습, 시계 만들기
10:10 - 초침 blink
11:10 - Hour_Min, Sec_Mil
13:00 - LCD H/W 작업(+ 가변저항)
14:00 - LCD 코딩 시작
15:00 - LCD에 HELLO 표시 코딩
16:00 - LCD string 출력 / TimeClock <-LCD 파일
과제 : TimeClock <--> StopWatch 만들기
// main.c
#include <avr/io.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include "ap/TimeClock/TimeClock.h"
#include "driver/FND/FND.h"
ISR(TIMER0_OVF_vect)
{
FND_ISR_Process();
}
ISR(TIMER2_COMP_vect) // 1ms period interrupt
{
TimeClock_incMilisec();
StopWatch_incMilisec();
}
int main(void)
{
Watch_init();
sei(); // global interrupt enable
while (1)
{
Watch_excute();
}
}
// ap.c
#include "TimeClock.h"
uint16_t stopwatch_milisec;
uint8_t stopwatch_sec;
uint8_t stopwatch_min;
uint8_t stopwatch_hour;
uint16_t milisec;
uint8_t sec;
uint8_t min;
uint8_t hour;
uint8_t stopWatchState;
uint8_t timeClockDispState = HOUR_MIN;
uint8_t watchState = TIMECLOCK;
button_t btnMode, btnWatchMode, btnRunStop, btnReset;
void Watch_init()
{
FND_init();
TIM0_INIT();
TIM2_INIT();
Button_init(&btnMode, &DDRA, &PINA, 0);
Button_init(&btnWatchMode, &DDRA, &PINA, 1);
Button_init(&btnRunStop, &DDRA, &PINA, 2);
Button_init(&btnReset, &DDRA, &PINA, 3);
LCD_init();
TimeClock_init();
StopWatch_init();
}
void TimeClock_init()
{
milisec = 0;
sec = 0;
min = 0;
hour = 12;
timeClockDispState = HOUR_MIN;
}
void StopWatch_init()
{
stopwatch_milisec = 0;
stopwatch_sec = 0;
stopwatch_min = 0;
stopwatch_hour = 0;
stopWatchState = STOP;
}
void TimeClock_incMilisec() // 시간 계산 알고리즘
{
milisec = (milisec + 1) % 1000;
if(milisec) return;
sec = (sec + 1) % 60;
if(sec) return;
min = (min + 1) % 60;
if(min) return;
hour = (hour + 1) % 24;
}
void StopWatch_incMilisec() // 시간 계산 알고리즘
{
if(stopWatchState == RUN){
stopwatch_milisec = (stopwatch_milisec + 1) % 1000;
}
else{
return;
}
if(stopwatch_milisec) return;
stopwatch_sec = (stopwatch_sec + 1) % 60;
if(stopwatch_sec) return;
stopwatch_min = (stopwatch_min + 1) % 60;
if(stopwatch_min) return;
stopwatch_hour = (stopwatch_hour + 1) % 24;
}
void Watch_excute()
{
Watch_eventButton();
Watch_runState();
}
void Watch_eventButton()
{
switch(watchState)
{
case TIMECLOCK:
if(Button_getState(&btnMode) == RELEASED){
watchState = STOPWATCH;
LCD_init();
break;
case STOPWATCH:
if(Button_getState(&btnMode) == RELEASED){
watchState = TIMECLOCK;
LCD_init();
break;
}
}
}
}
void Watch_runState()
{
switch(watchState)
{
case STOPWATCH:
stopWatch_eventButton();
StopWatch_runState();
break;
case TIMECLOCK:
TimeClock_eventButton();
TimeClock_runState();
break;
}
}
void TimeClock_eventButton()
{
switch(timeClockDispState)
{
case HOUR_MIN:
if(Button_getState(&btnWatchMode) == RELEASED){
timeClockDispState = SEC_MIL;
}
break;
case SEC_MIL:
if(Button_getState(&btnWatchMode) == RELEASED){
timeClockDispState = HOUR_MIN;
}
break;
}
}
void TimeClock_runState()
{
static uint8_t prevSec = 0xff;
if(sec != prevSec){
prevSec = sec;
char buff[30];
sprintf(buff, "Time Clock");
LCD_writeStringXY(0, 0, buff);
sprintf(buff, "%02d:%02d:%02d", hour, min, sec);
LCD_writeStringXY(1, 0, buff);
}
switch(timeClockDispState)
{
case HOUR_MIN:
TimeClock_dispHourMin();
break;
case SEC_MIL:
TimeClock_dispSecMil();
break;
}
}
void TimeClock_dispHourMin()
{
uint16_t timeClockData;
if(milisec < 500) FND_colonOn();
else FND_colonOff();
timeClockData = (hour * 100) + min;
FND_setFndData(timeClockData);
}
void TimeClock_dispSecMil()
{
uint16_t timeClockData;
if((milisec % 100) < 50) FND_colonOn();
else FND_colonOff();
timeClockData = (sec * 100) + (milisec / 10);
FND_setFndData(timeClockData);
}
void stopWatch_eventButton()
{
switch(stopWatchState)
{
case STOP:
if(Button_getState(&btnRunStop) == ACT_PUSHED){
stopWatchState = RUN;
}
else if(Button_getState(&btnReset) == ACT_PUSHED){
stopWatchState = RESET;
}
break;
case RUN:
if(Button_getState(&btnRunStop) == ACT_PUSHED){
stopWatchState = STOP;
}
break;
case RESET:
stopWatchState = STOP;
break;
}
}
void StopWatch_runState()
{
uint16_t stopWatchData;
static uint8_t prevSec = 0xff;
{
prevSec = stopwatch_sec;
char buff[30];
sprintf(buff, "Stop Watch");
LCD_writeStringXY(0, 0, buff);
sprintf(buff, "%02d:%02d:%03d", stopwatch_min, stopwatch_sec, stopwatch_milisec);
LCD_writeStringXY(1, 0, buff);
}
if(stopWatchState == RESET){
stopwatch_milisec = 0;
stopwatch_sec = 0;
stopwatch_min = 0;
stopwatch_hour = 0;
}
stopWatchData = (stopwatch_min%10 * 1000) + (stopwatch_sec*10) + (stopwatch_milisec/100);
FND_setFndData(stopWatchData);
}