Last active
August 29, 2015 14:02
-
-
Save nohponex/6dc412858b9006e14ed2 to your computer and use it in GitHub Desktop.
ΤΗΜΜΥ - Μικροεπεξεργαστές και περιφερειακά : Εξετάσεις 02/2013, Θέμα 2, 3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Thema 2 02/2013 | |
* Output Mean_LSB => PORTB 7-0 ; Negative logic | |
* Cable from OC1A (PD5) to INT0 (PD2) | |
*/ | |
.include "m128def.inc" | |
.def adc_mux = r18 | |
.def temp = r16 | |
.def temp2 = r17 | |
.def sumH = r20 | |
.def sumL = r21 | |
.equ ADC_MASK = 0b01000000 | |
.equ upper_bound = 0x348 | |
.equ TIMER1_ORC = 58593; ( 15 sec ) ; clocks = ( 15sec )*( CLK /N ) , CLK = 4Mhz, N = 1024 | |
.equ TIMER3_ORC = 19531; ( 5 sec ) ; clocks = ( 5sec )*( CLK /N ) , CLK = 4Mhz, N = 1024 | |
.org 0x00 | |
jmp RESET | |
.org 0x02 | |
jmp INT0_ISR | |
.org 0x2A | |
jmp ADC_ISR | |
.org 0x34 | |
jmp COUNTER3_COMPA_ISR ;Counter/timer 3 compare match A | |
;Reset ISR | |
RESET: | |
;SETUP STACK POINTER | |
ldi temp, HIGH( RAMEND ) | |
out SPH, temp | |
ldi temp, LOW( RAMEND ) | |
clr sumH | |
clr sumL | |
;SET PD5 as output | |
sbi DDRD,5 | |
;SET PD5 HIGH ( negative logic ) | |
sbi PORTD,5 | |
;SET PORTB as output | |
ser temp | |
out DDRB, temp | |
;SET PORTB HIGH ( negative logic ) | |
out PORTB, temp | |
;SETUP INT0 | |
;Enable INT0 Mask | |
ldi temp, 0b00000001; INT0 => 1 | |
out EIMSK, temp | |
;Set INT0 Sense control | |
ldi temp, 0b00000010; ISC10, ISC00 -> 10 ( falling edge ) | |
sts EICRA, temp;out EICRA, temp ; Use STS instead of out ( EICRA address is out of range for out ) | |
clr adc_mux | |
;SETUP ADC | |
ldi temp, ADC_MASK ; ( 0b01000000 ) REFS => 01 MUX => 0000 | |
out ADMUX, temp | |
;ENABLE ADC ( AVR clock = 4MHz, 13 Clocks per sample, 2500 Samples/sec ===> ADC prescaler ~= 128 ) | |
ldi temp, 0b11101111; ADEN => 1, ADCS => 1, ADFR => 1, ADIF => 0, ADIE => 1, ADSP => 111 ( ADC prescaler : 128 ) | |
out ADCSRA, temp | |
;SETUP TIMER1 | |
;SET OCR1A value | |
ldi temp, HIGH( TIMER1_ORC ) | |
out OCR1AH, temp | |
ldi temp, LOW( TIMER1_ORC ) | |
out OCR1AL, temp | |
;SET mode CTC AND prescaler AND Compare output Mode ( COM ) ( WG => 0100 (CTC ) ) | |
ldi temp, 0b10000000; COM1A=> 10 WG1,WG0 =>00 | |
out TCCR1A, temp | |
ldi temp, 0b00001101; WG3, WG2 => 01, CS => 101 ( prescaler : 1024 ) | |
out TCCR1B, temp | |
; ENABLE GLOBAL INTERRUPTS | |
sei | |
;INFINITE LOOP | |
loop: | |
jmp loop | |
;EXTERNAL ADC ISR | |
ADC_ISR: | |
in temp, ADCL | |
in temp2, ADCH | |
add sumL, temp | |
adc sumH, temp2 | |
inc adc_mux | |
cpi adc_mux, 0b1000 | |
brlo dont_reset_adc_mux | |
;reset adc_mux | |
clr adc_mux | |
dont_reset_adc_mux: | |
;return from ISR | |
reti | |
;EXTERNAL INT0 ISR | |
INT0_ISR: | |
;Get averare power per channel, per minute | |
;Multiply by 0,0002 ===> Result at sumH:sumL with 4 decimal digits, ( Average power per channel = (SUM * 60 )/(15 * 2500 * 8) = SUM * 0,0002 | |
;LOW Byte * 2 | |
lsl sumL ; bit 9 => C | |
;HIGH Byte * 2 ( get C from sumL ) | |
rol sumH | |
;Compare with upper_bound value IF average power is larger than upper_bound then set alarm | |
cpi sumH, HIGH( upper_bound ) | |
brlo no_alarm | |
cpi sumL, LOW( upper_bound ) | |
brlo no_alarm ; Skip if less than | |
breq no_alarm ; Skip if equal | |
;ALARM | |
;SETUP COUNTER_3 WITH 5 SEC TOOGLE | |
;SET OCR3A value | |
ldi temp, HIGH( TIMER3_ORC ) | |
sts OCR3AH, temp;out OCR3AH, temp | |
ldi temp, LOW( TIMER3_ORC ) | |
sts OCR3AL, temp;out OCR3AL, temp | |
;SET mode CTC AND prescaler AND Compare output Mode ( COM ) | |
ldi temp, 0b10000000; COM3A=> 10 WG 10 =>00 | |
sts TCCR3A, temp;out TCCR3A, temp | |
ldi temp, 0b0000101; WG 32 => 10, CS => 101 ( prescaler : 1024 ) | |
sts TCCR3B, temp;out TCCR3B, temp | |
;Clear PORTB ( open all LEDs ) | |
clr temp; | |
out PORTB, temp | |
rjmp done; | |
no_alarm: ;If no alarm is set | |
; DISABLE COUNTER 3 | |
clr temp | |
sts TCCR3B, temp;out TCCR3B, temp | |
;Negative logic | |
mov temp, sumH | |
com temp | |
;Output MSB to PORTB | |
out PORTB, temp | |
done: | |
reti | |
COUNTER3_COMPA_ISR: ;(alarm) | |
;Read current PORTB status | |
in temp, PORTB | |
;SET temp2 = 0xFF | |
ser temp2 | |
;XOR ( TOOGLE : 00 XOR 11 => 11, 11 XOR 11 => 00 ) | |
eor temp,temp2 | |
out PORTB, temp | |
reti; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Thema 3 02/2013 | |
* Input A,B,C,D => PA0, PA1, PA2, PA3; Positive logic | |
* Input External INT0 => PD2 ; Sense : Falling edge | |
* Output O1, O2, O3 => PB0, PB1, PB2 ; Positive logic | |
*/ | |
.include "m16def.inc" | |
.def temp = r16 | |
.def input = r17 | |
.def output = r18 | |
.org 0x00 | |
jmp RESET | |
.org 0x02 | |
jmp INT0_ISR | |
;Reset ISR | |
RESET: | |
;SETUP STACK POINTER | |
ldi temp, HIGH( RAMEND ) | |
out SPH, temp | |
ldi temp, LOW( RAMEND ) | |
out SPL, temp | |
;SET PA 0-3 AS INPUT | |
;SET PD 2 AS INPUT ( EXTERNAL INT0 ) | |
;SET PB 0-2 AS OUTPUT | |
ldi temp, 0b00000111 | |
out DDRB, temp | |
;SET INT0 INTERRUPT SENSE TO FALLING EDGE | |
ldi temp, 0b00000010 | |
out MCUCR, temp | |
;ENABLE INT0 | |
ldi temp, 0b01000000 | |
out GICR, temp | |
;ENABLE GLOBAL INTERRUPTS | |
sei | |
;INFINITE LOOP | |
loop: | |
jmp loop | |
;EXTERNAL INT0 ISR | |
INT0_ISR: | |
;set temporary output | |
clr output | |
;read input | |
in input, PINA | |
;Keep lower nibble | |
andi input, 0x0F | |
;Check if O1 is set ( ABCD ) | |
cpi input, 0x0F | |
; If ABCD != 1111 skip O1 | |
brne O1_not_set | |
;SET O1 | |
ori output, 0b00000001 | |
O1_not_set: | |
;Get AB and CD | |
;Copy input to temp | |
mov temp, input | |
;Shift left temp register | |
lsl temp | |
/*Contents in registers : | |
;input : 0000DCBA | |
;temp : 000DCBA0 | |
*/ | |
and temp, input | |
;apply mask to keep bits 1 and 3 ( bit 1 = AB, bit 3 = CD ) | |
andi temp, 0b00001010 | |
;Check if AB*2 + CD*8 == 0 | |
tst temp | |
breq done; IF AB*2 + CD*8 == 0 ( Both O2, O3 are 0 ) | |
;AB*2 + CD*8 > 0 then AB is set OR CD is set ===> (O2) AB OR BC is set | |
;SET O2 | |
ori output, 0b00000010 | |
;Check if AB*2 + CD*8 >= 10 | |
cpi temp, 10 | |
brsh done;IF AB*2 + CD*8 >= 10 then both AB, CD are set ==> (O3) AB XOR BC is clear | |
;AB*2 + CD*8 < 10 then AB is set XOR CD is set ==> (O3) AB XOR BC is set | |
;SET O3 | |
ori output, 0b00000100 | |
done: | |
out PORTB, output | |
;return from ISR | |
reti |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment