hm ich hab das jetzt mal so probiert, aber es kommt nichts zurück.
Druckbare Version
hm ich hab das jetzt mal so probiert, aber es kommt nichts zurück.
Aber du hast die Interrupts aktiviert und die Übertragung via Interrupt funktioniert auch?
Ja sollte alles funktionieren. Das ist mein Code:
Nach dem Reset wird auch vom µC auf den PC übertragen:Code:/*### Includes ###*/#include <avr/io.h>
#include <stdlib.h>
#include <string.h>
#include "BTControlled_v1.0.h"
#include "uart.h"
/*############### ISR ###########################*/
// Empfangene Zeichen werden in die Eingangs-FIFO gespeichert und warten dort
ISR (USART_RXC_vect)
{
_inline_fifo_put (&infifo, UDR);
}
// Ein Zeichen aus der Ausgabe-FIFO lesen und ausgeben
// Ist das Zeichen fertig ausgegeben, wird ein neuer SIG_UART_DATA-IRQ getriggert
// Ist die FIFO leer, deaktiviert die ISR ihren eigenen IRQ.
ISR (USART_UDRE_vect)
{
if (outfifo.count > 0)
UDR = _inline_fifo_get (&outfifo);
else
UCSRB &= ~(1 << UDRIE);
}
/*############## Main ############################*/
int main(void)
{
/*##########Initialisierungsphase############*/
//Pins bzw. Ports als Ein-/Ausgänge konfigurieren
DDRA |= 0x00; //00000000 -> alle Analogports als Eingänge
DDRB |= 0x03; //00000011 -> PORTB.0 und PORTB.1 sind Kanäle des rechten Motors
DDRC |= 0xFF; //11111111 -> PORTC.6 und PORTC.7 sind Kanäle des linken Motors, Rest sind LEDs für Lauflicht
DDRD |= 0xB0; //10110000 -> PORTD.4 ist PWM-Kanal des linken Motors, PORTD.5 des rechten
setportcon(0); setportcon(1); setportcon(2); setportcon(3); setportcon(4); setportcon(5); //LEDs ausschalten
setportdoff(7); //Speaker aus
init_timer1(); //Initialisierung Timer für PWM
uart_init(); //UART initialisieren
sei();
char text[] = "Hallo Welt.";
char text2[40] = "23";
uart_puts (text);
/*##############Hauptschleife###########*/
while(1)
{
if(infifo.count == 6)
{
char ch;
while(infifo.count > 0);
{
ch = fifo_get_wait(&infifo);
uart_putc(ch);
}
}
}
return 0;
}
Hallo Welt.\0x00
dann sende ich an den µC vom PC aus z.B. 1234567
aber es kommt nichts zurück
Initialisierst du das FIFO nicht ?
fifo_init (&fifo, buffer, BUF_SIZE);
das mache ich in uart.h:
unter uart_init():
hier noch fifo.h:Code:/* * uart.h
*
* Created on: 12.05.2012
* Author: rainer
*/
#ifndef UART_H_
#define UART_H_
#include <avr/io.h>
#include <avr/interrupt.h>
#include "fifo.h" // erklärt im Artikel "FIFO mit avr-gcc"
// FIFO-Objekte und Puffer für die Ein- und Ausgabe
#define BUFSIZE_IN 0x40
uint8_t inbuf[BUFSIZE_IN];
fifo_t infifo;
#define BUFSIZE_OUT 0x40
uint8_t outbuf[BUFSIZE_OUT];
fifo_t outfifo;
//Variable zum Dummy auslesen
uint8_t dummy;
void uart_init (void)
{
uint8_t sreg = SREG;
UBRRH = 0; //Highbyte ist 0
UBRRL = 51; //Lowbyte ist 103 (dezimal)
//-> (Frequenz_in_Hz / (Baudrate * 16)) - 1 <- Quarzfrequenz = 16*1000*1000 Hz!!!!
// Interrupts kurz deaktivieren
cli();
// UART Receiver und Transmitter anschalten, Receive-Interrupt aktivieren
// Data mode 8N1, asynchron
UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);
UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0);
// Flush Receive-Buffer (entfernen evtl. vorhandener ungültiger Werte)
do
{
// UDR auslesen (Wert wird nicht verwendet)
dummy = UDR;
}
while (UCSRA & (1 << RXC));
// Rücksetzen von Receive und Transmit Complete-Flags
UCSRA = (1 << RXC) | (1 << TXC);
// Global Interrupt-Flag wieder herstellen
SREG = sreg;
// FIFOs für Ein- und Ausgabe initialisieren
fifo_init (&infifo, inbuf, BUFSIZE_IN);
fifo_init (&outfifo, outbuf, BUFSIZE_OUT);
}
int uart_putc (const uint8_t c)
{
int ret = fifo_put (&outfifo, c);
UCSRB |= (1 << UDRIE);
return ret;
}
int uart_getc_nowait (void)
{
return fifo_get_nowait (&infifo);
}
uint8_t uart_getc_wait (void)
{
return fifo_get_wait (&infifo);
}
// Einen 0-terminierten String übertragen.
void uart_puts (const char *s)
{
do
{
uart_putc (*s);
}
while (*s++);
}
#endif /* UART_H_ */
Code:/* * fifo.h
*
* Created on: 12.05.2012
* Author: rainer
*/
#ifndef FIFO_H_
#define FIFO_H_
#include <avr/io.h>
#include <avr/interrupt.h>
typedef struct
{
uint8_t volatile count; // # Zeichen im Puffer
uint8_t size; // Puffer-Größe
uint8_t *pread; // Lesezeiger
uint8_t *pwrite; // Schreibzeiger
uint8_t read2end, write2end; // # Zeichen bis zum Überlauf Lese-/Schreibzeiger
} fifo_t;
extern void fifo_init (fifo_t*, uint8_t* buf, const uint8_t size);
extern uint8_t fifo_put (fifo_t*, const uint8_t data);
extern uint8_t fifo_get_wait (fifo_t*);
extern int fifo_get_nowait (fifo_t*);
static inline uint8_t
_inline_fifo_put (fifo_t *f, const uint8_t data)
{
if (f->count >= f->size)
return 0;
uint8_t * pwrite = f->pwrite;
*(pwrite++) = data;
uint8_t write2end = f->write2end;
if (--write2end == 0)
{
write2end = f->size;
pwrite -= write2end;
}
f->write2end = write2end;
f->pwrite = pwrite;
uint8_t sreg = SREG;
cli();
f->count++;
SREG = sreg;
return 1;
}
static inline uint8_t
_inline_fifo_get (fifo_t *f)
{
uint8_t *pread = f->pread;
uint8_t data = *(pread++);
uint8_t read2end = f->read2end;
if (--read2end == 0)
{
read2end = f->size;
pread -= read2end;
}
f->pread = pread;
f->read2end = read2end;
uint8_t sreg = SREG;
cli();
f->count--;
SREG = sreg;
return data;
}
void fifo_init (fifo_t *f, uint8_t *buffer, const uint8_t size)
{
f->count = 0;
f->pread = f->pwrite = buffer;
f->read2end = f->write2end = f->size = size;
}
uint8_t fifo_put (fifo_t *f, const uint8_t data)
{
return _inline_fifo_put (f, data);
}
uint8_t fifo_get_wait (fifo_t *f)
{
while (!f->count);
return _inline_fifo_get (f);
}
int fifo_get_nowait (fifo_t *f)
{
if (!f->count) return -1;
return (int) _inline_fifo_get (f);
}
#endif /* FIFO_H_ */
Das Einzige was mir noch sinnvoll vorkommen würde, wäre das nichts in das FIFO gelangt. Also sprich bei der ISR für den Empfang. Sonst fällt mir auf die Schnelle auch nichts mehr ein.