Forum: Compiler & IDEs Zeigerzuweisung in funktioniert nicht?


von Stephan (Gast)


Lesenswert?

Hallo,

stehe glaub ich, total auf dem Schlauch?!??!??????

Habe einen Zeiger auf volatile unsigned char* myUSART_tx ;
Im Verlauf des Programms soll dieser auf unterschiedliche strings 
Zeigen,
die dann über USART ausgegeben werden. Das mach ich in einer ISR die den
Zeiger kennt.....nun mein Problem>
Die Zuweisung funktioniert nur beim ersten mal
myUSART_tx = &myUSART_tx_mes_1[0] ;

innerhalb einer endlosschleife, soll myUSART_tx auf einen anderen
string zeigen. Das tut er jedoch nicht.

Er Springt in der Endlosschleife in die If  Abfrage, wie mir eine
LED an Port C anzeigt! Jedoch gibt es keine weitere Ausgabe..
Wenn ich aber innerhalb der Endlosschleife eine LCD Ausgabe mache,
dann funktioniert es wie es soll!!
Wo ist mein Denkfehler?!??

Bitte um eure Hilfe!
Benutzte einen ATMega8 und WinAVR-20090313
Quellcodes sind angehängt, unten steht mein main- Funktion
1
//#include <string.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <util/delay.h>
5
#include "include/lcd_modul.h"
6
#include "include/uart_modul.h"
7
//#include "include/counter_modul.h"
8
9
#define MaxLen  120
10
  unsigned char myUSART_tx_mes_1[] = "       ******ATMega8 Evaluation Software******\n\r" ; //Sendebuffer             
11
  unsigned char myUSART_tx_prompt[] = "ATMega8>" ;
12
 volatile unsigned char  USART_r_Buffer[MaxLen]; // Empfangsbuffer
13
 volatile unsigned char  * myUSART_tx ;
14
 unsigned char USART_received[MaxLen]; // fertig empfangener string
15
uint8_t ov0_cnt  = 0 ;
16
uint8_t cmp2_cnt = 0 ;
17
18
19
20
int main(void)
21
  {
22
23
   DDRC  = 0xff ; // Setzt das Richtungsregister des Ports B auf 0xff(alle Pins als Ausgang)
24
   PORTC = 0xFF ; // Alle Ausgänge von PortB auf 1 setzten ( Alle LED´s aus!! )
25
   lcd_init();
26
27
   set_cursor(0,1);
28
   lcd_string("Hallo, es funktioniert!");
29
   _delay_ms(100);
30
   set_cursor(0,2);
31
   
32
   myUSART_tx = &myUSART_tx_mes_1[0] ; // Ersten Text Ausgeben Zeigerzuweisung funktioniert hier!!!
33
   USART_Init(UBRR_VAL);
34
   sei();   //Interrupt wieder global freigeben
35
36
37
  for(;;) // Endlosschleife, Hauptprogramm
38
   {
39
         
40
      if((USART_reg.TXC_tatus == 1) & (USART_reg.prompt_tx == 0))
41
       {
42
    cli();
43
      USART_reg.prompt_tx = 1 ; 
44
    USART_reg.TXC_tatus = 0 ; 
45
      myUSART_tx = &myUSART_tx_prompt[0] ; // Der Zeiger wird nicht geaendert WARUM?!???
46
    sei();
47
        UCSRB |= (1 << UDRIE) ; // UASART_UDRE auslösen
48
    ov0_cnt++;
49
    //lcd_string("1.bliblablupp");
50
       }
51
     
52
     if (ov0_cnt == 1)
53
     {
54
      ov0_cnt = 0 ;
55
    PORTC ^= (1 << 2);
56
     }
57
   } // Endlosschleife, Hauptprogramm ende
58
   return(0);
59
  }
60
61
62
63
ISR(USART_UDRE_vect)
64
  { 
65
    static uint8_t StringLen ;
66
  
67
   if ( *myUSART_tx != '\0')
68
    { // string senden bis string ende Zeichen
69
    UDR = *myUSART_tx ; // naechstes Zeichen ins udr
70
      StringLen++; //mitzaehlen fuer naechstes Zeichen im array
71
    myUSART_tx++ ;
72
  }
73
   else
74
    {
75
     StringLen = 0; // zeichenzähler zurücksetzten
76
   USART_reg.TXC_tatus = 1 ; // kompletter string gesendet, durch dieses bit anzeigen
77
   UCSRB &=  ~(1 << UDRIE); // UDRIE bit löschen, damit wird dieser IRQ nicht mehr ausgeloest
78
    }
79
   sei();   //Interrupt wieder global freigeben
80
  }
81
82
ISR(USART_RXC_vect)
83
  {
84
   static uint8_t StringLen ;
85
   uint8_t NextChar;
86
87
   NextChar = UDR ; // USART Datenregister auslesen
88
     
89
   if ( NextChar != '\n' && StringLen < MaxLen - 1 )
90
    { // solange lesen bis Return oder maximale länge
91
    USART_r_Buffer[StringLen] = NextChar ;
92
      StringLen++ ;
93
  }
94
   else
95
    {
96
      USART_r_Buffer[StringLen+1]  = '\0'; // das stringende anzeigen
97
     StringLen = 0;
98
     USART_reg.RXC_tatus = 1 ; // kompletten string empfangen
99
    }
100
   sei()      ;   //Interrupt wieder global freigeben
101
  }
102
/*
103
ISR(TIMER0_OVF_vect)
104
  {
105
   ov0_cnt++ ;
106
   sei()     ;   //Interrupt wieder global freigeben
107
  }
108
109
ISR(TIMER2_OVF_vect)
110
  {
111
   PORTC |= (1 << 2) ;//wenn ja löschen (LED an!!!)
112
   sei()     ;   //Interrupt wieder global freigeben
113
  }
114
ISR(TIMER2_COMP_vect)
115
  {
116
   TCNT2 = 0x00 ;
117
   cmp2_cnt++   ;
118
   sei()        ;  //Interrupt wieder global freigeben
119
  }  */
Vielen Dank im Voraus....

von Stephan (Gast)


Angehängte Dateien:

Lesenswert?

hier der Anhang ! ;-)

von Rolf Magnus (Gast)


Lesenswert?

Dein Problem dürfte darin liegen, daß der Zeiger zwar auf ein Array aus 
volatile char zeigt, aber selbst nicht volatile ist.

von Stephan (Gast)


Lesenswert?

Habe bereits vieles Ausprobiert!

Der zeiger selbst ist ja  volatile unsigned char  * myUSART_tx ;

dieses  volatile unsigned char volatile  * myUSART_tx ;
funktioniert auch nicht.....
ob die arrays volatile sind oder nicht machte keinen unterschied....

Habe schon vieles ausprobiert!

Vielen Dank für die Antwort.

von Stefan E. (sternst)


Lesenswert?

Stephan wrote:

> Der zeiger selbst ist ja  volatile unsigned char  * myUSART_tx ;
>
> dieses  volatile unsigned char volatile  * myUSART_tx ;
> funktioniert auch nicht.....

Der Zeiger selbst ist nicht volatile, auch nicht bei der zweiten 
Version.

Richtig:
1
unsigned char *  volatile myUSART_tx;

von Stephan (Gast)


Lesenswert?

Hallo,

tatsächlich nun funktioniert es...Anfängerfehler... :-p
Wieder was dazugelernt. Bin sonst eher Hardwerker ;-)

Vielen Dank, habe schon stundenlang probiert.

Interressant ist das es auch mit
1
 volatile unsigned char  * myUSART_tx ;

funktioniert wenn ich gleichzeitig die Funktion
1
lcd_string("1.bliblablupp"); // Ausgabe auf LCD

in der Endlosschleife benutzte.
im Quelltext oben habe ich sie hier auskommentiert...


Vielen Dank für eure Hilfe!

von Stefan E. (sternst)


Lesenswert?

Stephan wrote:

> Interressant ist das es auch mit
> ...
> funktioniert wenn ich gleichzeitig die Funktion
> ..
> in der Endlosschleife benutzte.

Ja, denn vor einem Funktionsaufruf muss der Compiler geänderte globale 
Variablen zurückschreiben, denn die Funktion könnte ja auch darauf 
zugreifen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.