-         

Ergebnis 1 bis 5 von 5

Thema: Internes USART-Modul des PIC18F252 nutzen

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    01.12.2006
    Beiträge
    25

    Internes USART-Modul des PIC18F252 nutzen

    Anzeige

    Hallo,

    Ich versuche seit einiger Zeit das USART-Modul des PIC18F252 zu nutzen.
    Ich möchte eine Kommunikation zwischen 2 PICs aufbauen.
    Der Sende-PIC scheint dabei richtig zu funktionieren.
    Mit dem Empfangen habe ich noch einige Probleme.
    Ich programmiere mit C.
    Kann mir da jemand helfen?


    Das Sendeprogramm:

    Code:
    //Senden
    #include <P18F252.h>
    
    int ring;
    
    void open_serial (void)
    {
    	// Configure UART serial transmit
            // Configured for:
    	//  9600 Baud
    	//  8N1
    	                             
    	// SPBRG - Baud Rate Generator Register
    	SPBRG = 63; // 20MHz => 9600 baud (BRGH = 0)
    	
    	// BRGH - High Baud Rate Select Bit
    	TXSTAbits.BRGH = 0; // (0 = low speed)
    	
    	// SYNC - USART Mode select Bit
    	TXSTAbits.SYNC = 0; // (0 = asynchronous)
    	
    	// TRISC - Tri-state Data Direction Register for port C
    	// RC6 - 6th pin of port C - used for Serial Transmit
    	// RC7 - 7th pin of port C - used for Serial Receive
    	TRISCbits.TRISC6 = 0; // (0 = pin set as output)
    	TRISCbits.TRISC7 = 1; // (1 = pin set as input)
    	
    	// SPEN - Serial Port Enable Bit 
    	RCSTAbits.SPEN = 1; // (1 = serial port enabled)
    
    	// TXIE - USART Transmit Interupt Enable Bit
    	PIE1bits.TXIE = 0; // (1 = enabled)
    
    	// RCIE - USART Receive Interupt Enable Bit
    	PIE1bits.RCIE = 0; // (1 = enabled)
    	
    	// TX9 - 9-bit Transmit Enable Bit
    	TXSTAbits.TX9 = 0; // (0 = 8-bit transmit)
    	
    	// RX9 - 9-bit Receive Enable Bit
    	RCSTAbits.RX9 = 0; // (0 = 8-bit reception)
    	
    	// CREN - Continuous Receive Enable Bit
    	RCSTAbits.CREN = 0; // (1 = Enables receiver)
    	
    	// TXEN - Trasmit Enable Bit
    	TXSTAbits.TXEN = 1; // (1 = transmit enabled)
    	
    	// GIE - Global Interrupt Enable Bit
    	INTCONbits.GIE = 1; // (1 = Enable all unmasked interrupts)
    	
    	// PEIE - Peripheral Interrupt Enable Bit
    	INTCONbits.PEIE = 1; // (1 = Enable all unmasked peripheral interrupts)
    }
    
    void wait (void)
    {
    int k;
    for(k=0;k<5000;k++);
    }
    
    void main (void)
    {
    ADCON1 = 7;
    LATA = 0x00;
    TRISA = 0x00;
    TRISB = 0xFF;
    ring = 0;
    
    	while(1)
    	{	
    	wait();
    	open_serial();
    	ring = PORTB;
    	PORTA = ring;
    		while(PIR1bits.TXIF)
    		{
    		TXREG = ring;
    		}
    	}
    }
    Das Empfangsprogramm:


    Code:
    //Empfangen
    #include <P18F252.h>
    
    void open_serial(void)
    {
    	// Configure UART serial transmit
            // Configured for:
    	//  9600 Baud
    	//  8N1
    	                             
    	// SPBRG - Baud Rate Generator Register
    	SPBRG = 63; // 20MHz => 9600 baud (BRGH = 0)
    	
    	// BRGH - High Baud Rate Select Bit
    	TXSTAbits.BRGH = 1; // (0 = low speed)
    	
    	// SYNC - USART Mode select Bit
    	TXSTAbits.SYNC = 0; // (0 = asynchronous)
    	
    	// TRISC - Tri-state Data Direction Register for port C
    	// RC6 - 6th pin of port C - used for Serial Transmit
    	// RC7 - 7th pin of port C - used for Serial Receive
    	TRISCbits.TRISC6 = 0; // (0 = pin set as out)
    	TRISCbits.TRISC7 = 1; // (1 = pin set as input)
    	
    	// SPEN - Serial Port Enable Bit 
    	RCSTAbits.SPEN = 1; // (1 = serial port enabled)
    
    	// TXIE - USART Transmit Interupt Enable Bit
    	PIE1bits.TXIE = 0; // (1 = enabled)
    
    	// RCIE - USART Receive Interupt Enable Bit
    	PIE1bits.RCIE = 1; // (1 = enabled)
    	
    	// TX9 - 9-bit Transmit Enable Bit
    	TXSTAbits.TX9 = 0; // (0 = 8-bit transmit)
    	
    	// RX9 - 9-bit Receive Enable Bit
    	RCSTAbits.RX9 = 0; // (0 = 8-bit reception)
    	
    	// CREN - Continuous Receive Enable Bit
    	RCSTAbits.CREN = 1; // (1 = Enables receiver)
    	
    	// TXEN - Trasmit Enable Bit
    	TXSTAbits.TXEN = 0; // (1 = transmit enabled)
    	// GIE - Global Interrupt Enable Bit
    	INTCONbits.GIE = 0; // (1 = Enable all unmasked interrupts)
    	
    	// PEIE - Peripheral Interrupt Enable Bit
    	INTCONbits.PEIE = 1; // (1 = Enable all unmasked peripheral interrupts)
    }
    
    void main (void) 
    {
    TRISB = 0x00;
    PORTB = 0b01010101;
    RCREG = 0;
    open_serial();
    
    	while(1)
    	{	
    		if(PIR1bits.RCIF == 1)
    		{
    		PORTB = RCREG;
    		PIR1bits.RCIF = 0;
    		}
    	}
    }
    Danke für die Hilfe. mfg Adonai

  2. #2
    Hm... Ich habe nichts gefunden im Code, aaaber:
    1) Ist das kabel/die Verbindung ausgekreuzt? (TX -> RX und RX -> TX)
    2) Da ich zu 99.9% annehme, dass du den C18Compiler nutzt, schau doch mal unter Help/Topics/C18 Compiler/Libraries Da drinnen gibts ne softwarelib zum benutzen der Schnittstelle. machts leichter.
    3) Warum eine Serielle schnittstelle?! Das ding hat nen MSSP oben, der kann I2C und SPI. Ist dafür geeigneter...

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    01.12.2006
    Beiträge
    25
    Hallo,

    Das Kabel habe ich gekreuzt. Ich habe das Signal auch gemessen und es liegt am korrekten Pin des (Empfänger-)PICs an.
    Mit den Libraries von C18 komme ich nicht wirklich klar. Ich habe das ein zwei Mal versucht aber bis jetzt bin ich immer gescheitert.
    Warum USART? Schlussendlich soll ein Funkmodul die Kabel ersetzen. Dieses braucht USART.

    mfg Adonai

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    01.12.2006
    Beiträge
    25
    Hallo,

    Meine Methode zur Abfragung des Empfangs-Byte erfolgt mit Polling.
    Ich habe auf www.sprut.de gelesen, dass dies möglich ist.
    Kann es sein dass Sprut sich getäuscht hat und das USART-Modul nur mit den Interrupts funktioniert (beim PIC18F252)?

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    01.12.2006
    Beiträge
    25
    Hallo,

    Hier die Version des Empfangsprogramm mit Interrupts...
    Kommentare fehlen leider, aber ich hoffe es ist einigermassen verständlich.

    Code:
    //Empfangen
    #include <P18F252.h>					//Bibliothek einbinden
    int ring;								//Variable definieren
    void open_serial(void);					//Definition der Unterprogramme
    void initINT (void);					//Definition der Unterprogramme
    void InterruptHandler (void);			//Definition der Unterprogramme
    void InterruptVektor (void);			//Definition der Unterprogramme
    #pragma code InterruptVektor = 0x08		//Vektor für hohe Priorität
    #pragma code
    #pragma interrupt InterruptHandler
    
    void main (void) 
    {
    ADCON1 = 7;								//PORTA digital
    LATA = 0x00;							
    TRISA = 0x00;							//PORTA als Ausgang
    TRISB = 0x00;							//PORTB als Ausgang
    ring = 0;
    RCREG = 90;								//Anfangswert RCREG
    open_serial();							//USART-Modul konfigurieren
    initINT();								//Interrupts konfigurieren
    	while(1)
    	{
    	PORTB = 0xFF;						//PORTB auf High setzen
    	}
    }
    
    void open_serial()
    {
    	SPBRG = 103;						//Baud-Rate
    	TXSTAbits.BRGH = 0; 				//Baud-Rate
    	TXSTAbits.SYNC = 0;					//Asynchrone Übertragung
    	TRISCbits.TRISC6 = 0; 				//RB6 als Ausgang
    	TRISCbits.TRISC7 = 1; 				//RB7 als Ausgang 
    	RCSTAbits.SPEN = 1; 				//Seriellen Port aktivieren 
    	TXSTAbits.TX9 = 0; 					//8-Bit Sendung
    	RCSTAbits.RX9 = 0; 					//8-Bit Empfang
    	RCSTAbits.CREN = 1; 				//Empfänger aktivieren
    	TXSTAbits.TXEN = 0; 				//Sender deaktivieren
    	PIR1bits.PSPIF = 0;					//Laut Datenblatt zu löschen
    	PIE1bits.PSPIE = 0;					//Laut Datenblatt zu löschen
    	IPR1bits.PSPIP = 0;					//Laut Datenblatt zu löschen
    	RCSTAbits.FERR = 0;					//Laut Datenblatt zu löschen
    	RCSTAbits.OERR = 0;					//Laut Datenblatt zu löschen
    }
    
    void initINT()
    {
    PIE1bits.TXIE = 0; 						//Sende-Interrupt deaktivieren
    PIE1bits.RCIE = 1; 						//Empfangs-Interrupt aktivieren
    INTCONbits.GIE = 1; 					//Globale Interrupt-Freigabe
    INTCONbits.PEIE = 1;					//Periphere Interupts freigeben
    RCONbits.IPEN = 1;						//High-Priority Interrupts freigeben
    INTCONbits.GIEH = 1;					//High-Priority Interrupts freigeben
    IPR1bits.RCIP = 1;						//Empfangs-Interrupt erhält hohe Priorität
    }
    
    void InterruptHandler()					//Interrupt-Service-Routine
    {
    INTCONbits.GIE = 0; 					//Interrupts deaktivieren
    PORTB = 0x00;							//PORTB löschen (zeigt dass Interrupt ausgelöst wird)
    PORTA = RCREG;							//Empfnags-Buffer auslesen
    PIR1bits.RCIF = 0;						//Flag des Empfangs-Interrupt löschen
    INTCONbits.GIE = 1; 					//Interrupts wieder aktivieren
    }
    
    void InterruptVektor (void)				//Interrupt-Vektor festlegen
    {
    _asm
    	goto InterruptHandler
     _endasm
    }
    edit: Zum besseren Verständnis habe ich noch Kommentare hinzugefügt.

Berechtigungen

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