- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 1 von 5 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 49

Thema: UART mit dem F330 von SiLabs

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

    UART mit dem F330 von SiLabs

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo

    Ich hoffe ihr könnt mir weiter helfen. Ich möchte mit dem F330 von SiLabs eine RS232 Kommunikation aufbauen. Ich habe dazu folgendes Programm geschrieben:

    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
    unsigned char the_char;				//zwischenspeicher
    
    //-----------------------------------------------------------------------------
    // Function Prototypes
    //-----------------------------------------------------------------------------
    
    void OSCILLATOR_Init (void);
    void UART0_Init (void);
    void PORT_Init (void);
    void UART0_ISR (void);
    void Print_String (char pstring[]);
    
    //-----------------------------------------------------------------------------
    // 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 = 0;								//Interrupts global freigeben
    	ES0 = 1;							//UART0 interrupt freigeben
    
    	while (1)
    	{
    		
    	}
    }
    
    
    //-----------------------------------------------------------------------------
    // 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;	//receive buffer index
    	unsigned char the_char;				//zwischenspeicher
    	
    	Print_String ("In ISR...");			//Debugausgabe auf UART 
    	RI0 = 0;
    	if (RI0=1)
    	{
    		
    		the_char = SBUF0;
    		RX_buf[RX_index] = the_char;	//Byte in array speichern
    		
    
    		if(RX_index < (RX_length-2))
    		{
    			RX_index++;
    		}
    		else
    		{
    			RX_index = 0;
    			RX_ready = 1;
    			RX_buf[RX_index-1] = '\0';
    		}
    		
    
    	}
    }
    
    void Print_String (char pstring[])
    {
       unsigned char i = 0;
       while (pstring[i])
       {
          putchar(pstring[i++]);
       }
    }
    Das Senden eines Strings funktioniert auch schon gut. Ich möchte nun aber auch einen String einlesen, speichern und je nach dem was für Kommandos angekommen sind eine Aktion ausführen.
    Im Moment sieht es so aus als wenn der Controller nicht einmal in die UART ISR springt. Um das zu überprüfen gebe ich den Text "In ISR..." aus. Der Text wird ausgegeben wenn ich in main das Bit RI0 manuell setze. Eigentlich sollte das Bit automatisch gesetzt werden wenn ein byte vom PC empfangen wurde.
    Wie gesagt, das Senden von Text an den PC funtkioniert. Liegt also denke ich nicht an der Baudrate oder gleichen. Probier jetzt schon ne ganze Weile rum, komme aber nicht weiter. Hoffe ihr habt eine Idee.

    Grüße!

    Bean

  2. #2
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    53
    Beiträge
    502
    RI0 = 0;
    if (RI0=1)
    { ...

    wie soll da RI0 jemals 1 sein, wenn du es vorher auf 0 setzt? Außerdem ist in C der Vergleich ==

    sast

    edit:
    Versuche es doch erst mal ohne Interrupt mit

    Code:
    sfr  SBUF = 0x99;
    sbit RI   = 0x98;
    
    char nb_getkey ()  
    {
       char c;
       int i;
    
       while(!RI && i++<100);
       if(RI)
       {
          c = SBUF;
          RI = 0;
       }
       else
          c = '\3';
       return (c);
    }
    char b_getkey ()  
    {
       char c;
    
       while (!RI);
       c = SBUF;
       RI = 0;
       return (c);
    }
    und Aufruf von b_getkey() oder nb_getkey() in der while(1){}. Ich bin mir nicht mehr sicher, ob du nicht auch EA=1 setzen musst. Ist schon mind. 4 Jahre her, dass ich was mit dem F300 gemacht hatte. Ich hoffe die defines stimmen, ansonsten anpassen.

    Und das print würde ich aus der Interruptroutine nehmen.

    雅思特史特芬
    开发及研究

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    11.08.2005
    Beiträge
    178
    hallo,

    ev. hilft das weiter:
    http://read.pudn.com/downloads35/sou...0_Int1.c__.htm ab zeile 194

    lg
    "A robot with guns for arms shooting a plane made out of guns that fires guns" - Nelson Muntz

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

    Danke für die Antworten!
    @sast:
    Ich setzte RI0 ja erst in der ISR wieder auf 0. Das muss ich ja auch weil das Bit ja nicht von der Hardware zurückgesetzt wird oder? In main warte ich in der whileschleife auf einen Interrupt. Wenn der kommt gehe ich zu UART_ISR. Dort setzte ich das Bit zurück. So war mal mein PLan. Du hast recht, so komme ich nie in die if Schleife, aber in die ISR sollte ich so schon kommen. Und den String gebe ich ja vor der if Schleife aus. Kann natürlich sein dass ich falsch liege.
    EA hab ich auch auf 1 gesetzt.

    @johns:
    Danke für den Link, das Dokument kenne ich auch schon. Hat bei mir aber so auch nicht funktioniert, denke das liegt daran dass dieses C-Beispiel für einen anderen (kleineren) Prozessor von SiLabs ist.

    Vielleicht habt ihr ja noch ein paar Ideen, ich versuch derweil mal weiter.

    MFG

    Bean

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

    >>EA = 0; //Interrupts global freigeben
    >> ES0 = 1; //UART0 interrupt freigeben

    falsch, EA muß auch 1 sein, bei 0 wird gesperrt!

    >>In main warte ich in der whileschleife auf einen Interrupt.
    >>Wenn der kommt gehe ich zu UART_ISR

    was soll denn das werden? Entweder Polling von RI und dann Zeichen von UART abholen oder die ISR schiebt das Zeichen von der UART in den Rx-Buffer.

    >>Beispiel für einen anderen (kleineren) Prozessor
    da alle 8051ziger bei UART gleich arbeiten spielt der Prozessor keine Rolle.

    mfg
    Peter

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

    Ja da hast natürlich recht, die Interrupts muss ich mit 1 global freigeben. Da hat sich bei dem Rumprobieren wohl eine 0 eingeschlichen. Bringt aber auch keine Änderung. Außer dass ich, wenn ich die Interrupts global freigebe und danach ES0=1 setzte sofort in die ISR gesprungen wird. Das erkenne ich daran dass auf meinem Terminal ständig "In ISR...." ausgegeben wird. Kommentiere ich diese Zeile mit ES0 aus, passiert das nichtmehr, ich komme dann aber auch nicht in die ISR wenn ich ein Zeichen an den Controller schicke...

    Die SFR können doch schon von Controller zu Controller unterschiedlich sein oder?

    Grüße!

    Bean

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.07.2006
    Ort
    nähe Rottweil
    Alter
    39
    Beiträge
    240
    Was ich mir ja auch noch vorstellen könnte ist dass die interrupt quelle (interrupt 4 using 3) nicht passt. Das wurde nämlich von mir auch aus dem C-example übernommen. Wisst ihr da noch was?

    Grüße!

    Bean

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

    SFR..nur wenn 2 UARTS drin sind.
    Probiere mal eine reine Echofunktion.
    Bin allerdings Assemblerfreak, in C muss nicht alles stimmen:

    (all init)
    loop:
    while !(RI); //warte auf zeichen
    Tx = 0; // Tx auf leer setzen
    SBUF = SBUF; //umladen von Rx nach Tx und senden
    goto loop;

    Nun sollte alle Zeichen am Terminal als Echo erscheinen.

    mfg
    Peter

  9. #9
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    08.04.2009
    Ort
    an der Ostsee
    Beiträge
    334
    Nachtrag:
    REN=1; // Set REN of SCON to Enable UART Receive

  10. #10
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    53
    Beiträge
    502
    Also dein interrupt 4 stimmt schon mal, wenn man dem Datenblatt (Seite 90)glauben kann. Mit dem using von Registerbanken kenne ich mich nicht aus, da nie benutzt.

    Wie auch Peter geschrieben hat, noch mal der Hinweis, es erst mal ohne Interrupt zu versuchen. Taste dich langsam ran. Hab ja weiter oben den Code für meine F300 reingestellt.

    Hast du überhaupt das Datenblatt zum F330 von Silabs? Da steht eigentlich alles drin was du wissen musst. Wenn nicht dann lad es dir von www.silabs.com mal runter. Ohne wirst du den nicht beherrschen.

    Zu deinem Code vom Anfangscode ist mir noch was aufgefallen:

    ...else
    {
    RX_index = 0;
    RX_ready = 1;
    RX_buf[RX_index-1] = '\0';
    ...

    Wieviel ist denn 0-1 bei unsigned char? So ein Controller arbeitet schön der Reihe nach durch, wenn er nicht gerade von einem Interrupt unterbrochen wird. Du solltest also zuerst den String abschließen und dann den Index zurücksetzen. Das ist genau wie bei deiner RI Abfrage. Wenn du immer vorher den Wert von Hand neu setzt musst du ihn doch danach nicht abfragen

    sast

    雅思特史特芬
    开发及研究

Seite 1 von 5 123 ... LetzteLetzte

Berechtigungen

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

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad