www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik TXC FLag Problem mit dem ATmega644P


Autor: Tommy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab jetzt folgendes Programm geschrieben:
#include<avr/io.h>
#include<avr/interrupt.h>
#include<avr/sleep.h>
#include<util/delay.h>
#include"timer.h"
#include"uart.h"

#define F_CPU 4000000UL

// 9600 baud
#define UART_BAUD_RATE 9600

volatile uint8_t time=0;

ISR(TIMER2_OVF_vect)
{  
  time++;
}
int main()
{  uint8_t test=0;
   DDRA=0xff;
  PORTA=0xff;

  while(test!=100)
  {  _delay_ms(10);
    test++;
  }test=0;
  set_sleep_mode(SLEEP_MODE_PWR_SAVE);
  sleep_enable();
  
  timer2_init();

  sei();

  while(1)
  {
    if(time==5)
    {  
      uart_puts("jip das klappt");
      while ((UCSR0A & (1 << TXC0)) != 1);
  //    UCSR0A =(1 << TXC0);
      time=0;
    
    }
    else
      {
        PORTA=time;
        sleep_cpu(); 
      }
  }
  return(0);
}

Jedoch läuft das Programm einmal durch und dann bleibt der Timer stehen.
Hab irgendwo gelesen, dass man das TXC FLag zurücksetzen muss habs mit 
der auskommentierten Zeile versucht, klappt aber auch nicht!

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wo initialisierst du das USART?

> while ((UCSR0A & (1 << TXC0)) != 1);
Ungünstig, wenn TXC0 nicht an der ersten Stelle im Byte steht.
besser ist
 while ((UCSR0A & (1 << TXC0)) == 0);

oder
 while (!(UCSR0A & (1 << TXC0)));

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nicht der Timer bleibt stehen, sondern deine main landet in einer 
Endlosschleife, denn "(UCSR0A & (1 << TXC0))" ist immer ungleich 1.
Es ist nämlich entweder 0 oder 64.

Autor: Tommy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso denn 64?

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tommy wrote:
> Wieso denn 64?

Weil das Bit an Position 6 steht. Wenn das Bit gesetzt ist, ist das 
Ergebnis von "(UCSR0A & (1 << TXC0))" 01000000 (=64).

Komm jetzt aber nicht auf Idee "!= 64" zu schreiben. Benutze eine der 
schon genannten Varianten.

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Wieso denn 64?

Das TXC0-Bit steht an der 7.Stelle des UCSRA0-Bytes.
Dein TXC0 ist nichts anderes als eine Textersetzung zur besseren 
Lesbarkeit für eine 7.
2hoch7 ist 64.
1<<TXC0 ist gleich 1<<7 also = 64

In deinem Vergleich steht dann entweder:
64 == 1
oder
0 == 1

beides ist natürlich falsch (vom logischen Vergleich aus gesehen).
Teste lieber auf 0.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
STK500-Besitzer wrote:

> Dein TXC0 ist nichts anderes als eine Textersetzung zur besseren
> Lesbarkeit für eine 7.
> 2hoch7 ist 64.
> 1<<TXC0 ist gleich 1<<7 also = 64

Ersetze 7 durch 6, dann passt es. ;-)

Autor: Tommy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke danke habs vertsanden!

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man könnte aber auch schreiben:
while (!!(UCSR0A & (1 << TXC0)) != 1);

Die doppelte logische Negation ist immer 1 bei einem wahren Ausdruck.


Peter

Autor: Florian D. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, die nächste Frage ist: Was weckt deine MCU wieder auf? Du gehst in 
den Power Save Mode, und dann bleibt natürlich der Timer stehen. Ausser 
du versorgst ihn mit einem externen Takt (Uhrenquarz,...).

Autor: Tommy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja hab ich , timer2 mit 32,768khz

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger wrote:
> Man könnte aber auch schreiben:
>
> while (!!(UCSR0A & (1 << TXC0)) != 1);
> 

Aber wirklich besser lesbar im Vergleich zu
while ((UCSR0A & (1 << TXC0)) == 0)
  /* wait */;

ist das auch nicht.  (Den wait-Kommentar auf einer extra Zeile habe
ich mir generell angewöhnt.  Ein einzelnes Semikolon hinter einer
while-Anweisung ist ziemlich schnell zu übersehen.  Mit dem
Kommentar ist es klar, dass dies so die Absicht des Programmierers
war.)

Autor: Tommy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, bin jetzt soweit:
#include<avr/io.h>
#include<avr/interrupt.h>
#include<avr/sleep.h>
#include<util/delay.h>
#include"timer.h"
#include"uart.h"

#define F_CPU 4000000UL

// 9600 baud
#define UART_BAUD_RATE 9600

volatile uint8_t time=0;

ISR(TIMER2_OVF_vect)
{  
  time++;
}
int main()
{  uint8_t test=0;
   DDRA=0xff;
  PORTA=0xff;

  while(test!=100)
  {  _delay_ms(10);
    test++;
  }test=0;
  set_sleep_mode(SLEEP_MODE_PWR_SAVE);
  sleep_enable();
  uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
  
  timer2_init();

  sei();

  while(1)
  {
    if(time==5)
    {
      uart_puts("ein durchlauf klappt");  
      while ((UCSR0A & (1 << TXC0)) == 0);
      time=0;
    
    }
    else
      {
        PORTA=time;
        sleep_cpu(); 
      }
  }
  return(0);
}

Der timer2 läuft jetzt zwar weiter, aber über die Uart wird im zweiten 
Durchlauf michts mehr geschickt!
Liegt das jetzt daran, das er zu spät wach wird?

Autor: Tommy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habs gelöst, das TXC0 Flag muss wieder gelöscht werden und zwar mit eins 
setzen! jippih

Autor: Tommy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
als nächste versuch ich einen externen Interrupt auszulösen!

Autor: Tommy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab jetzt folgendes Problem!
#include<avr/io.h>
#include<avr/interrupt.h>
#include<avr/sleep.h>
#include<util/delay.h>
#include"timer.h"
#include"bewgs.h"
#include"uart.h"

#define F_CPU 4000000UL

// 9600 baud
#define UART_BAUD_RATE 9600

volatile uint8_t time=0;
volatile uint8_t bewg=0;

ISR(TIMER2_OVF_vect)
{  
  time++;
}

ISR(PCINT3_vect)
{
  bewg=1;
}
int main()
{  uint8_t test=0;
   DDRB=0xff;
  PORTB=0xff;

  while(test!=100)
  {  _delay_ms(10);
    test++;
  }test=0;
  set_sleep_mode(SLEEP_MODE_PWR_SAVE);
  sleep_enable();
  uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
  
  timer2_init();
  pcint0_init();

  sei();

  while(1)
  {
    if(bewg==1)
    {  
      uart1_puts("interrupt wurde ausgeloest!");
      while ((UCSR0A & (1 << TXC0)) == 0);
      UCSR0A|=(1<<TXC0);
      bewg=0;
    }
    if(time==5)
    {
      time=0;
    }
    else
      {
        PORTB=time;
        sleep_cpu(); 
      }
  }
  return(0);
}

Der Interrupt wird zwar ausgelöst, aber über die Uart wird nichts 
geschickt und darauf hin blebt das Programm in der while Schelife drin, 
da ja das txc bit nicht gesetzt wird! Weiß jemand woran das liegen kann?

Autor: Tommy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab jezt schon nen Fehler gesehen! Keine Ahnung warum ich etwas über die 
uart1 schicken will, wobei ich doch uart aktiviert habe!

Autor: Tommy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jip das wars! Sorry hätte ich gar nicht posten müssen, habs erst gesehen 
als es schon drin war

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jemand sollte Andreas Schwarz vorschlagen, ein Selbstgesprächsforum 
einzuführen.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tommy könnte sich ja auch in Zukunft Ingrid nennen...

http://de.wikipedia.org/wiki/Ingrid#Sonstiges

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.