PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : SRF02 über UART programmieren



tranh85bo
21.04.2010, 00:44
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.


#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

sternst
21.04.2010, 12:03
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.

tranh85bo
21.04.2010, 18:18
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

sternst
21.04.2010, 18:54
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).

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.

tranh85bo
24.04.2010, 08:39
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


/************************************************** ***********************
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

sternst
24.04.2010, 10:53
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.

tranh85bo
26.04.2010, 10:51
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