마이크로프로세서응용 마이크로프로세서응용
AT 128 I/O B d T
ATmega128 I/O Board Test Timer & Interrupt Handling
11
Lab3: Multiple Segment Driving technique
에 이라는 숫자가 동시에 나타나도록 프로그래밍
p g g q
7 Segment 에 0123 이라는 숫자가 동시에 나타나도록 프로그래밍
알고리즘 요약:첫번째 세그먼트를 시킨다
1] 첫번째 세그먼트를 enable 시킨다
2] 0 에 해당하는 세그먼트 데이터를 쓴다
3] 약간의 시간지연을 위한 지연함수를 부른다 ( 약 1/100초 정도)
3] 약간의 시간지연을 위한 지연함수를 부른다. ( 약 1/100초 정도)
4] 두번째 세그먼트를 enable 시킨다.
5] 1 에 해당하는 세그먼트 데이터를 쓴다
5] 1 에 해당하는 세그먼트 데이터를 쓴다.
6] 약간의 시간지연을 위한 지연함수를 부른다.
7] 12] 마찬가지로
7] … 12] 마찬가지로
13] 1행으로 가서 다시 수행.Lab3: Multiple Segment Driving technique
.include "m128def.inc"
p g g q
rjmp RESET ;Reset Handle
.def temp = r16
.def segdata = r17
.def segen = r18
def segcnt = r19
.def segcnt = r19
.org 0x46 ;
RESET:
ldi temp,low(RAMEND) ; Load low byte address of end of RAM into register R16 out SPL,temp ; Initialize stack pointer to end of internal RAM
ldi hi h(RAMEND) L d hi h b dd f d f RAM i i R16
ldi temp,high(RAMEND) ; Load high byte address of end of RAM into register R16 out SPH, temp ; Initialize high byte of stack pointer to end of internal RAM
ser temp ;
out DDRB, temp ; Set Port B as outputs
ldi temp, $0F ;
out DDRC, temp ; Set least significant 4bits of Port C as outputs
ldi XH, High(digit4) ;
ldi XL, Low(digit4) ; X points the start address of digit4 array
ldi temp, 1 ;
st X+, temp ;
ldi temp, 2 ;
st X+, temp ;
ldi t 3
ldi temp, 3 ;
st X+, temp ;
ldi temp, 4 ;
st X, temp ;
Lab3: Multiple Segment Driving technique p g g q
f
forever :
ldi XH, High(digit4) ;
ldi XL, Low(digit4) ; X points the start address of digit4 array
ldi segen, $01 ; Enable signal for the first character of 7 segment array
ldi cnt, 4 ;
loop4:
ldi ZH, HIGH(2*SegTable) ; Since program memory is 16 bit (2 byte) ldi ZL, LOW(2*SegTable) ; we have to multiply 2 at the starting index
ld temp, X+ ;
ld temp, X+ ;
clr r0 ;
add ZL, temp ;
adc ZH, r0 ;
l d t Z
lpm segdata, Z ;
out PORTC, segen ;
out PORTB, segdata ;
rcall delay1ms ;
lsl segen ;
dec cnt ;
brne loop4 ;
rjmp forever ;
Lab3: Multiple Segment Driving technique
d l 1
p g g q
delay1ms:
ldi r22, 255
loop:
dec r22
brne loop
ret SegTable:
.db $03, $9f, $25, $0d, $99, $49, $41, $1f, $01, $09 .DSEG
digit4:
.byte 4 rjmp reset GP Register 32
Reset: I/O Register 64
Extended I/O Register 128
12
digit4 ($0100)
// main program hereI/O Register 64
23 4 segdata
$9f $03
$0d $25
$49 $99
$1f $41
SP ( Stack Pointer : $10FF)
$09 $01
Timer / Counter
메인 루틴과 별도로 동작하다가 TCNTx 의 설정된 값이 완료되면 인터 럽트 요구를 발생
내부 클럭 사용하면 타이머, 외부 클럭 사용하면 카운터
4개의 독립된 타이머/카운터 내장
UP 카운터로 동작 오버플러우($FF->$00) 되면 Timer Overflow Interrupt
UP 카운터로 동작, 오버플러우($FF->$00) 되면 Timer Overflow Interrupt
타이머 0,2 는 8 비트, 타이머 1, 3 은 16 비트
인터럽트 설정시 ( 예를 들어 Timer 0 라고 하면 )
TCCR0 세팅 ( 클럭소스 결정 ) - Timer/Counter Control Register
TCNT0 세팅 ( 초기 카운트 값 설정 )
TIMSK 세팅 ( 인터럽트 발생 여부 결정 )( )
SEI 세팅 ( 전체적으로 인터럽트 허용 여부 설정 )
PreScaler for Timer 0 & 1
타이머/카운터의 이벤트 시간을 조절
타이머/카운터의 이벤트 시간을 조절
CS00,CS01,CS02 를 가지고 Timer 0 의 클럭소스 결정
Clock Select(CS) bits
Timer Counter Control Register (TCCR)
Timer Counter Control Register (TCCR)
ldi temp, $06 ; out TCCR0, temp
Timer Clock = 16MHz/256
Timer Overflow Interrupt
카 터 값 값이 $ $ 변할 때 인터럽 발생
p
카운터 값(TCNT) 값이 $FF -> $00 로 변할 때 인터럽트 발생
$FF TCNT0 Load value
interrupt interrupt interrupt interrupt
ldi temp, $00 ; out TCNT0, temp
Clear TCNT 0 register
Timer Interrupt Mask Register Setting p g g
Timer Overflow Interrupt Enable 0 (TOIE0) 를 세팅
ldi temp, $01 ; out TIMSK, temp
최종적으로 를 로 세팅 시켜야 한다
최종적으로 Global Interrupt Enable Flag 를 1 로 세팅 시켜야 한다.
sei ;
Interrupt Vector Table p
Lab 4 : Clock Design with Timer Interrupt
약 / 초마다 타이머 인터럽트가 발생 매 초마다 세그먼트 증가
g p
약 1/244 초마다 타이머 인터럽트가 발생, 매 1초마다 세그먼트 증가
알고리즘 :
타이머 인터럽트 발생을 위한 타이머 컨트롤 레지스터 설정
타이머 인터럽트 발생을 위한 타이머 컨트롤 레지스터 설정
( Timer0 Clock = Main Clock / 256, Overflow occurs at every 256 timer clock )
무한 루프를 돌면서 과제 3의 결과를 디스플레이무 루 를 돌 서 과제 의 결과를 디 플레이
타이머 인터럽트 서비스 루틴에서 카운트값 증가
1초가 경과(cnt=42)됨을 알리면 세그먼트의 데이터 값 1 증가
서비스 루틴에서 데이터 증가 시 9 or 5 이상이 되면 특수 처리를 해주어야 함.
Lab 4 : 7 Segment Display with Timer g p y
.include "m128def.inc"
.ORG 0
rjmp RESET ;Reset Handler or main program start
.ORG $0020
rjmp TIM0_OVF ;Timer 0 Overflow Service Routine
.ORG $0046
RESET:
// Set Stack Pointer
// Set Port Direction Register
// Set Timer 0 interrupt related registers // Display 4 digits in data memory ( ditit 4 ) // Display 4 digits in data memory ( ditit 4 ) TIM0_OVF:
// add timer 0 overflow service routine rti ;
segdata:
.db $03, $9f, $25, $0d, $99, $49, $41, $1f, $01, $09 .DSEG
digit4:
.byte 4
External Interrupt p
INT0, INT1, …, INT7 Pin 에 의하여 트리거 된다
INTn 핀이 출력으로 지정되었어도 인터럽트 발생
인터럽트의 형태 ( 저 레벨 rising edge falling edge ) 는 MCUCR 로 결정
인터럽트의 형태 ( 저 레벨, rising edge, falling edge ) 는 MCUCR 로 결정
인터럽트 발생시
PC 를 스텍에 저장
스텍 포인터는 2 감소
인터럽트 벡터 테이블로 이동
실제 인터럽트 서비스 루틴으로 이동
실제 인터럽트 서비스 루틴으로 이동
서비스 수행후 PC 값 복귀
스텍 포인터 2 증가
External Interrupt Sense Control p
우선적으로 External Interrupt 의 Sense 제어 레지스터를 설정.
ldi temp, $2A ; sts EICRA, temp
Set Ext Int 0, 1 and2
as falling Edge Sensitive
External Interrupt Mask Register p g
ldi temp $07;
그 다음 Interrupt Mask Register 를 세팅해서 인터럽트가 걸릴 수 있도록 설정
ldi temp, $07;
sts EIMSK, temp
Set External Interrupt 0,1,2 enable Note EIMSK is not an enable. Note EIMSK is not an I/O register but an external I/O register. Thus we have to use sts instead of out.
최종적으로 Global Interrupt Enable Flag 를 1 로 세팅 시켜야 한다.
sei ;
Lab 5 : 7 Segment Timer with Reset g
외부 인터럽트 버튼을 누르면 시계 데이터값이 초기화
알고리즘
알고리즘 : 외부 인터럽트 0 발생을 위한 인터럽트 컨트롤 레지스터 설정 인터럽트 서비스 루틴에서 데이터 값을 모두 0으로 초기화
인터럽트 서비스 루틴에서 데이터 값을 모두 0으로 초기화
Lab 5 : Template Code p
.include "m128def.inc"
.ORG 0
rjmp RESET ;Reset Handler or main program start
rjmp $0000 ;
rjmpj p EXT_INT1_ ; External Interrupt 1 service routine handler; p
.ORG 20
rjmp TIM0_OVF ;Timer 0 Overflow Service Routine
.ORG $0046
RESET:
// Set Stack Pointer // Set Stack Pointer
// Set Port Direction Register
// Set Timer 0 interrupt related registers ( ex: rcall Timer0_Init ; // Set External Interrupt related registers ( ex: rcall Eint0_Init ; //
// Display 4 digits in data memory ( ditit 4 ) EXT_INT0:
// add external interrupt service routine rti ;
TIM0_OVF:
// add timer 0 overflow service routine rti ;
segdata:
.db $81,$cf, $92, $86, $cc, $a4, $a0, $8f, $80, $84 .DSEG
digit4:
.byte 4