www.mikrocontroller.net

Forum: Compiler & IDEs Zeigerzuweisung in funktioniert nicht?


Autor: Stephan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

//#include <string.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "include/lcd_modul.h"
#include "include/uart_modul.h"
//#include "include/counter_modul.h"

#define MaxLen  120
  unsigned char myUSART_tx_mes_1[] = "       ******ATMega8 Evaluation Software******\n\r" ; //Sendebuffer             
  unsigned char myUSART_tx_prompt[] = "ATMega8>" ;
 volatile unsigned char  USART_r_Buffer[MaxLen]; // Empfangsbuffer
 volatile unsigned char  * myUSART_tx ;
 unsigned char USART_received[MaxLen]; // fertig empfangener string
uint8_t ov0_cnt  = 0 ;
uint8_t cmp2_cnt = 0 ;



int main(void)
  {

   DDRC  = 0xff ; // Setzt das Richtungsregister des Ports B auf 0xff(alle Pins als Ausgang)
   PORTC = 0xFF ; // Alle Ausgänge von PortB auf 1 setzten ( Alle LED´s aus!! )
   lcd_init();

   set_cursor(0,1);
   lcd_string("Hallo, es funktioniert!");
   _delay_ms(100);
   set_cursor(0,2);
   
   myUSART_tx = &myUSART_tx_mes_1[0] ; // Ersten Text Ausgeben Zeigerzuweisung funktioniert hier!!!
   USART_Init(UBRR_VAL);
   sei();   //Interrupt wieder global freigeben


  for(;;) // Endlosschleife, Hauptprogramm
   {
         
      if((USART_reg.TXC_tatus == 1) & (USART_reg.prompt_tx == 0))
       {
    cli();
      USART_reg.prompt_tx = 1 ; 
    USART_reg.TXC_tatus = 0 ; 
      myUSART_tx = &myUSART_tx_prompt[0] ; // Der Zeiger wird nicht geaendert WARUM?!???
    sei();
        UCSRB |= (1 << UDRIE) ; // UASART_UDRE auslösen
    ov0_cnt++;
    //lcd_string("1.bliblablupp");
       }
     
     if (ov0_cnt == 1)
     {
      ov0_cnt = 0 ;
    PORTC ^= (1 << 2);
     }
   } // Endlosschleife, Hauptprogramm ende
   return(0);
  }



ISR(USART_UDRE_vect)
  { 
    static uint8_t StringLen ;
  
   if ( *myUSART_tx != '\0')
    { // string senden bis string ende Zeichen
    UDR = *myUSART_tx ; // naechstes Zeichen ins udr
      StringLen++; //mitzaehlen fuer naechstes Zeichen im array
    myUSART_tx++ ;
  }
   else
    {
     StringLen = 0; // zeichenzähler zurücksetzten
   USART_reg.TXC_tatus = 1 ; // kompletter string gesendet, durch dieses bit anzeigen
   UCSRB &=  ~(1 << UDRIE); // UDRIE bit löschen, damit wird dieser IRQ nicht mehr ausgeloest
    }
   sei();   //Interrupt wieder global freigeben
  }

ISR(USART_RXC_vect)
  {
   static uint8_t StringLen ;
   uint8_t NextChar;

   NextChar = UDR ; // USART Datenregister auslesen
     
   if ( NextChar != '\n' && StringLen < MaxLen - 1 )
    { // solange lesen bis Return oder maximale länge
    USART_r_Buffer[StringLen] = NextChar ;
      StringLen++ ;
  }
   else
    {
      USART_r_Buffer[StringLen+1]  = '\0'; // das stringende anzeigen
     StringLen = 0;
     USART_reg.RXC_tatus = 1 ; // kompletten string empfangen
    }
   sei()      ;   //Interrupt wieder global freigeben
  }
/*
ISR(TIMER0_OVF_vect)
  {
   ov0_cnt++ ;
   sei()     ;   //Interrupt wieder global freigeben
  }

ISR(TIMER2_OVF_vect)
  {
   PORTC |= (1 << 2) ;//wenn ja löschen (LED an!!!)
   sei()     ;   //Interrupt wieder global freigeben
  }
ISR(TIMER2_COMP_vect)
  {
   TCNT2 = 0x00 ;
   cmp2_cnt++   ;
   sei()        ;  //Interrupt wieder global freigeben
  }  */

Vielen Dank im Voraus....

Autor: Stephan (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
hier der Anhang ! ;-)

Autor: Rolf Magnus (Gast)
Datum:

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

Autor: Stephan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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:
unsigned char *  volatile myUSART_tx;

Autor: Stephan (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
 volatile unsigned char  * myUSART_tx ;

funktioniert wenn ich gleichzeitig die Funktion
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!

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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.

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.