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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren