반응형
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
/*
 * avr-0910.cpp
 *
 * Created: 2018-09-10 오전 9:20:31
 * Author : USER
 */ 
 
#include <avr/io.h>
#define F_CPU 16000000
#include <util/delay.h>
#include "lcd.h"
#include <avr/interrupt.h>
#include <stdio.h>
 
void io_init(void)
{
    MCUCR|=(1<<SRE) | (1<<SRW10);
    XMCRA=(1<<SRL2) | (0<<SRL1) | (0<<SRL0) | (1<<SRW01) | (1<<SRW00) | (1<<SRW11);
    XMCRB |= 0x00;
}
unsigned int count =0, sec=0, min=0,hour=0;
unsigned int mode =0, ampm =0;
unsigned int flag=0;;
 
ISR(TIMER0_OVF_vect){
    TCNT0 =6;
    count++;
    if (count >1000){
        sec++; count=0;
        if(sec>=60){
            min++; sec=0;
            if (min>=60){
                hour++; min=0;
                if(hour>12){
                    hour=0;
                    if(ampm == 0) ampm =1;
                    else if(ampm ==1) ampm=0;
                    count =0;
                }
            }
        }
    }
}
 
int main(void)
{
    /* Replace with your application code */
    io_init();
    lcd_init();
    
    DDRE = 0x8f// 스위치 
    PORTE = 0x70; // 추후 확인 필요
    
    // 타이머 인터럽트 레지스터
    TIMSK = 0x01// R/W 선택 TIMER 0 사용
    TCCR0 =0x04// 분주비 64
    TCNT0 =6// 0에서 시작 255가되어 256이 되면 OVF가 되어 인터럽트 구문을 실행한다.
    
    /*
    1/16000000 = 0.0000000625
    분주비가 64
    0.0000000625 *64 = 0.000004 // TCNT0가 1올라가는 속도.
    ISR이 발생하는 시간 = 0.000004
    TCNT 250 회로 OVF 발생시 걸리는 시간 0.001
    500번이 OVF 인터럽트가 발생하면 1초가 된다.
    */
    
    sei();
    char temp[16];
    
    while (1
    {
        //input
        if (((PINE && 0x10)== 0x00&& flag ==0){
            mode++;
            flag=1;
            if (mode >=2)
            mode=0;
        }
        else if (PINE ==0xff) flag=0;    
        
        //display
        switch(mode){
            case 0:
            mode =1;
            sprintf(temp,"%d  :  %d  :  %d  %s",hour,min,sec,(ampm=0)?"AM":"PM");
            lcd_putsf(0,0,"  Normal Mode  ");
            lcd_putsf(0,1,temp);
        
            case 1:
            mode =0;
            sprintf(temp,"%d  :  %d  :  %d  %s",hour,min,sec,(ampm=0)?"AM":"PM");
            if (sec%2 ==0){
                temp[2]=temp[3= ' ';
            }
            lcd_putsf(0,0,"  Modify Mode  ");
            lcd_putsf(0,1,temp);
        }
        
 
    }
}
cs

 

 

// 스위치 DDRE 설정 다시 확인 후 시계 만들기 완성 소스

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
/*
 * avr-0910.cpp
 *
 * Created: 2018-09-10 오전 9:20:31
 * Author : USER
 */ 
 
#include <avr/io.h>
#define F_CPU 16000000
#include <util/delay.h>
#include "lcd.h"
#include <avr/interrupt.h>
#include <stdio.h>
#define LED_SEL1 (*(volatile unsigned char *)0xA000)
#define LED_SEL2 (*(volatile unsigned char *)0xB000)
#define FND (*(volatile unsigned char *)0x8000)
 
void io_init(void)
{
    MCUCR|=(1<<SRE) | (1<<SRW10);
    XMCRA=(1<<SRL2) | (0<<SRL1) | (0<<SRL0) | (1<<SRW01) | (1<<SRW00) | (1<<SRW11);
    XMCRB |= 0x00;
}
unsigned int count =0, sec=0, min=0,hour=0;
unsigned int mode =0, ampm =0;
unsigned int flag=0;
unsigned int saveSec=0, saveMin=0,saveHour=0;
 
ISR(TIMER0_OVF_vect){
    TCNT0 =6;
    count++;
    if (count >1000){
        sec++; count=0;
        if(sec>=60){
            min++; sec=0;
            if (min>=60){
                hour++; min=0;
                if(hour>12){
                    hour=0;
                    if(ampm == 0) ampm =1;
                    else if(ampm ==1) ampm=0;
                    count =0;
                }
            }
        }
    }
}
 
int main(void)
{
    /* Replace with your application code */
    io_init();
    lcd_init();
    
    DDRE = 0x8f// 스위치 
    PORTE = 0xff
    
    // 타이머 인터럽트 레지스터
    TIMSK = 0x01// R/W 선택 TIMER 0 사용
    TCCR0 =0x04// 분주비 64
    TCNT0 =6// 6에서 시작 255가되어 256이 되면 OVF가 되어 인터럽트 구문을 실행한다.
    
    /*
    1/16000000 = 0.0000000625
    분주비가 64
    0.0000000625 *64 = 0.000004 // TCNT0가 1올라가는 속도.
    ISR이 발생하는 시간 = 0.000004
    TCNT 250 회로 OVF 발생시 걸리는 시간 0.001
    500번이 OVF 인터럽트가 발생하면 1초가 된다.
    */
    
    mode =0;
    sei();
    char temp[16];
    int sel =0;
    while (1
    {
        
        //input
        if (((PINE & 0x10)== 0x00&& flag ==0 ){    
            sel=0;
            mode++;
            if(mode >=2)mode =0;
            flag=1;
        }    
        // 숫자 증가 input
        else if (((PINE & 0x20)== 0x00)&& flag==0 && mode==1 ){
            if (sel==0){hour++;
                if (hour >=60) hour =0;
            }
            else if (sel ==1){ min++;
                if(min>=60) min=0;
            }
            else if(sel ==2){ sec++;
                if(sec>=60) sec=0;
            }
            else if(sel==3){
                if (ampm ==0) ampm =1;
                else if (ampm ==1)  ampm=0;
            }
            flag=1;
        }
        // 숫자 선택 셀 증가
        else if (((PINE & 0x40)== 0x00)&& flag==0 && mode==1 ){
            sel++;
            if (sel >=4) sel=0;
            flag=1;
        }
        else if (PINE == 0xff){ flag=0;    
        }
        
        //display
        switch(mode){
            case 0:
            sprintf(temp," %2d :%2d :%2d %2s",hour,min,sec,(ampm==0)?"AM":"PM");
            lcd_putsf(0,0,"  Normal Mode  ");
            lcd_putsf(0,1,temp);
                break;
            case 1:
            sprintf(temp," %2d :%2d :%2d %2s",hour,min,sec,(ampm==0)?"AM":"PM");    
            if (sec%2 ==0){
                if(sel==0)temp[1= temp[2=' ';
                else if(sel==1)temp[5= temp[6=' ';
                else if(sel==2)temp[9= temp[10=' ';
                else if (sel==3)temp[12= temp[13=' ';
                else sel =0;
            }
            lcd_putsf(0,0,"  Modify Mode  ");
            lcd_putsf(0,1,temp);
                break;
        }
    }
}
cs

 

 

 

 

/*

// SW4, SW5, SW6

SW4 입력시 모드가 바뀌며, Nomal Mode , Modify Mode가 있다.

Modify Mode 에서는 SW5 과 SW6을 입력하여 시간과 AM/PM을 변경 할 수 있다.

*/

 

 

반응형
반응형
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
/*
 * avr-0910.cpp
 *
 * Created: 2018-09-10 오전 9:20:31
 * Author : USER
 */ 
 
#include <avr/io.h>
#define F_CPU 16000000
#include <util/delay.h>
#include "lcd.h"
#include <avr/interrupt.h>
#include <stdio.h>
 
void io_init(void)
{
    MCUCR|=(1<<SRE) | (1<<SRW10);
    XMCRA=(1<<SRL2) | (0<<SRL1) | (0<<SRL0) | (1<<SRW01) | (1<<SRW00) | (1<<SRW11);
    XMCRB |= 0x00;
}
unsigned int count =0, sec=0;
 
ISR(TIMER0_OVF_vect){
    TCNT0 =256-25;
    count++;
    if (count >625){
        sec++; count=0;
    }
}
int main(void)
{
    /* Replace with your application code */
    io_init();
    lcd_init();
    
    // 타이머 인터럽트 레지스터
    TIMSK = 0x01// R/W 선택 TIMER 0 사용
    TCCR0 =0x07// 분주비 1024
    TCNT0 =256-25// 0에서 시작 255가되어 256이 되면 OVF가 되어 인터럽트 구문을 실행한다.
    
    /*
    1/16000000 = 0.0000000625
    분주비가 1024
    0.0000000625 *1024 = 0.000064 // TCNT0가 1올라가는 속도.
    ISR이 발생하는 시간 = 0.016384
    약 61번이 OVF 인터럽트가 발생하면 1초가 된다.
    */
    
    sei();
    char temp[16];
    
    
    while (1
    {
        sprintf(temp,"%d",sec);
        lcd_putsf(0,0,temp);        
    }
}
cs

 

// 해당 소스는 정확한 1초가 아니다.

 

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
/*
 * avr-0910.cpp
 *
 * Created: 2018-09-10 오전 9:20:31
 * Author : USER
 */ 
 
#include <avr/io.h>
#define F_CPU 16000000
#include <util/delay.h>
#include "lcd.h"
#include <avr/interrupt.h>
#include <stdio.h>
 
void io_init(void)
{
    MCUCR|=(1<<SRE) | (1<<SRW10);
    XMCRA=(1<<SRL2) | (0<<SRL1) | (0<<SRL0) | (1<<SRW01) | (1<<SRW00) | (1<<SRW11);
    XMCRB |= 0x00;
}
unsigned int count =0, sec=0;
 
ISR(TIMER0_OVF_vect){
    TCNT0 =256-5;
    count++;
    if (count >500){
        sec++; count=0;
    }
}
int main(void)
{
    /* Replace with your application code */
    io_init();
    lcd_init();
    
    // 타이머 인터럽트 레지스터
    TIMSK = 0x01// R/W 선택 TIMER 0 사용
    TCCR0 =0x04// 분주비 64
    TCNT0 =256-5// 0에서 시작 255가되어 256이 되면 OVF가 되어 인터럽트 구문을 실행한다.
    
    /*
    1/16000000 = 0.0000000625
    분주비가 64
    0.0000000625 *64 = 0.000004 // TCNT0가 1올라가는 속도.
    ISR이 발생하는 시간 = 0.000004
    TCNT 250 회로 OVF 발생시 걸리는 시간 0.001
    500번이 OVF 인터럽트가 발생하면 1초가 된다.
    */
    
    sei();
    char temp[16];
    
    
    while (1
    {
        sprintf(temp,"%d",sec);
        lcd_putsf(0,0,temp);        
    }
}
cs
반응형
반응형

* 인터럽트 : 방해하다, 훼방놓다의 뜻, 긴급하거나 불규칙적인 사건의 처리, 외부와의 인터페이스, 폴링(polling)으로 처리하기에는 프로세싱 타임 낭비

HOW 

 - 현재 수행중인 일을 잠시 중단하고 급한 일을 처리

 - 일이 끝나면 본래의 일을 다시 이어서 수행

 - 이때, 급한 일을 해결하는 작업을 인터럽트 서비스 루틴이라 하는데, 각 인터럽트마다 고유의 인터럽트 서비스 루틴 존재

 - 인터럽트가 여러 개 동시에 걸리면 우선 순위에 따라 조치

* 인터럽트 서비스 루틴

 - 인터럽트가 발생하면 프로세서는 현재 수행중인 프로그램을 멈추고 상태 레지스터와 PC 등을 스택에 잠시 저장 후 인터럽트 서비스 루틴으로 점프, 인터럽트 서비스 루틴을 실행한 후에는 이전의 프로그램으로 복귀하여 정상적인 절차를 실행한다.


* 인터럽트 스위치로 1/100 스톱워치 만들기

 - 메인

1. 초기설정

2. state 변수 값 설정 : stop

3. 인터럽트 활성화

4. state 검사 후 stop 상태시 복사된 10초, 1초, 1/10초, 1/100초 변수를 디스플레이하고, go 상태면 현재의 10초, 1초, 1/10초, 1/100초 변수를 디스플레이
 - 인터럽트 INT4
1. state 값이 stop시 go 변경
2. state go 일시 stop으로 변경 후 이때 시간 값 복사 저장
 - 인터럽트 INT5
1. 변수 및 복사된 시간 값 0으로 초기화
2. state 값 stop으로 초기화

#include <avr/io.h> 

#include <avr/interrupt.h>

#define F_CPU 16000000UL

#define __DELAY_BACKWARD_COMPATIBLE__

#include <util/delay.h>

#define STOP 0

#define GO 1

volatile int cur_time = 0;

volatile int stop_time = 0;

volatile int state = STOP; 

unsigned char digit[]= {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7c, 0x07, 0x7f, 0x67};

unsigned char fnd_sel[4] = {0x01, 0x02, 0x04, 0x08};

SIGNAL(SIG_INTERRUPT4) 

if (state == STOP)

 state = GO; 

  else 

state = STOP; 

  stop_time = cur_time; 

SIGNAL(SIG_INTERRUPT5) 

{

state = STOP; 

cur_time = 0; stop_time = 0; 

}

void init( ) 

{

DDRC = 0xff; // FND Data 

DDRG = 0x0f; // FND Select 

DDRE = 0xcf; // INT4, 5

PORTC = digit[0]; PORTG = 0x0f; EICRB = 0x0a; //falling edge 

EIMSK = 0x30; //interrupt en 

sei(); 

}


void display_fnd(int count) // 수행시간 = 약 10ms 

int i, fnd[4]; 

fnd[3] = (count/1000)%10; // 천 자리

fnd[2] = (count/100)%10; // 백 자리

fnd[1] = (count/10)%10; // 십 자리 

fnd[0] = count%10; // 일 자리 

for (i=0; i<4; i++)

{

PORTC = digit[fnd[i]];

PORTG = fnd_sel[i];

_delay_ms(2+i%2); 

}

}


int main()

{

init( );

while(1)

if (state == STOP)

display_fnd(stop_time);

else display_fnd(cur_time);

cur_time++;

}

}

반응형

'Project > j-kit-128-1실습' 카테고리의 다른 글

FND_Display with Timer/Counter  (0) 2018.10.01
LED 제어  (0) 2016.02.26
FND 실습  (0) 2016.02.26
FND 실습 1/100초 스탑워치, 24시간 디지털 시계만들기  (0) 2016.02.26
회로도 참고  (0) 2016.02.26

+ Recent posts