- Labornetzteil AliExpress         
Seite 4 von 5 ErsteErste ... 2345 LetzteLetzte
Ergebnis 31 bis 40 von 49

Thema: UART mit dem F330 von SiLabs

  1. #31
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    53
    Beiträge
    502
    Anzeige

    Powerstation Test
    Danach oder davor, wie du willst, hauptsache du erlaubst ihm den UART-Interrupt

    Und du solltest dein rx_ready auch wieder auf 0 setzen nach dem Ausgeben, wenn du noch mehr empfangen willst.

    PS: Vergiss nicht dein Programmieradapter

    sast

    雅思特史特芬
    开发及研究

  2. #32
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    08.04.2009
    Ort
    an der Ostsee
    Beiträge
    334
    moin moin,

    also im Pollin-Modus geht senden und empfangen, im Interrupt-Modus gehts nicht.
    Wenn Du das Datenblatt liest, wirst Du feststellen, der UART-Interrupt kommt dann wenn:
    Ri: es wurde ein Zeichen empfangen
    Ti: der Sendepuffer wurde leer
    In der UART-ISR muss daher geprüft werden welches Ereignis den Interrupt ausgelöst hat. Senden willst Du ohne Interrupt, jedoch der Empfang soll in der ISR erfolgen. Die ISR muss dann so aussehen:
    - ist Ti gesetzt gleich wieder raus
    - ist Ri gesetzt, Ri löschen, Zeichen abholen und im Puffer ablegen.
    Sende nicht innerhalb der ISR über Tx neue Zeichen, gebe lieber über einen Port mit LED den Zustand an.

    Mit Gruß
    Peter

  3. #33
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    53
    Beiträge
    502
    Hi Peter,

    in der ISR fragt er ja schon nur den RI0 ab. Beim TI macht er gar nichts.

    Mit der UART Ausgabe in der Routine gebe ich dir recht. Sollte da nicht rein. Vielleicht gehts ja jetzt schon. Oft erfährt man das ja dann zum Schluß nicht, weil das Interesse am Schreiben nachläßt, wenn man die Lösung hat.

    Im Moment sehe ich jedenfalls nicht, wo es noch hängen sollte.

    Gute Nacht
    sast

    雅思特史特芬
    开发及研究

  4. #34
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.07.2006
    Ort
    nähe Rottweil
    Alter
    39
    Beiträge
    240
    Hallo

    Vielen Dank für die Antworten! Die Lust am Schreiben hat noch nicht nachgelassen. Nur die Zeit hat gefehlt...
    Leider funktioniert das ganze immernochnicht... Ich habe das senden aus der ISR raus genommen. und habe in main jetzt nur noch stehen:

    Code:
    void main (void)
    {
    	
    	// Disable Watchdog timer
       	PCA0MD &= ~0x40;                    // WDTE = 0 (clear watchdog timer
                                           // enable)
       	OSCILLATOR_Init ();                 // Initialize Oscillator
    	PORT_Init();                        // Initialize Port I/O
    	UART0_Init ();						// Initialize UART0
    
    	EA = 1;								//Interrupts global freigeben
    	ES0 = 1;							//UART0 interrupt freigeben
    	RI0=0;
    	
    	while(1)
    	{
    		while (RX_ready == 0);
    		
    		putchar(the_char);
    		the_char = 0;
    		 
    	}
    
    }
    Trotzdem will das ganze noch nicht so... so langsam weiß ich auch nichtmehr woran das noch liegen kann...
    Habe auch schon versucht wie sich das ganze verhält wenn ich den Controller ohne das Interface betreibe. Das brachte leider auch kein anderes Ergebniss...

    Grüße!

    Bean

  5. #35
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    53
    Beiträge
    502
    Da du an verschiedenen Stellen Änderungen vornimmst, hat es wenig Sinn nur einen Teil des Codes zu posten. Leider kann ich nur theoretische Überlegungen anstellen, da mir die Hardware zum Testen fehlt. Aber wenn es ohne ISR ging dann muss es auch mit funktionieren.

    Außerdem hatte ich dir ja weiter oben schon gesagt, dass du nicht vergessen sollst das RX_ready wieder auf 0 zu setzen wenn du putchar aufgerufen hast, sonst sendet der immer wieder the_char da RX_ready aus der ISR auf 1 gesetzt wurde.

    Wenn du den restlichen Code noch so hast wie bisher, dann hast du auch 2 unabhängige Variablen the_char. Die in der ISR deklarierte ist nämlich eine andere als die globale. D.h. selbst wenn deine ISR mal funktioniert wirst du in the_char für das putchar nie was empfangenes drin haben. Verstehst du den Unterschied zwischen lokalen und globalen Variablen? Variablen die im normalen Programmablauf und in einer ISR verwendet werden müssen als volatile deklariert werden.

    Pass das Programm mal an und reduziere die ISR auf das Setzen des RX_ready (wird auch im main() und in der ISR verwendet) und das RI0 rücksetzen und das SBUF0 in the_char Schreiben.

    Die 3 Funktionen können auch erst mal weg. Da haben wir dann nur noch den relevanten Code und versuchen uns mal ranzutasten.
    Ein Zeichen empfangen und zurücksenden mit RX-ISR

    sast

    雅思特史特芬
    开发及研究

  6. #36
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.07.2006
    Ort
    nähe Rottweil
    Alter
    39
    Beiträge
    240
    Hallo

    Vielen Dank! Jetzt funktioniert es. Lag zum einen daran dass die Variable nicht als Volatile deklariert war .
    Darauf hätte ich auch kommen können. Zum anderen hab ich jetzt mal noch das mit dem Array aus der ISR genommen. Also wirklich nur die Variable the_char beschrieben.
    Ich würde jetzt aber schon noch gerne mehrere Strings in ein Array schreiben bis ein bestimmtes Zeichen kommt. Werde das jetzt dann mal noch in Angriff nehmen. Werde dann wieder fragen...

    Hier mal noch mein aktueller Code:
    Code:
    #include <c8051F330.h>
    #include <stdio.h>
    
    #define SYSCLK			24500000
    #define BAUDRATE		115200
    #define RX_length		25
    
    //-----------------------------------------------------------------------------
    // Global Variables
    //-----------------------------------------------------------------------------
    
    //bit TX_ready;						//True = OK zur Übertragung
    //char *TX_ptr;						//pointer auf zu übermittelnden String
    
    bit RX_ready;						//True = string empfangen
    char RX_buf[RX_length];				//Array als Eingangsbuffer anlegen
    
    volatile unsigned char the_char;				//zwischenspeicher
    
    
    sfr  SBUF = 0x99;
    
    
    //-----------------------------------------------------------------------------
    // Function Prototypes
    //-----------------------------------------------------------------------------
    
    void OSCILLATOR_Init (void);
    void UART0_Init (void);
    void PORT_Init (void);
    void UART0_ISR (void);
    void Print_String (char pstring[]);
    char nb_getkey ();
    char b_getkey ();
    
    //-----------------------------------------------------------------------------
    // main Routine
    //-----------------------------------------------------------------------------
    void main (void)
    {
    	
    	// Disable Watchdog timer
       	PCA0MD &= ~0x40;                    // WDTE = 0 (clear watchdog timer
                                           // enable)
       	OSCILLATOR_Init ();                 // Initialize Oscillator
    	PORT_Init();                        // Initialize Port I/O
    	UART0_Init ();						// Initialize UART0
    
    	EA = 1;								//Interrupts global freigeben
    	ES0 = 1;							//UART0 interrupt freigeben
    	RI0=0;
    	
    	while(1)
    	{
    		while (RX_ready == 0);
    		
    		putchar(the_char);
    		RX_ready = 0;
    		 
    	}
    
    }
    
    //-----------------------------------------------------------------------------
    // Initialization Subroutines
    //-----------------------------------------------------------------------------
    
    //-----------------------------------------------------------------------------
    // OSCILLATOR_Init
    //-----------------------------------------------------------------------------
    //
    // Return Value : None
    // Parameters   : None
    //
    // This routine initializes the system clock to use the internal 24.5MHz
    // oscillator as its clock source.  Also enables missing clock detector reset.
    //
    //-----------------------------------------------------------------------------
    void OSCILLATOR_Init (void)
    {
       OSCICN |= 0x03;                     // Configure internal oscillator for
                                           // its maximum frequency
       RSTSRC  = 0x04;                     // Enable missing clock detector
    }
    
    //-----------------------------------------------------------------------------
    // PORT_Init
    //-----------------------------------------------------------------------------
    //
    // Return Value : None
    // Parameters   : None
    //
    // P0.4    digital    push-pull     UART TX
    // P0.5    digital    open-drain    UART RX
    //
    //-----------------------------------------------------------------------------
    void PORT_Init (void)
    {
       P0SKIP  |= 0x01;                    // Skip P0.0 for external VREF
       P1MDIN  |= 0xEF;                    // Configure P1.4 as analog input.
       P0MDOUT |= 0x10;                    // enable UTX as push-pull output
       XBR0    = 0x01;                     // Enable UART on P0.4(TX) and P0.5(RX)
       XBR1    = 0x40;                     // Enable crossbar and weak pull-ups
    }
    
    //-----------------------------------------------------------------------------
    // UART0_Init
    //-----------------------------------------------------------------------------
    //
    // Return Value : None
    // Parameters   : None
    //
    // Configure the UART0 using Timer1, for <BAUDRATE> and 8-N-1.
    //
    //-----------------------------------------------------------------------------
    void UART0_Init (void)
    {
       SCON0 = 0x10;                       // SCON0: 8-bit variable bit rate
                                           //        level of STOP bit is ignored
                                           //        RX enabled
                                           //        ninth bits are zeros
                                           //        clear RI0 and TI0 bits
       if (SYSCLK/BAUDRATE/2/256 < 1) {
          TH1 = -(SYSCLK/BAUDRATE/2);
          CKCON &= ~0x0B;                  // T1M = 1; SCA1:0 = xx
          CKCON |=  0x08;
       } else if (SYSCLK/BAUDRATE/2/256 < 4) {
          TH1 = -(SYSCLK/BAUDRATE/2/4);
          CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 01
          CKCON |=  0x09;
       } else if (SYSCLK/BAUDRATE/2/256 < 12) {
          TH1 = -(SYSCLK/BAUDRATE/2/12);
          CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 00
       } else {
          TH1 = -(SYSCLK/BAUDRATE/2/48);
          CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 10
          CKCON |=  0x02;
       }
    
       TL1 = TH1;                          // Init Timer1
       TMOD &= ~0xf0;                      // TMOD: timer 1 in 8-bit autoreload
       TMOD |=  0x20;
       TR1 = 1;                            // START Timer1
       TI0 = 1;                            // Indicate TX0 ready
    }
    
    
    void UART0_ISR (void) interrupt 4 using 3
    {
    	
    	static unsigned char RX_index = 0;				//zwischenspeicher
    
    	if(RI0 == 1)
    	{
    		if(RX_ready != 1)
    		{
    			the_char = SBUF0;
    			/*if (the_char != '\#')
    			RX_buf[RX_index] = the_char;
    			if(RX_index < (RX_length -2))
    			{
    				RX_index++;
    			}
    			else
    			{
    				RX_index = 0;
    				RX_ready = 1;
    				RX_buf[RX_index-1] = '\0';
    			}*/
    			RX_ready = 1;
    
    		}
    		RI0 = 0;
    	}
    
    }
    
    
    void Print_String (char pstring[])
    {
       unsigned char i = 0;
       while (pstring[i])
       {
          putchar(pstring[i++]);
       }
    }
    Grüße!

    Bean

  7. #37
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.07.2006
    Ort
    nähe Rottweil
    Alter
    39
    Beiträge
    240
    So, hallo ich bins nochmal.

    Ich hab den Code jetzt etwas umgeändert um die Zeichen in ein Array zu schreiben. Das Schreiben scheint auch zu funktionieren, da ich über Debugausgaben herasugefunden hab dass er diese Schleife in der ISR abarbeitet. Allerdings soll der Inhalt des Arrays in main an den PC geschickt werden. Das funktioniert leider nicht...

    Hier mal mein aktueller Code für die Variante mit dem Array:

    Code:
    #include <c8051F330.h>
    #include <stdio.h>
    
    #define SYSCLK			24500000
    #define BAUDRATE		115200
    #define RX_length		25
    
    //-----------------------------------------------------------------------------
    // Global Variables
    //-----------------------------------------------------------------------------
    
    //bit TX_ready;						//True = OK zur Übertragung
    //char *TX_ptr;						//pointer auf zu übermittelnden String
    
    bit RX_ready;						//True = string empfangen
    
    volatile char RX_buf[RX_length];				//Array als Eingangsbuffer anlegen
    
    volatile unsigned char the_char;				//zwischenspeicher
    
    
    sfr  SBUF = 0x99;
    
    
    //-----------------------------------------------------------------------------
    // Function Prototypes
    //-----------------------------------------------------------------------------
    
    void OSCILLATOR_Init (void);
    void UART0_Init (void);
    void PORT_Init (void);
    void UART0_ISR (void);
    void Print_String (char pstring[]);
    char nb_getkey ();
    char b_getkey ();
    
    //-----------------------------------------------------------------------------
    // main Routine
    //-----------------------------------------------------------------------------
    void main (void)
    {
    	
    	int i;
    	// Disable Watchdog timer
       	PCA0MD &= ~0x40;                    // WDTE = 0 (clear watchdog timer
                                           // enable)
       	OSCILLATOR_Init ();                 // Initialize Oscillator
    	PORT_Init();                        // Initialize Port I/O
    	UART0_Init ();						// Initialize UART0
    
    	EA = 1;								//Interrupts global freigeben
    	ES0 = 1;							//UART0 interrupt freigeben
    	RI0=0;
    	
    	while(1)
    	{
    		if (RX_ready != 0)
    		{
    			for(i=0;putchar(RX_buf[i])!='\0';i++);
    			RX_ready = 0;
    		}
    		
    		 
    	}
    
    }
    
    //-----------------------------------------------------------------------------
    // Initialization Subroutines
    //-----------------------------------------------------------------------------
    
    //-----------------------------------------------------------------------------
    // OSCILLATOR_Init
    //-----------------------------------------------------------------------------
    //
    // Return Value : None
    // Parameters   : None
    //
    // This routine initializes the system clock to use the internal 24.5MHz
    // oscillator as its clock source.  Also enables missing clock detector reset.
    //
    //-----------------------------------------------------------------------------
    void OSCILLATOR_Init (void)
    {
       OSCICN |= 0x03;                     // Configure internal oscillator for
                                           // its maximum frequency
       RSTSRC  = 0x04;                     // Enable missing clock detector
    }
    
    //-----------------------------------------------------------------------------
    // PORT_Init
    //-----------------------------------------------------------------------------
    //
    // Return Value : None
    // Parameters   : None
    //
    // P0.4    digital    push-pull     UART TX
    // P0.5    digital    open-drain    UART RX
    //
    //-----------------------------------------------------------------------------
    void PORT_Init (void)
    {
       P0SKIP  |= 0x01;                    // Skip P0.0 for external VREF
       P1MDIN  |= 0xEF;                    // Configure P1.4 as analog input.
       P0MDOUT |= 0x10;                    // enable UTX as push-pull output
       XBR0    = 0x01;                     // Enable UART on P0.4(TX) and P0.5(RX)
       XBR1    = 0x40;                     // Enable crossbar and weak pull-ups
    }
    
    //-----------------------------------------------------------------------------
    // UART0_Init
    //-----------------------------------------------------------------------------
    //
    // Return Value : None
    // Parameters   : None
    //
    // Configure the UART0 using Timer1, for <BAUDRATE> and 8-N-1.
    //
    //-----------------------------------------------------------------------------
    void UART0_Init (void)
    {
       SCON0 = 0x10;                       // SCON0: 8-bit variable bit rate
                                           //        level of STOP bit is ignored
                                           //        RX enabled
                                           //        ninth bits are zeros
                                           //        clear RI0 and TI0 bits
       if (SYSCLK/BAUDRATE/2/256 < 1) {
          TH1 = -(SYSCLK/BAUDRATE/2);
          CKCON &= ~0x0B;                  // T1M = 1; SCA1:0 = xx
          CKCON |=  0x08;
       } else if (SYSCLK/BAUDRATE/2/256 < 4) {
          TH1 = -(SYSCLK/BAUDRATE/2/4);
          CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 01
          CKCON |=  0x09;
       } else if (SYSCLK/BAUDRATE/2/256 < 12) {
          TH1 = -(SYSCLK/BAUDRATE/2/12);
          CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 00
       } else {
          TH1 = -(SYSCLK/BAUDRATE/2/48);
          CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 10
          CKCON |=  0x02;
       }
    
       TL1 = TH1;                          // Init Timer1
       TMOD &= ~0xf0;                      // TMOD: timer 1 in 8-bit autoreload
       TMOD |=  0x20;
       TR1 = 1;                            // START Timer1
       TI0 = 1;                            // Indicate TX0 ready
    }
    
    
    void UART0_ISR (void) interrupt 4 using 3
    {
    	
    	unsigned char RX_index = 0;				//zwischenspeicher
    
    	if(RI0 == 1)
    	{
    		
    		if(RX_ready != 1)
    		{
    			the_char = SBUF0;
    			
    			if(the_char != '\n' && ( RX_index < (RX_length-1)) )
    			{
    				
    				RX_buf[RX_index] = the_char;
    				RX_index++;
    				RI0 = 0;
    			}
    			else
    			{
    				RX_buf[RX_index] = '\0';
    				RX_index = 0;
    				RX_ready = 1;
    				RI0 = 0;
    			}
    		}
    	
    	}
    
    }
    Grüße!

    Bean

  8. #38
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    53
    Beiträge
    502
    Dein RX_index wird bei jedem Interruptaufruf auf 0 gesetzt.
    Und wenn du in den else Zweig kommst, wird zwar endlich mal RX_ready aufgerufen, aber du setzt ja vorher den String auf \0

    sast

    雅思特史特芬
    开发及研究

  9. #39
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.07.2006
    Ort
    nähe Rottweil
    Alter
    39
    Beiträge
    240
    Hmm... ja stimmt. Ich will eigenltich als letztes Zeichen nach dem String \0 eintragen. Aber das funkioniert ha nicht wenn ich RX_index immer auf 0 setze. Hab das geändert.

    Wie kann ich den Inhalt eines Arrays ausgeben? Funktioniert das mit printf("%c\n",RX_buf); ? Oder muss ich das in einer Schleife mit putchar machen?

    Grüße!

    Bean

  10. #40
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    53
    Beiträge
    502
    Also die einfachen Sachen solltest du schon allein hinbekommen. Wegen den Formatparametern kannst du ja auch mal ins C51.pdf schauen, was sicher deinem Keilkompiler beiliegt.

    Ansonsten tuts auch nicht weh, wenn man mal was ausprobiert, was dann nicht geht. So schnell kann man die Dinger nicht kaputtprogrammieren ;o)

    sast

    雅思特史特芬
    开发及研究

Seite 4 von 5 ErsteErste ... 2345 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Labornetzteil AliExpress