Interrupt fel, Krets: ATMega32, Språk: C

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Virr3
Inlägg: 840
Blev medlem: 25 juli 2004, 23:05:59
Ort: Göteborg

Inlägg av Virr3 »

Ska man be hehöva göra så speakman?

Jag trode det följde med WinAVR. Det har nämligen funkat förut att bara göra så. alltså bara skriva så direkt.

aja, får testa sen.

Edit: funkar de inte snart så funderar jag på att köpa en extärn RTC alltså. Dock har jag ingen tidigare erfarenhet av de. Men det finns kanske mer info om de och fler som gjort de. Det verkar ju som att ja ä först med att använda den inbyggda RTC:n :/
Kaggen
Inlägg: 432
Blev medlem: 29 januari 2005, 03:06:02

Inlägg av Kaggen »

Virr3:
> Ska man be hehöva göra så speakman?

Jag tror speakmans kortfattade inlägg var ett svar på Icecaps tidigare fråga. Ingenting du skall lägga till i din kod.

Om du mäter på utgångarna, får du några signaler? Om du inte får ut något så vet du ju inte helt säkert om det är koden eller kopplingen som det är fel på.

Du får börja köra uteslutningsmetoden. Strippa ner kod och ta bort interruptrutiner och prova sätta en pinne och mät den för att se om du får ut någe överhuvudtaget.

Om du fortfarande inte får något, prova koppla bort komponenter från en pinne på utgången och sätt den hög resp låg i din kod och se om du får olika nivåer när du mäter på pinnen ifråga.
Virr3
Inlägg: 840
Blev medlem: 25 juli 2004, 23:05:59
Ort: Göteborg

Inlägg av Virr3 »

Kod: Markera allt

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

uint8_t Htio = 0;
uint8_t Hen = 0;
uint8_t Mtio = 0;
uint8_t Men = 0;
uint8_t Stio = 0;
uint8_t Sen = 0;

SIGNAL(SIG_OVERFLOW2)
  { //funkade inte här. Här vart de dött
  PORTA |=  _BV(PA3); 
  PORTA |=  _BV(PA0); 
  _delay_loop_1(10); 
  PORTA &= ~_BV(PA0);
  if(++Sen >= 10) 
    { 
    Sen = 0; 
    if(++Stio >= 6)
      {
      Stio = 0; 
      if(++Men >= 10) 
        { 
        Men = 0; 
        if(++Mtio >= 6) 
          { 
          Mtio = 0;
          if(++Hen >= 10) 
            {
            Hen = 0;
            if(++Htio >= 2) Htio = 0;
            }
          }
        }
      }
    }
  }

int main(void)
{


int temp0;
int temp1;

for(temp0=0; temp0<0x0040; temp0++)
{
   for(temp1=0;temp1<0xFFFF;temp1++);
}
DDRA=0xFF;
TIMSK &=~((1<<TOIE2)|(1<<OCIE2));
ASSR |= (1<<AS2);

TCNT2 = 0x00;
TCCR2 = 0X05;

while (ASSR&0x07);
TIMSK |= (1<<TOIE2);

_SEI();

while(1)
{
   MCUCR = 0xB0;
   _SLEEP(); //hit kom den, sen efter här så vart de sten dött.
   _NOP();
   TCCR2=0x05;
   while (ASSR&0x07);//Tog jag bort Sleep och nop så blev det här de stannade.
}


   uint8_t a;
   uint8_t b;
   uint8_t c;
   uint8_t d;
   uint8_t e;
   uint8_t f;
   
   
   
   while(1)
   {  
      for(a=0;a>9;a++)
      { //Här vart de dött vilket som.
         if(Htio==a)
         {
            PORTA |=  _BV(PA2);
            _delay_loop_1(10);
            PORTA &= ~_BV(PA2);
            
            PORTA |=  _BV(PA1);
            _delay_loop_1(10);
            PORTA &= ~_BV(PA1);
         }
         else
         {
            PORTA |=  _BV(PA2);
            _delay_loop_1(10);
            PORTA &= ~_BV(PA2);
            
            _delay_loop_1(10);
         }
      }
      for(b=0;b>9;b++)
      {
         if(Hen==b)
         {
            PORTA |=  _BV(PA2);
            _delay_loop_1(10);
            PORTA &= ~_BV(PA2);
            
            PORTA |=  _BV(PA1);
            _delay_loop_1(10);
            PORTA &= ~_BV(PA1);
         }
         else
         {
            PORTA |=  _BV(PA2);
            _delay_loop_1(10);
            PORTA &= ~_BV(PA2);
            
            _delay_loop_1(10);
            
         }
      }
      for(c=0;c>9;c++)
      {
         if(Mtio==c)
         {
            PORTA |=  _BV(PA2);
            _delay_loop_1(10);
            PORTA &= ~_BV(PA2);
            
            PORTA |=  _BV(PA1);
            _delay_loop_1(10);
            PORTA &= ~_BV(PA1);
         }
         else
         {
            PORTA |=  _BV(PA2);
            _delay_loop_1(10);
            PORTA &= ~_BV(PA2);
            
            _delay_loop_1(10);
         }
      }
      for(d=0;d>9;d++)
      {
         if(Men==d)
         {
            PORTA |=  _BV(PA2);
            _delay_loop_1(10);
            PORTA &= ~_BV(PA2);
            
            PORTA |=  _BV(PA1);
            _delay_loop_1(10);
            PORTA &= ~_BV(PA1);
         }
         else
         {
            PORTA |=  _BV(PA2);
            _delay_loop_1(10);
            PORTA &= ~_BV(PA2);
            _delay_loop_1(10);
         }
      }
      for(e=0;e>9;e++)
      {
         if(Stio==e)
         {
            PORTA |=  _BV(PA2);
            _delay_loop_1(10);
            PORTA &= ~_BV(PA2);
            
            PORTA |=  _BV(PA1);
            _delay_loop_1(10);
            PORTA &= ~_BV(PA1);
         }
         else
         {
            PORTA |=  _BV(PA2);
            _delay_loop_1(10);
            PORTA &= ~_BV(PA2);
            
            _delay_loop_1(10);   
         }
      }
      for(f=0;f>9;f++)
      {
         if(Sen==f)
         {
            PORTA |=  _BV(PA2);
            _delay_loop_1(10);
            PORTA &= ~_BV(PA2);
            
            PORTA |=  _BV(PA1);
            _delay_loop_1(10);
            PORTA &= ~_BV(PA1);   
         }
         else
         {
            PORTA |=  _BV(PA2);
            _delay_loop_1(10);
            PORTA &= ~_BV(PA2);
            
            _delay_loop_1(10);
            
         }
      }
   }
} 
Jag gjorde så att jag strippa ner kopplingen till ynka fyra lysdioder. En för strobe, en för clock, en för enable och en som jag testade med.

Jag gjorde så att jag satte en port hög och såg hur långt jag kunde komma tills att den inte lös mer.

Skrivit komentarer i koden hur långt det gick.

I signal funkade det inte alls. I main så funkade det ett tag, men det tog ca:en sek innan den började lysa.
matseng
Inlägg: 2360
Blev medlem: 16 september 2003, 17:18:13
Ort: Dubai, United Arab Emirates
Kontakt:

Inlägg av matseng »

Det innebär att du inte lyckats få igång interruptena. _Sleep() sover ju tills ett interupt kommer in och i ditt faöl så vaknar den aldrig upp överhuvud taget efter att den gått in i sleep-mode.

Men hur som helst så har du fel i koden.

Den del som börjar med
uint8_t a;
uint8_t b;
uint8_t c;
uint8_t d;
uint8_t e;
uint8_t f;
kommer aldrig att nås eftersom det INTE finns något sätt att komma ur loopen som är precis ovanför. Du vet väl hur en while()-loop fungerar hoppas jag? Det är farligt att bara kopiera kod utan att ha nån pejl på vad den gör egentligen.
Virr3
Inlägg: 840
Blev medlem: 25 juli 2004, 23:05:59
Ort: Göteborg

Inlägg av Virr3 »

Sant de du säjer, Just nu har jag bara skrivit av det som stog i databladet eller vad man ska kalla det.

Vet hur en While-loop funkar ja. men av någon anledning har jag inte lagt märke till detta:/ men hur som hellst fattar jag inte varför de ligger i en while loop? den loopar ju de i en oändlighet nu väl? Vad ska jag skriva istället för ett där? hur länge ska den loopas? Ska jag vara ärlig så fattar jag inte varför det ska loopas över huvud taget.
Användarvisningsbild
cykze
EF Sponsor
Inlägg: 1539
Blev medlem: 8 april 2004, 10:40:28
Ort: Uppsala

Inlägg av cykze »

En huvudloop har man så gott som alltid på en µC.

Prova att byta ut detta...

Kod: Markera allt

_SEI();

while(1)
{
   MCUCR = 0xB0;
   _SLEEP(); //hit kom den, sen efter här så vart de sten dött.
   _NOP();
   TCCR2=0x05;
   while (ASSR&0x07);//Tog jag bort Sleep och nop så blev det här de stannade.
}
mot detta...

Kod: Markera allt

sei();

while(1)
{

}
I din interruptrutin för SIG_OVERFLOW2 tycker jag att du ska ha dessa två rader i början istället för dom du har nu.

Kod: Markera allt

PORTA ^=  _BV(PA3);
PORTA ^=  _BV(PA0);
Jag antar att PA3 och PA0 är kopplade till lysdioder eller något för att du ska se att interruptrutinen har körts.
Kaggen
Inlägg: 432
Blev medlem: 29 januari 2005, 03:06:02

Inlägg av Kaggen »

Virr3:

Enligt din kod sätter du timer/counter2 för assynkron klocka (AS2 = 1 i ASSR). Om man läser databladet så står det att om du kör i assynkront läge skall du ha extern oscillator på pinne TOSC1 och TOSC2.

Har du det?

Antagligen triggas inte interruptet tack vare att timern aldrig räknar upp.
Virr3
Inlägg: 840
Blev medlem: 25 juli 2004, 23:05:59
Ort: Göteborg

Inlägg av Virr3 »

Kaggen: Jodå, har en klock-kristall mellan TOSC1 och TOSC2.
Det har jag inte missat.

cykze: har bytt ut de du sa, ingen skilnad, funkar fortfarande inte :(
Vad är det för skilnad på PORTA ^= _BV(PA0); och PORTA |= _BV(PA0);?
matseng
Inlägg: 2360
Blev medlem: 16 september 2003, 17:18:13
Ort: Dubai, United Arab Emirates
Kontakt:

Inlägg av matseng »

Cykzes ändring kommer inte att shjälpa en smack tyvärr.

Steg 1 - Fixa så att interruptet fungerar. Kolla med lysdiodssättning i interrupthenteraren som tidigare.

Steg 2 - Ändra loopen såhär:

Kod: Markera allt

uint8_t a;
uint8_t b;
uint8_t c;
uint8_t d;
uint8_t e;
uint8_t f;

_SEI();

while(1)
{
   MCUCR = 0xB0;
   _SLEEP(); //hit kom den, sen efter här så vart de sten dött.
   _NOP();
   TCCR2=0x05;
   while (ASSR&0x07);

    for(a=0;a>9;a++)
    { 
...
... bla bla bla. 
... Fyll på med allt som fanns här tidigare. Har tagit bort det i exemplet för att det inte ska bli så förbaskat mycket kod att visa.
...
   }
}
Användarvisningsbild
cykze
EF Sponsor
Inlägg: 1539
Blev medlem: 8 april 2004, 10:40:28
Ort: Uppsala

Inlägg av cykze »

Virr3 skrev:cykze: har bytt ut de du sa, ingen skilnad, funkar fortfarande inte :(
Vad är det för skilnad på PORTA ^= _BV(PA0); och PORTA |= _BV(PA0);?
Skillnaden är att nivån på utgången kommer växla mellan hög och låg vid varje interrupt. Det blir helt tydligare att ha en lysdiod som växlar läge vid varje interrupt än att ha en lysdiod som tänds första gången och sedan inte ändrar sig vid nästa interrupt.
matseng skrev:Cykzes ändring kommer inte att shjälpa en smack tyvärr.
Jaså inte? Jag tog bort sleep-funktionen i mina ändringar, i fall det skulle vara något med det som krånglar. Om det fortfarande inte skulle fungera så får man se vad man mer man kan utesluta osv.

Har du ingen idé själv?
matseng
Inlägg: 2360
Blev medlem: 16 september 2003, 17:18:13
Ort: Dubai, United Arab Emirates
Kontakt:

Inlägg av matseng »

Cykze: Jo, därför att du loopen som du föreslog var ju den här:

Kod: Markera allt

 sei();

while(1)
{

}
Den gör ju att cpu'n för evigt ligger och spinner i en tom whileloop - förutom då den hoppar upp till isr'en emellanåt. All kod som kommer efter loopen (alla utskiftningarna av datat) kommer aldrig någonsin att exekveras.

Jag kom med ett förslag på hur loopen kunde implementeras på ett möjligen mer korrekt sätt - åtminstone ett sätt som har en möjlighet att göra rätt. Steg två i min åtegärdslista.
Användarvisningsbild
cykze
EF Sponsor
Inlägg: 1539
Blev medlem: 8 april 2004, 10:40:28
Ort: Uppsala

Inlägg av cykze »

Fast det som kommer efter while-loopen är ju inte intressant just nu. Det stora problemet just nu är ju att interruptrutinen inte verkar anropas. Om man då bort sleep:ningen så tar man förhoppningsvis bort en felkälla. Men sen när vi har fått ordning på interrupten kan man ju göra som du föreslår.
Kaggen
Inlägg: 432
Blev medlem: 29 januari 2005, 03:06:02

Inlägg av Kaggen »

Virr3: Kaggen: Jodå, har en klock-kristall mellan TOSC1 och TOSC2.
Det har jag inte missat.

Ok, då tar jag tillbaka det. :)

Frågan är om du vet att kristallen är ok? Jag lyckas inte hitta din ritning nå mer, så jag kan inte se hur du kopplat.

Onekligen verkar du ju inte få något interrupt, koden före _SLEEP() exekverar ju iaf, så processorn verkar funka. Hur vet du förresten hur långt processorn kommer? Har du någon debugger kopplad?

Några saker att kolla...

. Kolla att kristallen öht funkar (om du har oscilloscop vore ju bra).

. Kan du kolla om timern/countern överhuvudtaget räknar upp?

. Har du någon prescaler/postscaler satt?

. Har du rätt frekvens på kristallen (både den du har mellan TOSC1 och TOSC2 och den du klockar processorn med)?

. Om du har intern oscillator för processorn, är den ställd rätt?

. Har du några fuses satta/ej satta som kan inverka på detta?

Mats
Virr3
Inlägg: 840
Blev medlem: 25 juli 2004, 23:05:59
Ort: Göteborg

Inlägg av Virr3 »

"Kolla att kristallen öht funkar (om du har oscilloscop vore ju bra)."

Detta är intressant. Kollat med scopet, på ena benet blir signalen någon volt och på det andra är det dött.

kanske ska ta å testa med en anna klock-kristall.

"Kan du kolla om timern/countern överhuvudtaget räknar upp?"

hur? Har testat att göra något i stil med:

Kod: Markera allt


if(tcnt2==0x05)
{
PORTA &= ~_BV(PA1); //Lys med en led.
}
else {PORTA &= ~_BV(PA2); }//Lys med en annan led.

[code]

"Har du rätt frekvens på kristallen (både den du har mellan TOSC1 och TOSC2 och den du klockar processorn med)? "

jo, 32khz ska de va står de i databladet.

"Om du har intern oscillator för processorn, är den ställd rätt? "
nej, jag har inte kollat så mycket på de, men jag har tagit för givet att den inte är med i leken nu när jag använder den asynkrona. Att den avaktiveras när man sätter AS2 registret.


"Har du några fuses satta/ej satta som kan inverka på detta? "

ingen aning. Fuses är väl säkringar om min engelska inte är helt fel. Men det har med µC att göra väl? jag har inte gått in och ändrat i det. Så det är på "default"
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Angående fuses...

Accepetera **aldrig** "default".
Kolla **alltid** att de är satta på ett sätt som passar applikation.

Detta gäller oavsett om det är AVR eller PIC...

Och om du inte vet vad det är, så, läs på !
Skriv svar