[AVR] DP Blink/Stopwatch,Clock 구분 LED표시 시간 표시 기능
2021. 11. 9. 22:14ㆍ코딩/AVR
main.c
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "global.h" // 현재 내 디렉토리 밑에 있는 화일을 include할때는 ""
#include "fnd.h"
#include "button.h"
#include "time_clock.h"
//button : watch <--> stopwatch
//button2: stopwatch start <--> stop
//button3: stopwatch reset
#define WATCH 0
#define STOPWATCH 1
unsigned char mode_state=WATCH;
//for stopwatch
#define STOP 0
#define RUN 1
#define RESET 2
unsigned char stop_watch_state=STOP;
void inc_stop_watch_clock();
void stop_watch_stop_state();
void stop_watch_run_state();
void stop_watch_reset_state();
//0.001sec => 1ms마다 이곳으로 들어온다.
ISR(TIMER0_OVF_vect)
{
static uint16_t sec_count=0;
if (++sec_count >= 1000)
{
sec_count=0;
inc_time_sec();
}
if (stop_watch_state == RUN)
{
inc_stop_watch_clock();
}
fnd_display();
timeTick++;
}
uint16_t stop_watch_clock=0; //전역변수
void inc_stop_watch_clock()
{
static uint8_t count =0;
if (++count >= 100)
{
count =0;
stop_watch_clock++;
}
}
int main(void)
{
TIME myTime;
button_Init();
fnd_init();
//분주비를 64로 설정 16MHZ / 64 => 250KHZ 이렇게 설정시 TIM0 OV 256/250000
//0.001sec => 1ms마다 타이머 int가 발생된다.
TCCR0 |= (1 << CS02) | (0 << CS01) | (0 << CS00);
TIMSK |= (1 << TOIE0); // timer overflow int 설정 TCNT0의 register 값이256이 되는순간 발생
sei(); //모든 인터럽트가 실행이 되도록 대문을 연다
myTime.hour=00;
myTime.min=00;
myTime.sec=00;
set_time_clock(myTime);
// botton의 동작 상황을 체크하면서 상태 전이를 할수 있도록한다.
while (1)
{
switch (mode_state)
{
case WATCH:
get_time_clock(&myTime);
set_fnd_data(myTime.min*100 + myTime.sec);
if (getButton1State()) //버튼 1이 눌려졌다
{ PORTA = 0x01;
mode_state = STOPWATCH;
}
break;
case STOPWATCH:
switch (stop_watch_state)
{
case STOP:
stop_watch_stop_state();
break;
case RUN:
stop_watch_run_state();
break;
case RESET:
stop_watch_reset_state();
break;
}
if (getButton1State()) //버튼 1이 눌려졌다
{ PORTA = 0x02;
mode_state = WATCH;
}
}
}
}
void stop_watch_stop_state()
{
set_fnd_data(stop_watch_clock);
if (getButton2State()) //버튼1을 누르면
{
stop_watch_state=RUN; //run상태로 상태처리
}
if (getButton3State()) //버튼 2를 누름 reset버튼
{
stop_watch_state=RESET; //
}
}
// 현제 스톱워ㅣ가 돌고있는 상태에서 버튼 1 누르면 스탑상태
void stop_watch_run_state()
{
set_fnd_data(stop_watch_clock);
if (getButton2State()) //버튼1을 누르면
{
stop_watch_state=STOP; //STOP상태로 상태처리
}
}
//현제 스톱워치가 리셋상태에서 STOP모드로 복귀
void stop_watch_reset_state()
{
stop_watch_clock=0;
set_fnd_data(stop_watch_clock);
stop_watch_state=STOP; //stop상태로 전이
}
fnd.c
#include "fnd.h"
#include "extern.h"
uint16_t fnd_data;
void set_fnd_data(uint16_t data)
{
fnd_data = data;
}
uint16_t get_fnd_data()
{
return fnd_data;
}
void set_sec(uint32_t sec)
{
sec_data = sec; // 초를 받아서 save
}
void fnd_display(void)
{
#if 1 // common 애노우드
uint8_t fnd_font[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xd8,0x80, 0x98}; // common +가 공통애노우드
#else
uint8_t fnd_font[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x27,0x7f, 0x67}; // common -가 캐소우드
#endif
uint16_t data = get_fnd_data(); // 현재의 초를 가져 온다.
uint8_t dot[]={0x7f,0xff}; // 01111111 11111111 을 의미 dp만 빛이들어오거나 안들어오거나 신호를줌
FndPositionState++;
FndPositionState %=4; // FndPositionState = FndPositionState % 4;와 동일
switch(FndPositionState)
{
case 0: // digit1 선택 1000의 자리
FND_DIGIT_PORT = 0b10000000; // D1만ON 시키고 나머지는 OFF FND_DIGIT_PORT = 0b01111111;
FND_DATA_PORT=fnd_font[data/1000%10]; // 60분이 되기 전까지의 값을 출력 0~59분
// and문을 사용하여 양쪽이 다 신호가 들어갈때 만 신호가 출력됨 에노드 문이기 때문에 0일때 출력이 들어간다
//0x7f일때 출력이 들어가서 dp에 신호가 나오고 0xff일때 0과1의 and가 되어서 출력이 나오지 않는다
break;
case 1: // digit2 선택 100의 자리
FND_DIGIT_PORT = 0b01000000; // D2만ON 시키고 나머지는 OFF FND_DIGIT_PORT = 0b01111111;
FND_DATA_PORT= (fnd_font[data/100%10] & dot[data%2]); // 10분이 되기 전까지의 값을 출력 0~9분
break;
//dot[data/10%2]
case 2: // digit3 선택 10의 자리
FND_DIGIT_PORT = 0b00100000; // D3만ON 시키고 나머지는 OFF FND_DIGIT_PORT = 0b01111111;
FND_DATA_PORT= fnd_font[data/10%10]; // 1분이 되기 전까지의 값을 출력 0~59초 출력
break;
case 3: // digit4 선택 1의 자리
FND_DIGIT_PORT = 0b00010000; // D4만ON 시키고 나머지는 OFF FND_DIGIT_PORT = 0b01111111;
FND_DATA_PORT= fnd_font[data%10]; // 10가 되기 전의 값을 출력 (0~9)
break;
}
}
void fnd_init(void)
{
FND_DATA_DDR=0xff;
FND_DIGIT_DDR=0xff;
FND_DIGIT_PORT=0x00;
FND_LED_PORT=0x00;
FND_LED_DDR=0xff;
}
동작 동영상
상단의 붉은 LED 2개를 각각 모드에 따라 빛나게 하였습니다.
'코딩 > AVR' 카테고리의 다른 글
[AVR]출입 통제 시스템 (3) | 2021.11.09 |
---|---|
[AVR] 계산기 (0) | 2021.11.09 |
[AVR]전자레인지 동작 동영상 (0) | 2021.11.09 |
[AVR] 모터 속도제어 (선풍기) (0) | 2021.11.09 |
[AVR] UltraSonic 활용 (0) | 2021.11.09 |