AVR, uppför sig inte riktigt...

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
rickeboy
Inlägg: 678
Blev medlem: 13 augusti 2003, 09:12:17
Ort: Göteborg / Karlskrona
Kontakt:

AVR, uppför sig inte riktigt...

Inlägg av rickeboy »

Hoj... sitter och känner att jag börjar få koll på det här med C för avr... kul och givande...

Nedan skrivna program funkar, dvs när jag trycker på ngn av INT0 eller INT1 så ändras diodrarna som lyser dock inte alltid korrekt. Har 8:a st lysdiodrar där fyra lyser från början, efter man tryckt ska dem släckas och dem andra börja lysa MEN visa gånger så gör dem inte det, dvs dem ändras inte eller snarare dem andra börjar lysa men sen slocknar dem lika fort och dem första fyra som redan lyste när jag tryckte på knappen lyser hela tiden... fortsätter jag trycka kan det vara så här 2 tryckningar till innan den skiftar, sen skiftar den på direkten mellan dem och sen uppkommer det igen... se filmen för bättre förståelse...
frågan är då varför detta uppkommer? Är det för att det är kass avstudsning på knappen? eller vad är det som gör att det uppkommer? Använder en AT90S8515 på 4Mhz

Film: Hur det ser ut...

Jag la in denna för att försöka avstudsa i mjukvaran men det verkar inte spela ngn roll _delay_loop_2(5000);

Kod: Markera allt

#include <avr/io.h>
#include <avr/delay.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

unsigned char led;

SIGNAL(SIG_INTERRUPT0) {

led = PORTB;
PORTB = ~led;

_delay_loop_2(5000);

}

SIGNAL(SIG_INTERRUPT1) {

led = PORTB;
PORTB = ~led;

_delay_loop_2(5000);

}

int main(void)
{

DDRB = 0xFF; /* Use PORTB as outputs (leds) */
DDRD = 0x00; /* Use PORTD as inputs (switches) */

PORTB = 0xF; /* Light four of the eight leds... */
PORTD = 0xFF; /*activate the Pull-Ups...*/

GIMSK = _BV(INT0) | _BV(INT1); /* SET INT0 and INT1 to active */

sei(); /* enable interrupts...*/

for (;;) {}

return 0;
}
Ngn som kommer på ngt?

//Rille
matseng
Inlägg: 2360
Blev medlem: 16 september 2003, 17:18:13
Ort: Dubai, United Arab Emirates
Kontakt:

Inlägg av matseng »

Bra fråga....

Du gör ju iallfall rätt med att använda SIGNAL() istället för INTERRUPT(). Signal() stänger av vidare interrupt medans handlern kör. Interrupt() låter nya interrupt avbryta handlern - vilket kan vara bra i vissa fall, men definitivt inte när det riskerar att komma in skurar med interrupts.

Att lägga in en delay i en interrupthanterare är definitivt klart olämpligt, en interrupthanterare ska göra sitt jobb så snabbt som det bara är möjligt för att sedan låta huvudprocessen jobba vidare.

Felet ligger nog i att om det kommer in ytterligare en extern interruptpuls (och INT0 är satt till att vara edge-triggered) när den behandlar ett interrupt så läggs det interruptet på kö och kommer att utföras när den första interrupthanteraren är klar med sitt jobb.

Läs på sidan 26 i databladet. http://www.atmel.com/dyn/resources/prod ... oc0841.pdf

EDIT: R*vans massa fingerslintningar fixade
Senast redigerad av matseng 14 september 2004, 14:12:19, redigerad totalt 1 gång.
Användarvisningsbild
rickeboy
Inlägg: 678
Blev medlem: 13 augusti 2003, 09:12:17
Ort: Göteborg / Karlskrona
Kontakt:

Inlägg av rickeboy »

Hmm... tack försvaret... hmm... läser i databladet om att och löste att! AVR är underbart ;)

Löste att så här:

Kod: Markera allt

MCUCR |= _BV(ISC01) | _BV(ISC11); //falling edge will make an interupt

GIMSK |= _BV(INT0) | _BV(INT1); /* SET INT0 and INT1 to active */
Som ni ser ändrade jag GIMSK = bla bla till GIMSK |= på det sättet försöker den inte sätta de reserverade bitarna till 0...

Kul med lite intressant problem lösning :)
Tack återigen matseng... UART here we come!
Jag och uC är igång igen... efter mitt uppehåll efter allt krabb med PIC ;)

EDIT: Tog ju då även bort delayen...

//Rille
Skriv svar