mikrocontroller.net

Forum: Compiler & IDEs Schleifenabruch bei Tasterdruck


Autor: Jonas K. (nandus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
 #include "em4095.h" 
#define KEYS 2




 #define BAUD 9600UL

/*EEPROM schreiben*/
void EEPROM_write(unsigned int uiAddress, unsigned char ucData) 
{ 
/* Wait for completion of previous write */ 
while(EECR & (1<<EEPE)) 
; 
/* Set up address and data registers */ 
EEAR = uiAddress; 
EEDR = ucData; 
/* Write logical one to EEMPE */ 
EECR |= (1<<EEMPE); 
/* Start eeprom write by setting EEPE */ 
EECR |= (1<<EEPE); 
}

/*EEPROM lesen*/
unsigned char EEPROM_read(unsigned int uiAddress) 
{ 
/* Wait for completion of previous write */ 
while(EECR & (1<<EEPE)) 
; 
/* Set up address register */ 
EEAR = uiAddress; 
/* Start eeprom read by writing EERE */ 
EECR |= (1<<EERE); 
/* Return data from data register */ 
return EEDR; 
}

int uart_putc(char c)
{
  loop_until_bit_is_set(UCSRA, UDRE);
  UDR = c;
  return 0;
}
/*Funktion zum Bitweisen-Vergleichen der TAG IDs*/
int cmp_tag(uint8_t *a,uint8_t *b)
{
int i;
      for (i=0;i<5;i++)
          {
        if(a[i]!=b[i])
            return 0;
        }
return 1;
}


/*RS232-Ausgabe */
void print (char *text)
{
int i=0;
while (text[i])
    uart_putc(text[i++]);
  
}
void nibbleout(int wert)
{
if(wert < 10) uart_putc(wert +'0');
                else
              uart_putc(wert +'A'-10);
}

void hexout(int wert)
{
nibbleout((wert&0xf0)>>4);
nibbleout(wert&0xf);

}

void tagout(uint8_t *a)
{
int i;
      for (i=0;i<5;i++)
          {
        hexout(a[i]);
        }
print("\n\r");
} 



int main()
{
  DDRD  = 1 <<PD2;
  PORTD = 1<<PD2;
  //Leuchtdiodenport
    DDRB  =1<<PB6|1<<PB7;
  char  KeyNichtEingelesen=1; 

  UCSRB = 1<<TXEN;
  UCSRC = 1<<UCSZ1 | 1<<UCSZ0;
  
  UBRRH = (uint8_t) (F_CPU / (BAUD * 16) - 1) / 256;
  UBRRL = (uint8_t) (F_CPU / (BAUD * 16) - 1);



  TCCR0B = 1<<CS01 | 1<<CS00; //Timer/Counter0 prescaler 64
  MCUCR |= 1<<ISC10; //Any logical change on INT1 generates an interrupt request
  GIMSK |= 1<<INT1; //External interrupt request 1 enable (demod_out from RFID chip)

  sei();

  uint8_t tag[5];
    uint8_t key[5];//Schlüssel
  uint8_t abbruch=1;
  unsigned char EEPROM_Inhalt ;
  

  volatile uint32_t d;
  //ersten Tag als Key einlesen




while (1) /*Hauptprogramm*/
         
{
EEPROM_Inhalt = EEPROM_read(0);
if (EEPROM_Inhalt != 0x1F)
{

  while (KeyNichtEingelesen)
  {
    if (em4095_read_tag(key))
    {
  /*  print("Schluessel eingelesen: "); */
    tagout(key); 
  /*  print("\n\r"); */
      KeyNichtEingelesen=0;
    }
    }

   
EEPROM_write(0,key[0]);
EEPROM_write(1,key[1]);
EEPROM_write(2,key[2]);
EEPROM_write(3,key[3]);
EEPROM_write(4,key[4]);
}
else 
{
key[0]=EEPROM_read(0);
key[1]=EEPROM_read(1);
key[2]=EEPROM_read(2);
key[3]=EEPROM_read(3);
key[4]=EEPROM_read(4);
}



   /*HIER IST DAS HAUPTPROBLEM !!!*/
  while (abbruch==1)
  {
    if (em4095_read_tag(tag))
    {
    tagout(tag);


        if (cmp_tag(key,tag))

            PORTB=1<<PB6; //Led an Port PB6 aus und Led an PB7 an
          else
                    PORTB=1<<PB7; //Led an Port PB7 aus und Led an PB6 an

        }
        else

                   { PORTB=1<<PB7;} //Led an Port PB7 aus und Led an PB6 an

      for (d=0; d<50000; d++);

    
    
     
     if (PIND&(1<<PD4))

    {
    
    EEPROM_write(0,0x0);
    abbruch=0;
    } 
    }  
    }
}

Der Verwendete Controller ist ein ATTiny2313 die Anwendung ist das RFID 
Entwicklerboard von Pollin.

Meine Frage wo ist der DENKFEHLER meinerseits das er die Schleife nicht 
abbricht wenn ich den Taster (active High) der an PD4 liegt betätige.
bzw.
2. Frage nachdem ich den Taster der an PD4 anliegt betätige soll das 
Byte 0 im EEPROM mit  Nullen überschrieben werden,  ist dies richtig 
gemacht . Den Prototyp aus dem ATTiny2313 manuel

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rücke mal ordentlich ein, damit man die einzelnen Blöcke {} erkennt.
Und poste als Dateianhang.

Was soll das Programm überhaupt machen?


Peter

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich sehe das Problem in der Reaktion auf den Tastendruck. Vor dem 
Abprüfen ist eine (schlechte) Warteschleife und danach wird gerade in 
einem CPU-Takt auf die Taste geprüft.

Ich schlage vor, dass du in der Warteschleife kontinuierlich auf die 
Taste abprüftst und entsprechend reagierst.

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>

#include <util/delay.h> // F_CPU und -Os nicht vergessen!
#define DEBUG 0         // steuert print Ausgabe
#define DUMMY 1         // weil em4095.h und em4095_read_tag() fehlen

#if DUMMY
uint8_t em4095_read_tag(uint8_t *k)
{
  return 1;
}
#else
#include "em4095.h" 
#endif

#define KEYS 2
#define BAUD 9600UL

/*EEPROM schreiben*/
void EEPROM_write(unsigned int uiAddress, uint8_t ucData) 
{ 
  /* Wait for completion of previous write */ 
  while(EECR & (1<<EEPE)) 
    ; 

  /* Set up address and data registers */ 
  EEAR = uiAddress; 
  EEDR = ucData; 
  /* Write logical one to EEMPE */ 
  EECR |= (1<<EEMPE); 
  /* Start eeprom write by setting EEPE */ 
  EECR |= (1<<EEPE); 

  /* Wait for completion of previous write */ 
  while(EECR & (1<<EEPE)) 
    ; 
}


/*EEPROM lesen*/
uint8_t EEPROM_read(unsigned int uiAddress) 
{ 
  /* Wait for completion of previous write */ 
  while(EECR & (1<<EEPE)) 
    ; 

  /* Set up address register */ 
  EEAR = uiAddress; 
  /* Start eeprom read by writing EERE */ 
  EECR |= (1<<EERE); 
  /* Return data from data register */ 

  return EEDR; 
}


void uart_putc(uint8_t c)
{
  loop_until_bit_is_set(UCSRA, UDRE);
  UDR = c;
}


/*Funktion zum Bitweisen-Vergleichen der TAG IDs*/
uint8_t cmp_tag(uint8_t *a, uint8_t *b)
{
  int i;
  for (i=0;i<5;i++)
  {
    if(*a++ != *b++)
      return 0;
  }
  return 1;
}


/*RS232-Ausgabe */
void print(char *text)
{
  while (*text)
    uart_putc(*text++);
}

void nibbleout(uint8_t wert)
{
  if(wert < 10) 
    uart_putc(wert+'0');
  else
    uart_putc(wert+'A'-10);
}


void hexout(uint8_t wert)
{
  nibbleout((wert&0xf0)>>4);
  nibbleout(wert&0xf);
}


void tagout(uint8_t *a)
{
  int i;
  for (i=0;i<5;i++)
  {
    hexout(*a++);
  }
  print("\n\r");
} 


int main(void)
{
  // Lokale Variablen
  uint8_t tag[5]; // eingelesener Tag
  uint8_t key[5]; // Schlüssel (= gespeicherter Tag)
  unsigned char EEPROM_Inhalt;
#if 0
  volatile uint32_t d;
#else
  uint8_t d;
#endif

  // Ports initialisieren
  DDRD  = 1<<PD2;
  PORTD = 1<<PD2;
  //Leuchtdiodenport
  DDRB  = 1<<PB6|1<<PB7;

  // UART initialisieren
  UCSRB = 1<<TXEN;
  UCSRC = 1<<UCSZ1 | 1<<UCSZ0;
  UBRRH = (uint8_t) (F_CPU / (BAUD * 16) - 1) / 256;
  UBRRL = (uint8_t) (F_CPU / (BAUD * 16) - 1);

  // Timer0 initialisieren
  TCCR0B = 1<<CS01 | 1<<CS00; //Timer/Counter0 prescaler 64
  MCUCR |= 1<<ISC10;          //Any logical change on INT1 generates an interrupt request
  GIMSK |= 1<<INT1;           //External interrupt request 1 enable (demod_out from RFID chip)
  sei();

  while (1) 
  {
    /*
        Erstes Byte aus dem EEPROM einlesen
        Wenn 1. byte aus EEPROM UNGLEICH 0x1F 
        ist, dann key mit em4095_read_tag() 
        einlesen und in EEPROM speichern
     */
    EEPROM_Inhalt = EEPROM_read(0);
    
    if (EEPROM_Inhalt != 0x1F)
    {
      uint8_t KeyEingelesen = 0; 
      while (!KeyEingelesen)
      {
        if (em4095_read_tag(key))
        {
#if DEBUG
          print("Schluessel eingelesen: ");
#endif
          tagout(key); 
          KeyEingelesen = 1;
#if DEBUG
          print("\n\r");
#endif
        }
      }
      EEPROM_write(0,key[0]);
      EEPROM_write(1,key[1]);
      EEPROM_write(2,key[2]);
      EEPROM_write(3,key[3]);
      EEPROM_write(4,key[4]);
    }
    else 
    {
      // key bereits im EEPROM vorhanden
      key[0]=EEPROM_read(0);
      key[1]=EEPROM_read(1);
      key[2]=EEPROM_read(2);
      key[3]=EEPROM_read(3);
      key[4]=EEPROM_read(4);
    }

    /*
       Weitere tags einlesen und mit key
       vergleichen und Ergebnis an LEDs anzeigen
       Abbruch durch Druck auf Taster
     */
    uint8_t abbruch = 0;
    while (!abbruch)
    {
      if (em4095_read_tag(tag))
      {
        tagout(tag);
        if (cmp_tag(key,tag))
          PORTB = 1<<PB6; // Led an Port PB6 aus und Led an PB7 an
        else
          PORTB = 1<<PB7; // Led an Port PB7 aus und Led an PB6 an
      }
      else
      { 
#if 0
        PORTB = 1<<PB7; //Led an Port PB7 aus und Led an PB6 an
#else
        PORTB = (1<<PB7) | (1<<PB7); //Led an Port PB7 und PB6 aus
#endif
      } 

#if 0
      for (d=0; d<50000; d++);

      if (PIND & (1<<PD4))
      {
        EEPROM_write(0,0x0);
        abbruch = 1;
      } 
#else
      /*
          User ca. 3s (120*25=3000) Zeit geben, 
          um Taster zu drücken. Tastendruck selbst
          wird alle 25ms gepollt
          
          Tastendruck löscht 1. Byte vom EEPROM
          (key ungültig machen)
       */
      for (d = 0; d < 120; d++)
      {
        // active-high Taster gedrückt?
        if (PIND & (1<<PD4))
        {
          EEPROM_write(0,0x0);
          abbruch = 1; // while(!abbruch) verlassen
          break;       // for sofort verlassen
        } 
        _delay_ms(25);      
      }
#endif 
    } // while(!abbruch) 
  }
}

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
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
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 bestätigst du, die Nutzungsbedingungen anzuerkennen.