www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Gesetztes Bit bleibt nicht aktiv. ISR löscht Bit.


Important announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Alexander G. (illness)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hi, schon wieder ein Problem was mich meine Berven kostet. Der Tiny 
macht mich ech zu schaffen....

Problem: in der main schleife setze ich ein bit, dieses wird aber sofort 
wieder zurück gesetzt. die led an dem pin blinkt nur kurz auf.
// Countdown 199 - 0 auf TOT-4301 (2,5 Stelliges 7-Segment von Pollin) 
// ATtiny2313

#include <avr/io.h>
#define  F_CPU 1000000UL 
#include <stdio.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define SETBIT(ADRESS, BIT) (ADRESS |=(1<<BIT))      //Makro zum Setzen eines Bits
#define CLEARBIT(ADRESS, BIT) (ADRESS &=~(1<<BIT))   //Makro zum Loeschen eines Bits
#define CHECKBIT(ADRESS, BIT) (ADRESS &(1<<BIT))     //Makro zum Pruefen eines Bits

volatile int leerlauf;
volatile unsigned int count =0;
volatile unsigned int mpx =0;

volatile unsigned char seg7[]={63,6,91,79,102,109,125,7,127,111};
volatile unsigned int zeit;
volatile unsigned char merker=0;
volatile unsigned char spalte=1;
volatile unsigned char z1;
char digit[];

struct zerlegung
{
  int zahl;
  int var;
  int zehner;
  int hunderter;
  int tausender;
  int zehntausender;
};

struct zerlegung ziffer;


ISR(TIMER0_OVF_vect)
{
    TCNT0 = 150; 
               
    count++;
  mpx++;

  if(mpx==1)  // Multiplexer
  {
    merker=0;

    if(spalte==1)
    {
      CLEARBIT(PIND,PIND1);
      SETBIT(PIND,PIND0);
      
      PORTB=~seg7[digit[1]] + z1;
      spalte=2;
      merker=1;
    }

    if(spalte==2 & merker==0)
    {
      CLEARBIT(PIND,PIND0);
      SETBIT(PIND,PIND1);
      
      
      PORTB =~seg7[digit[0]] + z1;
      spalte=1;
      merker=0;
    }          
  }
  if(mpx==1) mpx=0;    

}

void init(void)

{
  DDRA=0xff;
  DDRB=0xff;          // -> PORTB 0-6 = 7-Segment a-f | PORTB 7 = halbe stelle
  DDRD=0b11100011 ;       // -> PD0 -> Stelle 1, PD1 -> Stelle 2  
                // -> PD 5:7 -> Taster
                  
  TCCR0B = 0x02;        // Timerstart
    TCNT0 = 150;            // Startwert nachladen, 0xFA
                      // 250* 64us=16ms bis Overflow
      
  SREG = (1<<7);           // Allgemeine Interruptfreigabe;

    TIMSK=(1<<TOIE0);       // Freigabe Timer0 Iterrupt    
}  


int main(void)
{
  zeit=124;
  init();  

    while(1)
  {    
    if(zeit<=99) z1 = 0; 
    if(zeit>=100) z1 = 128; 

    if((PIND & 0b00000100) == 0b00000100)
    {
    zeit=30;    
    }
      
    if(count >= 500)              
      {    
      count=0;
      zeit--;


      // Teilt eine 5 Stellige Zahl in einzelne Stellen auf
      // Ausgabe in der Variablen "digit[]"
      // digit[4] -> Erste Stelle
      // digit[0] -> Letzte Stelle

      ziffer.zahl = zeit;

      ziffer.zehner       = ziffer.zahl / 10;
      ziffer.hunderter     = ziffer.zahl / 100;
      ziffer.tausender     = ziffer.zahl / 1000;
      ziffer.zehntausender   = ziffer.zahl / 10000;

      digit[4] = ziffer.zehntausender;

      ziffer.var = ziffer.zehntausender * 10;
      digit[3] = ziffer.tausender - ziffer.var;

      ziffer.var = ziffer.tausender * 10;
      digit[2] = ziffer.hunderter - ziffer.var;

      ziffer.var = ziffer.hunderter * 10;
      digit[1] = ziffer.zehner - ziffer.var;

      ziffer.var = ziffer.zehner * 10;
      digit[0] = ziffer.zahl - ziffer.var;


      if(zeit>0) PORTD |= (1 << 5);   <----------------- HIER, das Bit will nicht bleiben
            
    }      
        
    leerlauf++;  
  }
   
}

bei anderen µCs ist mir das noch nicht passiert....

gruß Alex

Autor: Joachim минифлоть (minifloat)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Das ist so bei den AVRs, dass sie das der entsprechenden ISR zugehörige 
Flag löschen. Aber das meinst du vermutlich garnicht.

Das Array "digit[]" sollte auch volatile sein, da schließlich in der ISR 
darauf zugegriffen wird. Dann solltest du die Größe von digit auf ein 
auf jeden Fall ausreichendes Maß festnageln; auf dem µC gibt es mit 
dieser Umgebung keine dynamische Speicherzuweisung und in der reinen 
Essenz der Programmiersprache C geht das auch nicht auf diese Art und 
Weise.

mfg mf

Autor: Alexander G. (illness)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
ja, das mit dem volatile ist mir noch nicht ganz klar...bei meinem µC 
Board mit nem AT90CAN128 hab ich das noch nie gebraucht....

hab den fehler aber schon gefunden:

ich schreibe in der ISR:

CLEARBIT(PIND,PIND1);
SETBIT(PIND,PIND0);

das muss so sein:

CLEARBIT(PORTD,PORTD1);
SETBIT(PORTD,PORTD0);

.....

Autor: Joachim минифлоть (minifloat)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Alexander G. schrieb:
> ja, das mit dem volatile ist mir noch nicht ganz klar

"volatile" ist ein Schlüsselwort. Flüchtig. Damit Teilst du dem Compiler 
mit, dass sich an der Variable auch zu Zeiten, zu denen ers nicht 
"sieht", etwas ändern könnte oder Fremdzugriffe stattfinden. Dies 
betrifft Schreiben und auch Lesen.

Hier zum Beispiel wird in der "main()" viel an "digit[]" rumgeorgelt. In 
der ISR sehe ich aber auch noch einen Zugriff. Gerade der GCC ist dafür 
bekannt, im Schreiben von Variableninhalten von Registern zurück in den 
RAM je nach Optimierungsstufe extrem faul zu sein. Es wird dann zum 
spätestmöglichen Zeitpunkt; manchmal auch garnicht zurückgespeichert.

Mit "volatile" behandelt der Compiler die Variable wie eine heiße 
Kartoffel. Idealerweise gibt es dazu beim AVR über Pointeradressierung 
eine elegante Methode. Das löst der Compiler dann so auf. 
16Bit-Operationen sind in der Prozessorarchitektur zum Glück als 
atomische(=nicht unterbrechbare) Operationen realisiert. Also einfach an 
die Kartoffel denken.
mfg mf

Ja, auf PINx-Register Schreiben ist Toggeln des PORTx-Registers an den 
Stellen, wo Bits gesetzt sind. Das ist auch erst seit ein paar Jahren 
so. Hab aber auch schon elegantere Lösungen dazu gesehen. Vorteil ist, 
dass man sich so ein paar Zyklen spart.

Autor: Simon K. (simon) Benutzerseite
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
> atomische
atomare?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel




Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder GIF-Format hochladen.
Siehe Bildformate
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net