- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Ergebnis 1 bis 7 von 7

Thema: SRF02 über UART programmieren

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    08.05.2007
    Beiträge
    27

    SRF02 über UART programmieren

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hi,

    hat jemand von euch den Code für SRF02 über UART programmieren.

    Ich habe einen Code geschrieben aber der hat leider nicht funktioniert. Ich verwendet ein ATmega128 mit 2 UART. Das erste habe ich zum Debug vervendet. An den zweite habe ich den Ultraschallsensor angeschloßen (selbstverständlich an TTL 5V). Die Funktionen zum Ansprechen des Sensor und Bearbeitung der Daten wurde in main(Ultraschallsensor.c) und in einer Schleife aufgerufen.
    Code:
    #include "Ultraschallsensor.h"
    #include "uart1.h"
    unsigned volatile char SioTmp1 = 0;
    
    unsigned volatile char SendeBuffer1[MAX_SENDE_BUFF1];
    unsigned volatile char RxdBuffer1[MAX_EMPFANGS_BUFF1];
    
    unsigned volatile char NeuerDatensatzEmpfangen1 = 0;
    unsigned volatile char AnzahlEmpfangsBytes1 = 0;
    unsigned volatile int  wandabstand;
    unsigned volatile char UebertragungAbgeschlossen1 = 1;
    
    void Sensoranforderung(void);
    
    
    
    
    
    unsigned volatile int test1=0;
    
    //############################################################################
    //INstallation der Seriellen Schnittstelle
    
    
    
    
    void UART1_Init (void)
    //############################################################################
    {
        //Teiler wird gesetzt UBRR=UBRR0L Siehe Seite 174 von Atmega 644P wegen des Double Speed Modus
    	
    	uint8_t sreg = SREG;
    	uint16_t ubrr = (unsigned int) ((unsigned long) F_CPU/(8 * BAUD_RATE1) - 1);
    	cli();
    
    	// disable RX-Interrupt
    	UCSR1B &= ~(1 << RXCIE1);
    	// disable TX-Interrupt
    	UCSR1B &= ~(1 << TXCIE1);
    	// disable DRE-Interrupt
    	UCSR1B &= ~(1 << UDRIE1);
    
    	// set direction of RXD1 and TXD1 pins
    	// set RXD1 (PD2) as an input pin
    	PORTD |= (1 << PORTD2);
    	DDRD &= ~(1 << DDD2);
        
    	// set TXD1 (PD3) as an output pin
    	PORTD |= (1 << PORTD3);
    	DDRD  |= (1 << DDD3);
        
    	// USART0 Baud Rate Register
    	// set clock divider
    	UBRR1H = (uint8_t)(ubrr>>8);
    	UBRR1L = (uint8_t)ubrr;
    
        // enable double speed operation
    	// UCSR1A |= (1 << U2X1);
    	// enable receiver and transmitter
    	UCSR1B = (1 << TXEN1) | (1 << RXEN1);
    	// set asynchronous mode
    	UCSR1C &= ~(1 << UMSEL1);
    	
    	// no parity
    	UCSR1C &= ~(1 << UPM11);
    	UCSR1C &= ~(1 << UPM10);
    	// 2 stop bit
    	UCSR1C |= (1 << USBS1);
    	//UCSR1C &= ~ (1 << USBS1);
    	// 8-bit
    	UCSR1B &= ~(1 << UCSZ12);
    	UCSR1C |=  (1 << UCSZ11);
    	UCSR1C |=  (1 << UCSZ10);
    
    	// flush receive buffer explicit
    	while ( UCSR1A & (1<<RXC1) ) UDR1;
    
    	// enable interrupts at the end
    	// enable RX-Interrupt
    	UCSR1B |= (1 << RXCIE1);
    	// enable TX-Interrupt
    	UCSR1B |= (1 << TXCIE1);
    	// enable DRE interrupt
    	//UCSR1B |= (1 << UDRIE1);
    
    	// restore global interrupt flags
        SREG = sreg;
    	
    	/*
    	UCSR1B=(1 << TXEN1) | (1 << RXEN1);
        // UART Double Speed (U2X) USR=UCSR0A
    	UCSR1A   |= (1<<U2X1);           
    	// RX-Interrupt Freigabe
    	UCSR1B |= (1<<RXCIE1);           
    	// TX-Interrupt Freigabe
    	UCSR1B |= (1<<TXCIE1);   
    	UBRR1L=(F_CPU / (BAUD_RATE1 * 8L) - 1);
            
        */
    	
    	
     }
    
    //---------------------*********--------------------------------//
    // Weitere Befehl an Sensordaten senden 
     //ISR(SIG_USART1_DATA)
     ISR(SIG_USART1_TRANS)//USART1_TX_vect)
    
    {
     static unsigned int ptr = 0;
     unsigned char tmp_tx;
     if(!UebertragungAbgeschlossen1)  
      {
       ptr++;                    // die [0] wurde schon gesendet
       tmp_tx = SendeBuffer1[ptr]; 
       
       if((tmp_tx == 84) || (ptr == MAX_SENDE_BUFF1))
        {
         ptr = 0;
         UebertragungAbgeschlossen1 = 1;
    	 
        }
       UDR1 = tmp_tx; //Put data in the buffer ,sends the data
       uart_puts("In Sendenvorgang springen \n"); 
      } 
      else ptr = 0;
    
    } 
     
    
    //---------------------*********--------------------------------//
    // Sensordaten empfangen
     ISR(SIG_USART1_RECV)     //USART1_RX_vect
     {
     static unsigned char buf_ptr;
     
      
     uart_puts("Empfangsvorgang springen \n"); 
     SioTmp1 = UDR1; 
    // test1++;
    //test1 = SioTmp1;
    
    //  alte Daten schon verarbeitet
     if(!NeuerDatensatzEmpfangen1)
    	  {
    	   NeuerDatensatzEmpfangen1=1;
    	  
    	  }	
    // Buffer voll 
     if  (buf_ptr==MAX_EMPFANGS_BUFF1)
          
          {
           buf_ptr=0;
    	  }
    // Datenbytes des Ultraschalls im Buffer speichern
     RxdBuffer1[buf_ptr++] = SioTmp1; 
    	
    //test1 = SioTmp1;  
     }
    
    
    
    
    //---------------------*********--------------------------------//
    
    void Sensoranforderung(void)
    {
    
    // Packen Daten in Buffer, sendet Daten
      //Übertragungvorgang noch nicht abgeschlossen -> nichts weitere übertragen
      if(!UebertragungAbgeschlossen1) return;
      //Messen in centimeter
      SendeBuffer1[1]=84;
      //ID von Sensor aufrufen
      SendeBuffer1[0]=4;
      //erste Byte im Buffer senden, gleichzeitig wird ISR vom UART1 für Senden aktiviert
      UebertragungAbgeschlossen1=0;
      
      UDR1 = SendeBuffer1[0];
      
      uart_putc(SendeBuffer1[0]);
    
    }  
     
     
     
     void BearbeiteRxDaten1(void)
    {
     
     if(!NeuerDatensatzEmpfangen1) return;
      
      wandabstand =   RxdBuffer1[1];
      wandabstand =+ RxdBuffer1[0]<<8;
      NeuerDatensatzEmpfangen1 = 0;
      
     }
    Ich habe den Mustercode im Bascom ausprobiert und es hat funktioniert. Das heißt, es Fehler bei meinem Code gibt. Ich habe ein paar Zeil über andere UART zum Debug übertragen und mit Terminalprogramm angeschaut. Die ISR Receive wird niemals hineingesprungen.Der Ultraschallsensor funktioniert unter UART Modus mit Baudrate 9600,8 Data Bit, 2 Stop Bit.

    Kann jemand von euch mir helfen?

    Viele Grüsse

  2. #2
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Die ISR Receive wird niemals hineingesprungen.
    Woher weißt du das?
    Etwa weil der Text "Empfangsvorgang springen" über die Debug-Schnittstelle nicht angezeigt wird? Dazu müsste man mal den Code dieser Debug-Schnittstelle sehen, denn wenn dort das Senden ebenfalls per Interrupt passiert, hast du dir die Möglichkeit für einen Deadlock geschaffen.

    Außerdem: die Funktion zum Senden eines Strings über die Debug-Schnittstelle heißt "uart_puts", und die zum Senden eines Zeichens über die Sensor-Schnittstelle "uart_putc"? Da ist doch auch was nicht koscher. Ich wette, die Funktion "uart_putc" gehört ebenfalls zur Debug-Schnittstelle.
    MfG
    Stefan

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    08.05.2007
    Beiträge
    27
    Hi,
    Klar die Funktion uart_putc gehört zur Debug-Schnittstelle. Ich habe nur ein Byte, das gerade gesendet, angezeigt auf dem Bildschirm gelassen. Was meinst du mit deadlock ? Ich habe UART ,d.h. 2 getrennte Leitungen, verwendet.

    Mit freundlichen Grüssen

  4. #4
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Zitat Zitat von tranh85bo
    Klar die Funktion uart_putc gehört zur Debug-Schnittstelle.
    Sorry, habe die Zeile davor ("UDR1 = SendeBuffer1[0];") übersehen. Ich dachte das "uart_putc(SendeBuffer1[0]);" sollte das Senden des ersten Zeichens an den Sensor sein (was ja aber die Zeile davor erledigt).
    Zitat Zitat von tranh85bo
    Was meinst du mit deadlock ? Ich habe UART ,d.h. 2 getrennte Leitungen, verwendet.
    Ich meine einen Deadlock auf der Software-Ebene. Zeige doch mal bitte den kompletten Debug-Schnittstellen-Code. Wenn du einen Deadlock hast, dann kann ich dir das an dem konkreten Beispiel erklären, statt dass ich hier jetzt theoretische (und möglicherweise unnötige) Erklärungen abgebe.
    MfG
    Stefan

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    08.05.2007
    Beiträge
    27
    Hi,

    Sorry,dass ich zu spät anworte. Ich habe den Code von peterfleury verwendet im Debug-Code. Ich habe schon vorher ohne Debug-Code versucht aber es ging auch nicht. Deswegen habe ich den Debug-Code zugefügt. Hier ist der Code von Debug
    Code:
    /*************************************************************************
    Title:    Interrupt UART library with receive/transmit circular buffers
    Author:   Peter Fleury <pfleury@gmx.ch>   http://jump.to/fleury
    File:     $Id: uart.c,v 1.6.2.1 2007/07/01 11:14:38 peter Exp $
    Software: AVR-GCC 4.1, AVR Libc 1.4.6 or higher
    Hardware: any AVR with built-in UART, 
    License:  GNU General Public License 
              
    DESCRIPTION:
        An interrupt is generated when the UART has finished transmitting or
        receiving a byte. The interrupt handling routines use circular buffers
        for buffering received and transmitted data.
        
        The UART_RX_BUFFER_SIZE and UART_TX_BUFFER_SIZE variables define
        the buffer size in bytes. Note that these variables must be a 
        power of 2.
        
    USAGE:
        Refere to the header file uart.h for a description of the routines. 
        See also example test_uart.c.
    
    NOTES:
        Based on Atmel Application Note AVR306
                        
    LICENSE:
        Copyright (C) 2006 Peter Fleury
    
        This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation; either version 2 of the License, or
        any later version.
    
        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.
                            
    *************************************************************************/
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/pgmspace.h>
    #include "uart.h"
    
    #include <avr/signal.h>
    /*
     *  constants and macros
     */
    
    /* size of RX/TX buffers */
    #define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1)
    #define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1)
    
    #if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK )
    #error RX buffer size is not a power of 2
    #endif
    #if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK )
    #error TX buffer size is not a power of 2
    #endif
    
    #if defined(__AVR_AT90S2313__) \
     || defined(__AVR_AT90S4414__) || defined(__AVR_AT90S4434__) \
     || defined(__AVR_AT90S8515__) || defined(__AVR_AT90S8535__) \
     || defined(__AVR_ATmega103__)
     /* old AVR classic or ATmega103 with one UART */
     #define AT90_UART
     #define UART0_RECEIVE_INTERRUPT   SIG_UART_RECV
     #define UART0_TRANSMIT_INTERRUPT  SIG_UART_DATA
     #define UART0_STATUS   USR
     #define UART0_CONTROL  UCR
     #define UART0_DATA     UDR  
     #define UART0_UDRIE    UDRIE
    #elif defined(__AVR_AT90S2333__) || defined(__AVR_AT90S4433__)
     /* old AVR classic with one UART */
     #define AT90_UART
     #define UART0_RECEIVE_INTERRUPT   SIG_UART_RECV
     #define UART0_TRANSMIT_INTERRUPT  SIG_UART_DATA
     #define UART0_STATUS   UCSRA
     #define UART0_CONTROL  UCSRB
     #define UART0_DATA     UDR 
     #define UART0_UDRIE    UDRIE
    #elif  defined(__AVR_ATmega8__)  || defined(__AVR_ATmega16__) || defined(__AVR_ATmega32__) \
      || defined(__AVR_ATmega8515__) || defined(__AVR_ATmega8535__) \
      || defined(__AVR_ATmega323__)
      /* ATmega with one USART */
     #define ATMEGA_USART
     #define UART0_RECEIVE_INTERRUPT   SIG_UART_RECV
     #define UART0_TRANSMIT_INTERRUPT  SIG_UART_DATA
     #define UART0_STATUS   UCSRA
     #define UART0_CONTROL  UCSRB
     #define UART0_DATA     UDR
     #define UART0_UDRIE    UDRIE
    #elif defined(__AVR_ATmega163__) 
      /* ATmega163 with one UART */
     #define ATMEGA_UART
     #define UART0_RECEIVE_INTERRUPT   SIG_UART_RECV
     #define UART0_TRANSMIT_INTERRUPT  SIG_UART_DATA
     #define UART0_STATUS   UCSRA
     #define UART0_CONTROL  UCSRB
     #define UART0_DATA     UDR
     #define UART0_UDRIE    UDRIE
    #elif defined(__AVR_ATmega162__) 
     /* ATmega with two USART */
     #define ATMEGA_USART0
     #define ATMEGA_USART1
     #define UART0_RECEIVE_INTERRUPT   SIG_USART0_RECV
     #define UART1_RECEIVE_INTERRUPT   SIG_USART1_RECV
     #define UART0_TRANSMIT_INTERRUPT  SIG_USART0_DATA
     #define UART1_TRANSMIT_INTERRUPT  SIG_USART1_DATA
     #define UART0_STATUS   UCSR0A
     #define UART0_CONTROL  UCSR0B
     #define UART0_DATA     UDR0
     #define UART0_UDRIE    UDRIE0
     #define UART1_STATUS   UCSR1A
     #define UART1_CONTROL  UCSR1B
     #define UART1_DATA     UDR1
     #define UART1_UDRIE    UDRIE1
    #elif defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__) 
     /* ATmega with two USART */
     #define ATMEGA_USART0
     #define ATMEGA_USART1
     #define UART0_RECEIVE_INTERRUPT   SIG_UART0_RECV
     #define UART1_RECEIVE_INTERRUPT   SIG_UART1_RECV
     #define UART0_TRANSMIT_INTERRUPT  SIG_UART0_DATA
     #define UART1_TRANSMIT_INTERRUPT  SIG_UART1_DATA
     #define UART0_STATUS   UCSR0A
     #define UART0_CONTROL  UCSR0B
     #define UART0_DATA     UDR0
     #define UART0_UDRIE    UDRIE0
     #define UART1_STATUS   UCSR1A
     #define UART1_CONTROL  UCSR1B
     #define UART1_DATA     UDR1
     #define UART1_UDRIE    UDRIE1
    #elif defined(__AVR_ATmega161__)
     /* ATmega with UART */
     #error "AVR ATmega161 currently not supported by this libaray !"
    #elif defined(__AVR_ATmega169__) 
     /* ATmega with one USART */
     #define ATMEGA_USART
     #define UART0_RECEIVE_INTERRUPT   SIG_USART_RECV
     #define UART0_TRANSMIT_INTERRUPT  SIG_USART_DATA
     #define UART0_STATUS   UCSRA
     #define UART0_CONTROL  UCSRB
     #define UART0_DATA     UDR
     #define UART0_UDRIE    UDRIE
    #elif defined(__AVR_ATmega48__) ||defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__)
     /* ATmega with one USART */
     #define ATMEGA_USART0
     #define UART0_RECEIVE_INTERRUPT   SIG_USART_RECV
     #define UART0_TRANSMIT_INTERRUPT  SIG_USART_DATA
     #define UART0_STATUS   UCSR0A
     #define UART0_CONTROL  UCSR0B
     #define UART0_DATA     UDR0
     #define UART0_UDRIE    UDRIE0
    #elif defined(__AVR_ATtiny2313__)
     #define ATMEGA_USART
     #define UART0_RECEIVE_INTERRUPT   SIG_USART0_RX 
     #define UART0_TRANSMIT_INTERRUPT  SIG_USART0_UDRE
     #define UART0_STATUS   UCSRA
     #define UART0_CONTROL  UCSRB
     #define UART0_DATA     UDR
     #define UART0_UDRIE    UDRIE
    #elif defined(__AVR_ATmega329__) ||defined(__AVR_ATmega3290__) ||\
          defined(__AVR_ATmega649__) ||defined(__AVR_ATmega6490__) ||\
          defined(__AVR_ATmega325__) ||defined(__AVR_ATmega3250__) ||\
          defined(__AVR_ATmega645__) ||defined(__AVR_ATmega6450__)
      /* ATmega with one USART */
      #define ATMEGA_USART0
      #define UART0_RECEIVE_INTERRUPT   SIG_UART_RECV
      #define UART0_TRANSMIT_INTERRUPT  SIG_UART_DATA
      #define UART0_STATUS   UCSR0A
      #define UART0_CONTROL  UCSR0B
      #define UART0_DATA     UDR0
      #define UART0_UDRIE    UDRIE0
    #elif defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega640__)
    /* ATmega with two USART */
      #define ATMEGA_USART0
      #define ATMEGA_USART1
      #define UART0_RECEIVE_INTERRUPT   SIG_USART0_RECV
      #define UART1_RECEIVE_INTERRUPT   SIG_USART1_RECV
      #define UART0_TRANSMIT_INTERRUPT  SIG_USART0_DATA
      #define UART1_TRANSMIT_INTERRUPT  SIG_USART1_DATA
      #define UART0_STATUS   UCSR0A
      #define UART0_CONTROL  UCSR0B
      #define UART0_DATA     UDR0
      #define UART0_UDRIE    UDRIE0
      #define UART1_STATUS   UCSR1A
      #define UART1_CONTROL  UCSR1B
      #define UART1_DATA     UDR1
      #define UART1_UDRIE    UDRIE1  
    #elif defined(__AVR_ATmega644__)
     /* ATmega with one USART */
     #define ATMEGA_USART0
     #define UART0_RECEIVE_INTERRUPT   SIG_USART_RECV
     #define UART0_TRANSMIT_INTERRUPT  SIG_USART_DATA
     #define UART0_STATUS   UCSR0A
     #define UART0_CONTROL  UCSR0B
     #define UART0_DATA     UDR0
     #define UART0_UDRIE    UDRIE0
    #elif defined(__AVR_ATmega164P__) || defined(__AVR_ATmega324P__) || defined(__AVR_ATmega644P__)
     /* ATmega with two USART */
     #define ATMEGA_USART0
     #define ATMEGA_USART1
     #define UART0_RECEIVE_INTERRUPT   SIG_USART_RECV
     #define UART1_RECEIVE_INTERRUPT   SIG_USART1_RECV
     #define UART0_TRANSMIT_INTERRUPT  SIG_USART_DATA
     #define UART1_TRANSMIT_INTERRUPT  SIG_USART1_DATA
     #define UART0_STATUS   UCSR0A
     #define UART0_CONTROL  UCSR0B
     #define UART0_DATA     UDR0
     #define UART0_UDRIE    UDRIE0
     #define UART1_STATUS   UCSR1A
     #define UART1_CONTROL  UCSR1B
     #define UART1_DATA     UDR1
     #define UART1_UDRIE    UDRIE1
    #else
     #error "no UART definition for MCU available"
    #endif
    
    
    /*
     *  module global variables
     */
    static volatile unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE];
    static volatile unsigned char UART_RxBuf[UART_RX_BUFFER_SIZE];
    static volatile unsigned char UART_TxHead;
    static volatile unsigned char UART_TxTail;
    static volatile unsigned char UART_RxHead;
    static volatile unsigned char UART_RxTail;
    static volatile unsigned char UART_LastRxError;
    
    #if defined( ATMEGA_USART1 )
    static volatile unsigned char UART1_TxBuf[UART_TX_BUFFER_SIZE];
    static volatile unsigned char UART1_RxBuf[UART_RX_BUFFER_SIZE];
    static volatile unsigned char UART1_TxHead;
    static volatile unsigned char UART1_TxTail;
    static volatile unsigned char UART1_RxHead;
    static volatile unsigned char UART1_RxTail;
    static volatile unsigned char UART1_LastRxError;
    #endif
    
    
    
    SIGNAL(UART0_RECEIVE_INTERRUPT)
    /*************************************************************************
    Function: UART Receive Complete interrupt
    Purpose:  called when the UART has received a character
    **************************************************************************/
    {
        unsigned char tmphead;
        unsigned char data;
        unsigned char usr;
        unsigned char lastRxError;
     
     
        /* read UART status register and UART data register */ 
        usr  = UART0_STATUS;
        data = UART0_DATA;
        
        /* */
    #if defined( AT90_UART )
        lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
    #elif defined( ATMEGA_USART )
        lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
    #elif defined( ATMEGA_USART0 )
        lastRxError = (usr & (_BV(FE0)|_BV(DOR0)) );
    #elif defined ( ATMEGA_UART )
        lastRxError = (usr & (_BV(FE)|_BV(DOR)) );
    #endif
            
        /* calculate buffer index */ 
        tmphead = ( UART_RxHead + 1) & UART_RX_BUFFER_MASK;
        
        if ( tmphead == UART_RxTail ) {
            /* error: receive buffer overflow */
            lastRxError = UART_BUFFER_OVERFLOW >> 8;
        }else{
            /* store new index */
            UART_RxHead = tmphead;
            /* store received data in buffer */
            UART_RxBuf[tmphead] = data;
        }
        UART_LastRxError = lastRxError;   
    }
    
    
    SIGNAL(UART0_TRANSMIT_INTERRUPT)
    /*************************************************************************
    Function: UART Data Register Empty interrupt
    Purpose:  called when the UART is ready to transmit the next byte
    **************************************************************************/
    {
        unsigned char tmptail;
    
        
        if ( UART_TxHead != UART_TxTail) {
            /* calculate and store new buffer index */
            tmptail = (UART_TxTail + 1) & UART_TX_BUFFER_MASK;
            UART_TxTail = tmptail;
            /* get one byte from buffer and write it to UART */
            UART0_DATA = UART_TxBuf[tmptail];  /* start transmission */
        }else{
            /* tx buffer empty, disable UDRE interrupt */
            UART0_CONTROL &= ~_BV(UART0_UDRIE);
        }
    }
    
    
    /*************************************************************************
    Function: uart_init()
    Purpose:  initialize UART and set baudrate
    Input:    baudrate using macro UART_BAUD_SELECT()
    Returns:  none
    **************************************************************************/
    void uart_init(unsigned int baudrate)
    {
        UART_TxHead = 0;
        UART_TxTail = 0;
        UART_RxHead = 0;
        UART_RxTail = 0;
        
    #if defined( AT90_UART )
        /* set baud rate */
        UBRR = (unsigned char)baudrate; 
    
        /* enable UART receiver and transmmitter and receive complete interrupt */
        UART0_CONTROL = _BV(RXCIE)|_BV(RXEN)|_BV(TXEN);
    
    #elif defined (ATMEGA_USART)
        /* Set baud rate */
        if ( baudrate & 0x8000 )
        {
        	 UART0_STATUS = (1<<U2X);  //Enable 2x speed 
        	 baudrate &= ~0x8000;
        }
        UBRRH = (unsigned char)(baudrate>>8);
        UBRRL = (unsigned char) baudrate;
       
        /* Enable USART receiver and transmitter and receive complete interrupt */
        UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
        
        /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
        #ifdef URSEL
        UCSRC = (1<<URSEL)|(3<<UCSZ0);
        #else
        UCSRC = (3<<UCSZ0);
        #endif 
        
    #elif defined (ATMEGA_USART0 )
        /* Set baud rate */
        if ( baudrate & 0x8000 ) 
        {
       		UART0_STATUS = (1<<U2X0);  //Enable 2x speed 
       		baudrate &= ~0x8000;
       	}
        UBRR0H = (unsigned char)(baudrate>>8);
        UBRR0L = (unsigned char) baudrate;
    
        /* Enable USART receiver and transmitter and receive complete interrupt */
        UART0_CONTROL = _BV(RXCIE0)|(1<<RXEN0)|(1<<TXEN0);
        
        /* Set frame format: asynchronous, 8data, no parity, 1stop bit */
        #ifdef URSEL0
        UCSR0C = (1<<URSEL0)|(3<<UCSZ00);
        #else
        UCSR0C = (3<<UCSZ00);
        #endif 
    
    #elif defined ( ATMEGA_UART )
        /* set baud rate */
        if ( baudrate & 0x8000 ) 
        {
        	UART0_STATUS = (1<<U2X);  //Enable 2x speed 
        	baudrate &= ~0x8000;
        }
        UBRRHI = (unsigned char)(baudrate>>8);
        UBRR   = (unsigned char) baudrate;
    
        /* Enable UART receiver and transmitter and receive complete interrupt */
        UART0_CONTROL = _BV(RXCIE)|(1<<RXEN)|(1<<TXEN);
    
    #endif
    
    }/* uart_init */
    
    
    /*************************************************************************
    Function: uart_getc()
    Purpose:  return byte from ringbuffer  
    Returns:  lower byte:  received byte from ringbuffer
              higher byte: last receive error
    **************************************************************************/
    unsigned int uart_getc(void)
    {    
        unsigned char tmptail;
        unsigned char data;
    
    
        if ( UART_RxHead == UART_RxTail ) {
            return UART_NO_DATA;   /* no data available */
        }
        
        /* calculate /store buffer index */
        tmptail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK;
        UART_RxTail = tmptail; 
        
        /* get data from receive buffer */
        data = UART_RxBuf[tmptail];
        
        return (UART_LastRxError << 8) + data;
    
    }/* uart_getc */
    
    
    /*************************************************************************
    Function: uart_putc()
    Purpose:  write byte to ringbuffer for transmitting via UART
    Input:    byte to be transmitted
    Returns:  none          
    **************************************************************************/
    void uart_putc(unsigned char data)
    {
        unsigned char tmphead;
    
        
        tmphead  = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
        
        while ( tmphead == UART_TxTail ){
            ;/* wait for free space in buffer */
        }
        
        UART_TxBuf[tmphead] = data;
        UART_TxHead = tmphead;
    
        /* enable UDRE interrupt */
        UART0_CONTROL    |= _BV(UART0_UDRIE);
    
    }/* uart_putc */
    
    
    /*************************************************************************
    Function: uart_puts()
    Purpose:  transmit string to UART
    Input:    string to be transmitted
    Returns:  none          
    **************************************************************************/
    void uart_puts(const char *s )
    {
        while (*s) 
          uart_putc(*s++);
    
    }/* uart_puts */
    
    
    /*************************************************************************
    Function: uart_puts_p()
    Purpose:  transmit string from program memory to UART
    Input:    program memory string to be transmitted
    Returns:  none
    **************************************************************************/
    void uart_puts_p(const char *progmem_s )
    {
        register char c;
        
        while ( (c = pgm_read_byte(progmem_s++)) ) 
          uart_putc(c);
    
    }/* uart_puts_p */
    
    
    /*
     * these functions are only for ATmegas with two USART
     */
    Viele Grüsse

  6. #6
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Und wie groß ist UART_TX_BUFFER_SIZE?
    Wenn es kleiner ist als 26, dann hast du in ISR(SIG_USART1_RECV) definitiv einen Deadlock. Wenn es größer ist, hängt es davon ab ,wie viel gerade im Buffer ist.

    Der konkrete Deadlock:
    Der Debug-Code schreibt die zu sendenden Daten in einen Puffer. Ist nicht mehr genug Platz im Puffer, wird so lange gewartet, bis wieder Platz ist. Das Senden funktioniert aber per Interrupt, und die sind abgeschaltet innerhalb einer anderen ISR. Es wird also nichts gesendet, also wird kein Platz im Puffer frei, also wird bis in alle Ewigkeit gewartet.
    MfG
    Stefan

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    08.05.2007
    Beiträge
    27
    Hi, Stefan

    Der UART_TX_BUFFER_SIZE ist 32. Auf dem Hyperteminal habe ich immer die Zeile" In Sendenvorgang springen" gesehen. Ich glaube, es kein Deadlock hier gibt. Sonst tritten nicht aktualisierte Zeile "In Sendenvorgang springen" auf.
    Viele Grüsse

Berechtigungen

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

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad