Sida 1 av 3
Snabb hjälp med AVR önskas!
Postat: 14 september 2006, 15:14:36
av Johan.o
Hej, har problem med AVR, i mikrodator-kurs.
Inte ens läraren kan hjälpa mig med detta (!)
iaf så vill inte datorn inte komma ur mina subrutiner.
Detta är alltså ett enkelt blinka lysdioder på portB (alla utgångar har LED )
klockas med intern 1Mhz, använder STK500, och AVRstudio.
programmet funkar fram tills jag ska in i första subrutinen..
sedan händer det inget mer.. Lite fundersam om jag lagt in subrutinerna på rätt ställe?
Tacksam för hjälp..
Kod: Markera allt
.include "m16def.inc"
.def count = r18
.def temp = r17
.org 0
jmp main ; Gå till huvudprogrammet
wait_1ms:
ldi count,0xc8 ; 200dec
loop_1ms:
dec count
cpi count,0
brne loop_1ms
ret
wait_1s:
ldi count,0xc8 ; 200 dec
loop_1s:
rcall wait_1ms
dec count
cpi count,0
brne loop_1s
ret
main:
ldi temp, HIGH(RAMEND) ; Beräkna övre del av SP
out SPH, temp ; och lagra i SPH
ldi temp, low(RAMEND) ; därefter lägre del av SP
out SPL, temp ; och lagra i SPL
ldi temp, 0xff
out DDRB, temp ; Sätter PortB = alla utgångar
ldi r28, 0
out DDRA, r28 ; Sätter PortA = Alla ingångar
ldi temp, 0x00
out PORTB, r28 ; Nollställ
loop:
ldi temp, 0x0f
out PORTB, temp
rcall wait_1s
ldi temp, 0xff
out PORTB, temp
rcall wait_1s
jmp loop
Postat: 14 september 2006, 15:18:07
av sodjan
Kolla hur du använder "count".
Det är inte speciellt konstigt att det inte fungerar...
Postat: 14 september 2006, 15:29:14
av Johan.o
Tack sodjan
Ibland blir bara allt fel

Postat: 14 september 2006, 15:33:05
av sodjan
OK. Då såg alltså vad det var, eller hur ?
Det som var mest förvånande i ditt inlägg var :
> "Inte ens läraren kan hjälpa mig med detta (!)"...
Postat: 14 september 2006, 15:36:13
av Johan.o
Nä, han visste inte hur man fick igång så subrutiner funkade..
Utan var mest van vid att använda en c-kompilator där allt sånt sköts i ett "färdigt skal"
Eftersom jag fortfarande trodde att det var stacken subrutin-anropen som var fel så...
Nåväl jag bytte count -> count2 i ena subrutinen..
Postat: 14 september 2006, 15:41:40
av sodjan
Vilka sopa... (läreren) !!
Hur f-n kan han leda en AVR kurs !!??
Jag har aldrig skrivit en rad kod till AVR, men det tog 10 sek att se felet...
För övrigt är din åtgärd helt rätt.
En C-komp hade antagligen hanterat "count" com "local" (beroende på hur man skriver koden)...
D.v.s att det hade blivit två olika instanser av "count".
EDIT:
Har eran utvecklingsmiljö ingen simulator ?
Typ MPSIM i MPLAB (för PIC) ?
Postat: 14 september 2006, 15:56:50
av björn
Får verkligen hålla med Sodjan angående en lärare som inte hittar det felet (för det var väl inte som han tyckte att du skulle hitta det själv?).
AVRStudio har simulering.
Postat: 14 september 2006, 17:05:20
av Johan.o
Först så bad jag om hjälp, då jag inte fick min subrutin att funka
(wait_1s) som även innuti anropar wait_1ms. Gick igenom den men vi hittade inte felet.
Då hade jag inte förstått att man var tvungen att använda rcall och
initiera stacken, villket inte han heller viste.
Så att det största felet då, var att felaktiga 'call' användes samt att
vid 'ret' så hämtades felaktig återvänds-adress från stacken.
Sedan så löste jag det på egen hand, men antog att det fortfarande
var problem med att gå in/ur subrutiner..
Men jo, jag tycker också han verkar ha lite dålig koll på AVR..
Det ska ju inte vara okänt hur man använder sig av subrutiner för honom.
Sedan får jag nog påstå att det var lite sopigt av mig själv att göra ett sådant fel.
Jag har ändå programmerat (PIC) assembler i många år, och bör inte gå bet på något sådant enkelt.
Postat: 14 september 2006, 19:15:30
av exile
Lite sopit av läraren....
jag ser att du använder cpi x,0 efter dec vilket är helt onödigt efter som dec ändra Z-flagan när registret blir noll...
Sedan behöver du inte använda rcall utan kan använda call, skilnade mellan rcall och call är att rcall endast kan hoppa +/-2k instruktioner medans call kan hoppa +/-2048k instruktioner där imot tar rcall endast 2byte medans call tar 4byte och längre tid att köras...
Sedan vill jag slå ett slag för använda 16bitar eller mer, som kan göras väldigt enkelt med AVR exemple
Kod: Markera allt
.include "m16def.inc"
.def counth = r19 //
.def countl = r18 //16bitar
.def temp = r16
jmp reset
wait:
.equ conts = 500 //vänte tiden
ldi counth,high(conts)
ldi countl,low(conts) //count = 500;
w_loop: //do{
subi countl,low(1) //
sbci counth,high(1) // count--;
brne w_loop //} while (count)
ret
reset:
ldi temp, HIGH(RAMEND)
out SPH, temp
ldi temp, low(RAMEND)
out SPL, temp
ldi temp, 0xff
out DDRB, temp
loop:
rcall wait
in temp, PORTB
com temp
out PORTB, temp
rjmp loop
^^
Postat: 11 oktober 2006, 14:46:13
av Johan.o
Fortsatta problem i den mikrodatorkurs jag läser, programmerar atmel MEGA 16, nu skrivs koden i C.
Jag har problem med att i en interrupt-rutin så ändrar jag värdet på en variabel "value" som är definerad i början av programmet.
Probelmet är att jag försöker ändra på value i interuupten men det förblir ofärändrat, hur löser jag det?
Läraren har som vanligt ingen aning.
använder några filer som serverats på silverfat för att interrupt ska fungera,
interrupt.h och signal.h , programmerar i winAVR.
såhär ser mitt program ut:
Kod: Markera allt
#include <io_atmega16.h>
#include <stdio.h>
#include <avr/delay.h>
#include <delay_loop.h>
#include <lcd4.h>
#include <signal.h>
#include <interrupt.h>
// --- Globala objekt ---
lcd4 theDisplay;
delay_loop theDelay;
int value=0;
//--- Main ---
int main(void)
{
char s[20];
//--- Intitiering av portar ---
DDRA = 0xFF; // Alla utgångar
DDRB = 0xFF; // Alla utgångar
DDRC = 0xFB; // PD2 ingång, resten utgångar
MCUCR = 0x03; // Positiv flank på INT0 genererar interrupt
GICR = 0x40; // INT0 enable
//--- Initiering av objects ---
lcd4_init(&theDisplay,&PORTC, &DDRC, 4000,50);
delay_loop_init(&theDelay, 5000, DELAY_LOOP_8MHZ );
SREG = 0x80; // Global aktiveing av interrupt
while(1)
{
sprintf(s, "Pulser=%x st", value);
lcd4_cup_row1(&theDisplay);
lcd4_write_string(&theDisplay, s);
delay_loop_delay(&theDelay);
}
SIGNAL(SIG_INTERRUPT0)
{
value++;
}
return 0;
}
edit: Ändrade kod enligt Icecaps förslag
Postat: 11 oktober 2006, 15:09:15
av Icecap
"Value" är definierat i "main" vilket gör att den inte kan ses av interruptrutinen. "Value" är alltså en lokal variabel som ägs (och "ses") enbart av main. Flytt deklarationen till "grunden" alltså strax in under "// --- Globala objekt ---"
Edit: sopig lärare!
Postat: 11 oktober 2006, 15:36:46
av Johan.o
Funkar ändå inte, trots att jag flyttar det, ändrade i bifogad kod så du ser vart jag la den nu..
Japp totalsopig, man får inte lära sig något så jag vet inte riktigt vad jag gör.
Postat: 11 oktober 2006, 15:43:17
av Icecap
Testa att definiera den som:
volatile int value;
Det är inte standart att man assigner ett värde i deklarationen, det är inte alla kompilers som klarar det.
Postat: 11 oktober 2006, 15:44:20
av calmar
Jag vet inte hur interrupt i winAVR fungerar, men det kan vara värt att prova att ändra deklarationen till
.
Postat: 11 oktober 2006, 15:45:24
av Johan.o
Funkar ej heller med volatile int value;
