TXC FLag Problem mit dem ATmega644P

Gast #1246209
Lesenswert?
• ▲
▼
Hab jetzt folgendes Programm geschrieben:
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
#include<avr/sleep.h>
4
#include<util/delay.h>
5
#include"timer.h"
6
#include"uart.h"
7

8
#define F_CPU 4000000UL
9

10
// 9600 baud
11
#define UART_BAUD_RATE 9600
12

13
volatile uint8_t time=0;
14

15
ISR(TIMER2_OVF_vect)
16
{  
17
  time++;
18
}
19
int main()
20
{  uint8_t test=0;
21
   DDRA=0xff;
22
  PORTA=0xff;
23

24
  while(test!=100)
25
  {  _delay_ms(10);
26
    test++;
27
  }test=0;
28
  set_sleep_mode(SLEEP_MODE_PWR_SAVE);
29
  sleep_enable();
30
  
31
  timer2_init();
32

33
  sei();
34

35
  while(1)
36
  {
37
    if(time==5)
38
    {  
39
      uart_puts("jip das klappt");
40
      while ((UCSR0A & (1 << TXC0)) != 1);
41
  //    UCSR0A =(1 << TXC0);
42
      time=0;
43
    
44
    }
45
    else
46
      {
47
        PORTA=time;
48
        sleep_cpu(); 
49
      }
50
  }
51
  return(0);
52
}

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!
Gast #1246220
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)));
Gast #1246232
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.
Gast #1246264
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,...).
Moderator Persönliche Seite #1246278
Lesenswert?
• ▲
▼
Peter Dannegger wrote:
> Man könnte aber auch schreiben:
>
1
> while (!!(UCSR0A & (1 << TXC0)) != 1);
2
>

Aber wirklich besser lesbar im Vergleich zu
1
while ((UCSR0A & (1 << TXC0)) == 0)
2
  /* 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.)
Gast #1246303
Lesenswert?
• ▲
▼
So, bin jetzt soweit:
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
#include<avr/sleep.h>
4
#include<util/delay.h>
5
#include"timer.h"
6
#include"uart.h"
7

8
#define F_CPU 4000000UL
9

10
// 9600 baud
11
#define UART_BAUD_RATE 9600
12

13
volatile uint8_t time=0;
14

15
ISR(TIMER2_OVF_vect)
16
{  
17
  time++;
18
}
19
int main()
20
{  uint8_t test=0;
21
   DDRA=0xff;
22
  PORTA=0xff;
23

24
  while(test!=100)
25
  {  _delay_ms(10);
26
    test++;
27
  }test=0;
28
  set_sleep_mode(SLEEP_MODE_PWR_SAVE);
29
  sleep_enable();
30
  uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
31
  
32
  timer2_init();
33

34
  sei();
35

36
  while(1)
37
  {
38
    if(time==5)
39
    {
40
      uart_puts("ein durchlauf klappt");  
41
      while ((UCSR0A & (1 << TXC0)) == 0);
42
      time=0;
43
    
44
    }
45
    else
46
      {
47
        PORTA=time;
48
        sleep_cpu(); 
49
      }
50
  }
51
  return(0);
52
}

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?
Gast #1246415
Lesenswert?
• ▲
▼
Hab jetzt folgendes Problem!
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
#include<avr/sleep.h>
4
#include<util/delay.h>
5
#include"timer.h"
6
#include"bewgs.h"
7
#include"uart.h"
8

9
#define F_CPU 4000000UL
10

11
// 9600 baud
12
#define UART_BAUD_RATE 9600
13

14
volatile uint8_t time=0;
15
volatile uint8_t bewg=0;
16

17
ISR(TIMER2_OVF_vect)
18
{  
19
  time++;
20
}
21

22
ISR(PCINT3_vect)
23
{
24
  bewg=1;
25
}
26
int main()
27
{  uint8_t test=0;
28
   DDRB=0xff;
29
  PORTB=0xff;
30

31
  while(test!=100)
32
  {  _delay_ms(10);
33
    test++;
34
  }test=0;
35
  set_sleep_mode(SLEEP_MODE_PWR_SAVE);
36
  sleep_enable();
37
  uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
38
  
39
  timer2_init();
40
  pcint0_init();
41

42
  sei();
43

44
  while(1)
45
  {
46
    if(bewg==1)
47
    {  
48
      uart1_puts("interrupt wurde ausgeloest!");
49
      while ((UCSR0A & (1 << TXC0)) == 0);
50
      UCSR0A|=(1<<TXC0);
51
      bewg=0;
52
    }
53
    if(time==5)
54
    {
55
      time=0;
56
    }
57
    else
58
      {
59
        PORTB=time;
60
        sleep_cpu(); 
61
      }
62
  }
63
  return(0);
64
}

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?

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.