w bascomie zapis wyglada tak :
Enable Interrupts
Config Timer0 = Timer , Prescale = 1024
On Ovf0 Tim0_isr
Tim0_isr:
Disable Timer0
Temp = 0
While _rs_head_ptr0 <> _rs_tail_ptr0
Name = Inkey()
If Name > 13 Then
Ciag = Ciag + Chr(name)
Temp = Temp + 1
End If
Wend
Enable Timer0
Return
i tu prosze o podpowiedz.
W bascomie dziala bezproblemowo
to co nadane jest z komputera ma zapisac w zmiennej ciag
probuje to samo zrobic w asm ale mi nie wychodzi
czy ma ktos jakis przyklad jak to zrobic w asm ?
pszeszukalem internet i nie znalazlem.
Aktyw Forum
Zarejestruj się na forum.ep.com.pl i zgłoś swój akces do Aktywu Forum. Jeśli jesteś już zarejestrowany wystarczy, że się zalogujesz.
Sprawdź punkty Zarejestruj sięPrzerwania w avr ??
Moderatorzy:Jacek Bogusz, procesorowiec, r-mik, Moderatorzy
Przysylam Ci cos podobnego w assemblerze (tzn napisane w c) ale przesylam ci po kompilacji kod wynikowy w asm moze ci pomoze.. W dzisiejszych czasach juz raczej srednio sie oplaca pisac w asm chyba ze co najwyzej krytyczne czasowo procedury.. Dziala to mniej wiecej tak ze funkcja odbiera ciag znakow z portu szeregowego i gdy przez zadany czas nie przychodzi nowy znak ustawia zmienna koniec odbioru. Mam nadzieje ze sie przyda
testserial.elf: file format elf32-avr
Disassembly of section .text:
00000000 <__vectors>:
0: 0c 94 2a 00 jmp 0x54
4: 0c 94 45 00 jmp 0x8a
8: 0c 94 45 00 jmp 0x8a
c: 0c 94 45 00 jmp 0x8a
10: 0c 94 45 00 jmp 0x8a
14: 0c 94 45 00 jmp 0x8a
18: 0c 94 45 00 jmp 0x8a
1c: 0c 94 45 00 jmp 0x8a
20: 0c 94 45 00 jmp 0x8a
24: 0c 94 45 00 jmp 0x8a
28: 0c 94 45 00 jmp 0x8a
2c: 0c 94 5a 00 jmp 0xb4
30: 0c 94 45 00 jmp 0x8a
34: 0c 94 7e 00 jmp 0xfc
38: 0c 94 45 00 jmp 0x8a
3c: 0c 94 45 00 jmp 0x8a
40: 0c 94 45 00 jmp 0x8a
44: 0c 94 45 00 jmp 0x8a
48: 0c 94 45 00 jmp 0x8a
4c: 0c 94 45 00 jmp 0x8a
50: 0c 94 45 00 jmp 0x8a
00000054 <__ctors_end>:
54: 11 24 eor r1, r1
56: 1f be out 0x3f, r1 ; 63
58: cf e5 ldi r28, 0x5F ; 95
5a: d8 e0 ldi r29, 0x08 ; 8
5c: de bf out 0x3e, r29 ; 62
5e: cd bf out 0x3d, r28 ; 61
00000060 <__do_copy_data>:
60: 10 e0 ldi r17, 0x00 ; 0
62: a0 e6 ldi r26, 0x60 ; 96
64: b0 e0 ldi r27, 0x00 ; 0
66: e2 e5 ldi r30, 0x52 ; 82
68: f1 e0 ldi r31, 0x01 ; 1
6a: 02 c0 rjmp .+4 ; 0x70
0000006c <.do_copy_data_loop>:
6c: 05 90 lpm r0, Z+
6e: 0d 92 st X+, r0
00000070 <.do_copy_data_start>:
70: a0 36 cpi r26, 0x60 ; 96
72: b1 07 cpc r27, r17
74: d9 f7 brne .-10 ; 0x6c
00000076 <__do_clear_bss>:
76: 11 e0 ldi r17, 0x01 ; 1
78: a0 e6 ldi r26, 0x60 ; 96
7a: b0 e0 ldi r27, 0x00 ; 0
7c: 01 c0 rjmp .+2 ; 0x80
0000007e <.do_clear_bss_loop>:
7e: 1d 92 st X+, r1
00000080 <.do_clear_bss_start>:
80: ab 32 cpi r26, 0x2B ; 43
82: b1 07 cpc r27, r17
84: e1 f7 brne .-8 ; 0x7e
86: 0c 94 a2 00 jmp 0x144
0000008a <__bad_interrupt>:
8a: 0c 94 00 00 jmp 0x0
0000008e <InitUart>:
void InitUart(void)
{
/* Konfiguracja Timera 0 */
TCNT0 = LOADT0;
8e: 8d e3 ldi r24, 0x3D ; 61
90: 82 bf out 0x32, r24 ; 50
//Wlacz przerwanie overflow Timera 0
TIMSK |= _BV(TOIE0);
92: 89 b7 in r24, 0x39 ; 57
94: 81 60 ori r24, 0x01 ; 1
96: 89 bf out 0x39, r24 ; 57
//Timer 0 - autoreload preskaler f/1024
TCCR0 = _BV(CS02) | _BV(CS00);
98: 85 e0 ldi r24, 0x05 ; 5
9a: 83 bf out 0x33, r24 ; 51
/*Konfiguracja portu szeregowego 9600,n,8,1*/
//Predkosc dla podzielnika
UBRRH = 0x00;
9c: 10 bc out 0x20, r1 ; 32
UBRRL = 0x26;
9e: 86 e2 ldi r24, 0x26 ; 38
a0: 89 b9 out 0x09, r24 ; 9
//Zeruj znacziki
UCSRA = 0;
a2: 1b b8 out 0x0b, r1 ; 11
// Wlaczenie odbiornika nadajnika oraz przerwan odebrania i nadania
UCSRB = _BV(RXEN) | _BV(TXEN) | _BV(RXCIE);
a4: 88 e9 ldi r24, 0x98 ; 152
a6: 8a b9 out 0x0a, r24 ; 10
UCSRC = _BV(URSEL) | _BV(UCSZ0) | _BV(UCSZ1);
a8: 86 e8 ldi r24, 0x86 ; 134
aa: 80 bd out 0x20, r24 ; 32
//Odblokuj przerwania w jednostce centralnej
sei();
ac: 78 94 sei
//Ustawienie warunkow poczatkowych
RxRdy = 0;
ae: 10 92 2a 01 sts 0x012A, r1
}
b2: 08 95 ret
000000b4 <__vector_11>:
//Przerwanie od Timera0 funkcja porownania
SIGNAL(SIG_OVERFLOW0)
{
b4: 1f 92 push r1
b6: 0f 92 push r0
b8: 0f b6 in r0, 0x3f ; 63
ba: 0f 92 push r0
bc: 11 24 eor r1, r1
be: 8f 93 push r24
TCNT0 += LOADT0;
c0: 82 b7 in r24, 0x32 ; 50
c2: 83 5c subi r24, 0xC3 ; 195
c4: 82 bf out 0x32, r24 ; 50
if(TimRx) --TimRx;
c6: 80 91 60 00 lds r24, 0x0060
ca: 88 23 and r24, r24
cc: 31 f0 breq .+12 ; 0xda
ce: 80 91 60 00 lds r24, 0x0060
d2: 81 50 subi r24, 0x01 ; 1
d4: 80 93 60 00 sts 0x0060, r24
d8: 0b c0 rjmp .+22 ; 0xf0
else
{
if(RxCnt && !RxRdy)
da: 80 91 61 00 lds r24, 0x0061
de: 88 23 and r24, r24
e0: 39 f0 breq .+14 ; 0xf0
e2: 80 91 2a 01 lds r24, 0x012A
e6: 88 23 and r24, r24
e8: 19 f4 brne .+6 ; 0xf0
{
//Znacznik odebrania ramki
RxRdy = 1;
ea: 81 e0 ldi r24, 0x01 ; 1
ec: 80 93 2a 01 sts 0x012A, r24
}
}
}
f0: 8f 91 pop r24
f2: 0f 90 pop r0
f4: 0f be out 0x3f, r0 ; 63
f6: 0f 90 pop r0
f8: 1f 90 pop r1
fa: 18 95 reti
000000fc <__vector_13>:
//Przerwanie od portu szeregowego odbior znaku
SIGNAL(SIG_UART_RECV)
{
fc: 1f 92 push r1
fe: 0f 92 push r0
100: 0f b6 in r0, 0x3f ; 63
102: 0f 92 push r0
104: 11 24 eor r1, r1
106: 8f 93 push r24
108: 9f 93 push r25
10a: ef 93 push r30
10c: ff 93 push r31
if(RxCnt != UART_BUFSIZE)
10e: 80 91 61 00 lds r24, 0x0061
112: 88 3c cpi r24, 0xC8 ; 200
114: 59 f0 breq .+22 ; 0x12c
RxBuf[RxCnt++] = UDR;
116: 80 91 61 00 lds r24, 0x0061
11a: e8 2f mov r30, r24
11c: ff 27 eor r31, r31
11e: ee 59 subi r30, 0x9E ; 158
120: ff 4f sbci r31, 0xFF ; 255
122: 9c b1 in r25, 0x0c ; 12
124: 90 83 st Z, r25
126: 8f 5f subi r24, 0xFF ; 255
128: 80 93 61 00 sts 0x0061, r24
TimRx = 3;
12c: 83 e0 ldi r24, 0x03 ; 3
12e: 80 93 60 00 sts 0x0060, r24
}
132: ff 91 pop r31
134: ef 91 pop r30
136: 9f 91 pop r25
138: 8f 91 pop r24
13a: 0f 90 pop r0
13c: 0f be out 0x3f, r0 ; 63
13e: 0f 90 pop r0
140: 1f 90 pop r1
142: 18 95 reti
00000144 <main>:
//Funkcja glowna
int main(void)
{
144: cf e5 ldi r28, 0x5F ; 95
146: d8 e0 ldi r29, 0x08 ; 8
148: de bf out 0x3e, r29 ; 62
14a: cd bf out 0x3d, r28 ; 61
InitUart();
14c: 0e 94 47 00 call 0x8e
while(1);
150: ff cf rjmp .-2 ; 0x150
testserial.elf: file format elf32-avr
Disassembly of section .text:
00000000 <__vectors>:
0: 0c 94 2a 00 jmp 0x54
4: 0c 94 45 00 jmp 0x8a
8: 0c 94 45 00 jmp 0x8a
c: 0c 94 45 00 jmp 0x8a
10: 0c 94 45 00 jmp 0x8a
14: 0c 94 45 00 jmp 0x8a
18: 0c 94 45 00 jmp 0x8a
1c: 0c 94 45 00 jmp 0x8a
20: 0c 94 45 00 jmp 0x8a
24: 0c 94 45 00 jmp 0x8a
28: 0c 94 45 00 jmp 0x8a
2c: 0c 94 5a 00 jmp 0xb4
30: 0c 94 45 00 jmp 0x8a
34: 0c 94 7e 00 jmp 0xfc
38: 0c 94 45 00 jmp 0x8a
3c: 0c 94 45 00 jmp 0x8a
40: 0c 94 45 00 jmp 0x8a
44: 0c 94 45 00 jmp 0x8a
48: 0c 94 45 00 jmp 0x8a
4c: 0c 94 45 00 jmp 0x8a
50: 0c 94 45 00 jmp 0x8a
00000054 <__ctors_end>:
54: 11 24 eor r1, r1
56: 1f be out 0x3f, r1 ; 63
58: cf e5 ldi r28, 0x5F ; 95
5a: d8 e0 ldi r29, 0x08 ; 8
5c: de bf out 0x3e, r29 ; 62
5e: cd bf out 0x3d, r28 ; 61
00000060 <__do_copy_data>:
60: 10 e0 ldi r17, 0x00 ; 0
62: a0 e6 ldi r26, 0x60 ; 96
64: b0 e0 ldi r27, 0x00 ; 0
66: e2 e5 ldi r30, 0x52 ; 82
68: f1 e0 ldi r31, 0x01 ; 1
6a: 02 c0 rjmp .+4 ; 0x70
0000006c <.do_copy_data_loop>:
6c: 05 90 lpm r0, Z+
6e: 0d 92 st X+, r0
00000070 <.do_copy_data_start>:
70: a0 36 cpi r26, 0x60 ; 96
72: b1 07 cpc r27, r17
74: d9 f7 brne .-10 ; 0x6c
00000076 <__do_clear_bss>:
76: 11 e0 ldi r17, 0x01 ; 1
78: a0 e6 ldi r26, 0x60 ; 96
7a: b0 e0 ldi r27, 0x00 ; 0
7c: 01 c0 rjmp .+2 ; 0x80
0000007e <.do_clear_bss_loop>:
7e: 1d 92 st X+, r1
00000080 <.do_clear_bss_start>:
80: ab 32 cpi r26, 0x2B ; 43
82: b1 07 cpc r27, r17
84: e1 f7 brne .-8 ; 0x7e
86: 0c 94 a2 00 jmp 0x144
0000008a <__bad_interrupt>:
8a: 0c 94 00 00 jmp 0x0
0000008e <InitUart>:
void InitUart(void)
{
/* Konfiguracja Timera 0 */
TCNT0 = LOADT0;
8e: 8d e3 ldi r24, 0x3D ; 61
90: 82 bf out 0x32, r24 ; 50
//Wlacz przerwanie overflow Timera 0
TIMSK |= _BV(TOIE0);
92: 89 b7 in r24, 0x39 ; 57
94: 81 60 ori r24, 0x01 ; 1
96: 89 bf out 0x39, r24 ; 57
//Timer 0 - autoreload preskaler f/1024
TCCR0 = _BV(CS02) | _BV(CS00);
98: 85 e0 ldi r24, 0x05 ; 5
9a: 83 bf out 0x33, r24 ; 51
/*Konfiguracja portu szeregowego 9600,n,8,1*/
//Predkosc dla podzielnika
UBRRH = 0x00;
9c: 10 bc out 0x20, r1 ; 32
UBRRL = 0x26;
9e: 86 e2 ldi r24, 0x26 ; 38
a0: 89 b9 out 0x09, r24 ; 9
//Zeruj znacziki
UCSRA = 0;
a2: 1b b8 out 0x0b, r1 ; 11
// Wlaczenie odbiornika nadajnika oraz przerwan odebrania i nadania
UCSRB = _BV(RXEN) | _BV(TXEN) | _BV(RXCIE);
a4: 88 e9 ldi r24, 0x98 ; 152
a6: 8a b9 out 0x0a, r24 ; 10
UCSRC = _BV(URSEL) | _BV(UCSZ0) | _BV(UCSZ1);
a8: 86 e8 ldi r24, 0x86 ; 134
aa: 80 bd out 0x20, r24 ; 32
//Odblokuj przerwania w jednostce centralnej
sei();
ac: 78 94 sei
//Ustawienie warunkow poczatkowych
RxRdy = 0;
ae: 10 92 2a 01 sts 0x012A, r1
}
b2: 08 95 ret
000000b4 <__vector_11>:
//Przerwanie od Timera0 funkcja porownania
SIGNAL(SIG_OVERFLOW0)
{
b4: 1f 92 push r1
b6: 0f 92 push r0
b8: 0f b6 in r0, 0x3f ; 63
ba: 0f 92 push r0
bc: 11 24 eor r1, r1
be: 8f 93 push r24
TCNT0 += LOADT0;
c0: 82 b7 in r24, 0x32 ; 50
c2: 83 5c subi r24, 0xC3 ; 195
c4: 82 bf out 0x32, r24 ; 50
if(TimRx) --TimRx;
c6: 80 91 60 00 lds r24, 0x0060
ca: 88 23 and r24, r24
cc: 31 f0 breq .+12 ; 0xda
ce: 80 91 60 00 lds r24, 0x0060
d2: 81 50 subi r24, 0x01 ; 1
d4: 80 93 60 00 sts 0x0060, r24
d8: 0b c0 rjmp .+22 ; 0xf0
else
{
if(RxCnt && !RxRdy)
da: 80 91 61 00 lds r24, 0x0061
de: 88 23 and r24, r24
e0: 39 f0 breq .+14 ; 0xf0
e2: 80 91 2a 01 lds r24, 0x012A
e6: 88 23 and r24, r24
e8: 19 f4 brne .+6 ; 0xf0
{
//Znacznik odebrania ramki
RxRdy = 1;
ea: 81 e0 ldi r24, 0x01 ; 1
ec: 80 93 2a 01 sts 0x012A, r24
}
}
}
f0: 8f 91 pop r24
f2: 0f 90 pop r0
f4: 0f be out 0x3f, r0 ; 63
f6: 0f 90 pop r0
f8: 1f 90 pop r1
fa: 18 95 reti
000000fc <__vector_13>:
//Przerwanie od portu szeregowego odbior znaku
SIGNAL(SIG_UART_RECV)
{
fc: 1f 92 push r1
fe: 0f 92 push r0
100: 0f b6 in r0, 0x3f ; 63
102: 0f 92 push r0
104: 11 24 eor r1, r1
106: 8f 93 push r24
108: 9f 93 push r25
10a: ef 93 push r30
10c: ff 93 push r31
if(RxCnt != UART_BUFSIZE)
10e: 80 91 61 00 lds r24, 0x0061
112: 88 3c cpi r24, 0xC8 ; 200
114: 59 f0 breq .+22 ; 0x12c
RxBuf[RxCnt++] = UDR;
116: 80 91 61 00 lds r24, 0x0061
11a: e8 2f mov r30, r24
11c: ff 27 eor r31, r31
11e: ee 59 subi r30, 0x9E ; 158
120: ff 4f sbci r31, 0xFF ; 255
122: 9c b1 in r25, 0x0c ; 12
124: 90 83 st Z, r25
126: 8f 5f subi r24, 0xFF ; 255
128: 80 93 61 00 sts 0x0061, r24
TimRx = 3;
12c: 83 e0 ldi r24, 0x03 ; 3
12e: 80 93 60 00 sts 0x0060, r24
}
132: ff 91 pop r31
134: ef 91 pop r30
136: 9f 91 pop r25
138: 8f 91 pop r24
13a: 0f 90 pop r0
13c: 0f be out 0x3f, r0 ; 63
13e: 0f 90 pop r0
140: 1f 90 pop r1
142: 18 95 reti
00000144 <main>:
//Funkcja glowna
int main(void)
{
144: cf e5 ldi r28, 0x5F ; 95
146: d8 e0 ldi r29, 0x08 ; 8
148: de bf out 0x3e, r29 ; 62
14a: cd bf out 0x3d, r28 ; 61
InitUart();
14c: 0e 94 47 00 call 0x8e
while(1);
150: ff cf rjmp .-2 ; 0x150
Po pierwsze, w programie musisz określić jaka procedura będzie odpowiedzialna na obsługę każdego z przerwań. Robi się to w ten sposób, że w pamięci flash na początku umieszcza się tzw tabelę vektorów przerwań (reset też można traktować jako takie przerwanie). W kolejnych słowach (po dwa bajty) umieszcza się początki procedur przerwań+resetu. Każdy początek zaczyna się od ściśle określonego adresu w pamięci programu. Dla procesora AVR 2313 może wyglądać to następująco:
.org 0
rjmp ResetProcessor ;
.org INT0addr ;External Interrupt0 Vector Address
rjmp INT0Interrupt ;
.org INT1addr ;External Interrupt1 Vector Address
rjmp INT1Interrupt ;
.org ICP1addr ;Input Capture1 Interr. Vector Address
rjmp TC1CaptInterrupt ;
.org OC1addr ;Output Compare1A Inter. Vect. Adr.
rjmp TC1CompInterrupt ;
.org OVF1addr ;Overflow1 Interrupt Vector Address
rjmp TC1OvfInterrupt ;
.org OVF0addr ;Overflow0 Interrupt Vector Address
rjmp TC0OvfInterrupt ;
.org URXCaddr ;UART Recv Compl Inter. Vect. Address
rjmp UARTRXCInterrupt ;
.org UDREaddr ;UART Data Reg. Empty Interr. Vect Address
rjmp UARTEmptInterrupt ;
.org UTXCaddr ;UART Transmit Complete Interrupt Vector Address
rjmp UARTTXDInterrupt ;
.org ACIaddr ;Analog Comparator Interr. Vector Adr
rjmp AnalogCompInterrupt ;
Wszystkie stałe występujące w dyrektywie .org pochodzą o odpowiedniego zbioru (tu konkretnie z 2313def.inc). Jeżeli zaistnieje przerwanie przykładowo od UART odbiornika, to procek rozpocznie odbługę od adresu, który jest określony przez wartość stałej URXCaddr, czyli wykona instrukcję spod tego adresu w pamięci flash (tu będzie to instrukcja rjmp UARTRXCInterrupt). Musisz sobie napisać procedurkę obsługi. W archiwum Wojtka jest przykład obsługi przerwania od zegara/licznika (na http://www.elektronika.qs.pl/arch.html zbiór t0interrupt.asm).
Podaj swój adres to coś ci podeślę. Ja mam adres: an177@poczta.fm.
.org 0
rjmp ResetProcessor ;
.org INT0addr ;External Interrupt0 Vector Address
rjmp INT0Interrupt ;
.org INT1addr ;External Interrupt1 Vector Address
rjmp INT1Interrupt ;
.org ICP1addr ;Input Capture1 Interr. Vector Address
rjmp TC1CaptInterrupt ;
.org OC1addr ;Output Compare1A Inter. Vect. Adr.
rjmp TC1CompInterrupt ;
.org OVF1addr ;Overflow1 Interrupt Vector Address
rjmp TC1OvfInterrupt ;
.org OVF0addr ;Overflow0 Interrupt Vector Address
rjmp TC0OvfInterrupt ;
.org URXCaddr ;UART Recv Compl Inter. Vect. Address
rjmp UARTRXCInterrupt ;
.org UDREaddr ;UART Data Reg. Empty Interr. Vect Address
rjmp UARTEmptInterrupt ;
.org UTXCaddr ;UART Transmit Complete Interrupt Vector Address
rjmp UARTTXDInterrupt ;
.org ACIaddr ;Analog Comparator Interr. Vector Adr
rjmp AnalogCompInterrupt ;
Wszystkie stałe występujące w dyrektywie .org pochodzą o odpowiedniego zbioru (tu konkretnie z 2313def.inc). Jeżeli zaistnieje przerwanie przykładowo od UART odbiornika, to procek rozpocznie odbługę od adresu, który jest określony przez wartość stałej URXCaddr, czyli wykona instrukcję spod tego adresu w pamięci flash (tu będzie to instrukcja rjmp UARTRXCInterrupt). Musisz sobie napisać procedurkę obsługi. W archiwum Wojtka jest przykład obsługi przerwania od zegara/licznika (na http://www.elektronika.qs.pl/arch.html zbiór t0interrupt.asm).
Podaj swój adres to coś ci podeślę. Ja mam adres: an177@poczta.fm.
Kto jest online
Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 2 gości