Hender
09.03.2006, 16:21
Hallo,
ich suche nach einer möglichst einfachen Variante Daten zwischen meinem Atmega32 und dem Pc auszutauschen.
PC->Atmel:
Es soll möglich sein vom Pc aus einfache Steuerbefehle zu senden, bei denen dann auf dem Atmel einfach eine Funktion ausgerufen wird, z.B.: "res" löst die Funktion reset() aus. Zudem soll es möglich sein konkrete Werte zu senden, die dann auf dem Atmel einer Variable oder einem Register zugewiesen werden, z.B. durch "pwm128" wird dem PWM-Register OCR1AL=128; zugewiesen.
Atmel->PC: (diese Richtung ist weniger das Problem)
Hier soll es möglich sein diverse Statuswerte von Variablen an den PC zu senden, z.B. ADCValue=234.
Ich weiß das es eine Variante gibt, wo man zwei Byte sendet, wobei im ersten Byte das Kommando steht und im zweiten Byte die dazugehörigen Daten. Leider verstehe ich das ganze noch nicht richtig und weiß auch nicht wie die Pakete aussehen müssen, die ich vom PC aus sende. Veilleicht gibt es auch eine andere, vielleicht auch einfachere, Variante.
Es wäre echt nett wenn mir da jemand weiter helfen könnte. Vielleicht kennt jemand ein Tutorial im Netz, wo eine Protokoll-Implemenation erklärt?
Für die Uart-Kommunikation verwende ich den folgenden Code.:
#include "uart.h"
#include <avr/io.h>
#include <avr/signal.h>
/* UART Buffer */
#define UART_RX_BUFFER_SIZE 128 /* 2,4,8,16,32,64,128 or 256 bytes */
#define UART_TX_BUFFER_SIZE 128
#define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1 )
#if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK )
#error RX buffer size is not a power of 2
#endif
#define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1 )
#if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK )
#error TX buffer size is not a power of 2
#endif
/* Static Variables */
static uint8_t uart_rxbuf[UART_RX_BUFFER_SIZE];
static volatile uint8_t uart_rxhead;
static volatile uint8_t uart_rxtail;
static uint8_t uart_txbuf[UART_TX_BUFFER_SIZE];
static volatile uint8_t uart_txhead;
static volatile uint8_t uart_txtail;
/* Initialize UART */
void uart_init (uint8_t ubrr)
{
UBRRH = 0;
UBRRL = ubrr; /* Set the baud rate */
/* Enable UART receiver and transmitter, and receive interrupt */
UCSRB = ( (1<<RXCIE) | (1<<RXEN) | (1<<TXEN) );
/* enable 2 stopbits 8bit char size */
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //syncron usart modus UMSEL
/* Flush receive buffer */
uart_rxtail = 0;
uart_rxhead = 0;
uart_txtail = 0;
uart_txhead = 0;
}
/* Interrupt handlers */
/*
* Receive Complete
*/
SIGNAL (SIG_UART_RECV)
{
uint8_t data;
uint8_t tmphead;
data = UDR; /* Read the received data */
/* Calculate buffer index */
tmphead = (uart_rxhead + 1) & UART_RX_BUFFER_MASK;
if (tmphead == uart_rxtail) {
/* ERROR! Receive buffer overflow */
tmphead = uart_rxhead;
}
uart_rxhead = tmphead; /* Store new index */
uart_rxbuf[tmphead] = data; /* Store received data in buffer */
}
/*
* Data Register Empty
*/
SIGNAL (SIG_UART_DATA)
{
uint8_t tmptail;
/* Check if all data is transmitted */
if (uart_txhead != uart_txtail) {
/* Calculate buffer index */
tmptail = ( uart_txtail + 1 ) & UART_TX_BUFFER_MASK;
uart_txtail = tmptail; /* Store new index */
UDR = uart_txbuf[tmptail]; /* Start transmition */
} else {
UCSRB &= ~ _BV (UDRIE); /* Disable UDRE interrupt */
}
}
/* Read and write functions */
uint8_t uart_get_char (void)
{
uint8_t tmptail;
while (uart_rxhead == uart_rxtail) { /* Wait for incomming data */
}
/* Calculate buffer index */
tmptail = (uart_rxtail + 1) & UART_RX_BUFFER_MASK;
uart_rxtail = tmptail; /* Store new index */
return uart_rxbuf[tmptail]; /* Return data */
}
uint8_t tx_buffer_size (void)
{
return (uart_txhead - uart_txtail);
}
uint8_t uart_put_char (uint8_t data)
{
uint8_t tmphead;
/* Calculate buffer index */
tmphead = ( uart_txhead + 1 ) & UART_TX_BUFFER_MASK;
/* Wait for free space in buffer */
while ( tmphead == uart_txtail ) {
}
uart_txbuf[tmphead] = data; /* Store data in buffer */
uart_txhead = tmphead; /* Store new index */
UCSRB |= _BV (UDRIE); /* Enable UDRE interrupt */
return 0;
}
uint8_t uart_data_available (void)
{
/* Return 0 (FALSE) if the receive buffer is empty */
return (uart_rxhead != uart_rxtail);
}
... also uart_get_char() und uart_put_char(data)
ich suche nach einer möglichst einfachen Variante Daten zwischen meinem Atmega32 und dem Pc auszutauschen.
PC->Atmel:
Es soll möglich sein vom Pc aus einfache Steuerbefehle zu senden, bei denen dann auf dem Atmel einfach eine Funktion ausgerufen wird, z.B.: "res" löst die Funktion reset() aus. Zudem soll es möglich sein konkrete Werte zu senden, die dann auf dem Atmel einer Variable oder einem Register zugewiesen werden, z.B. durch "pwm128" wird dem PWM-Register OCR1AL=128; zugewiesen.
Atmel->PC: (diese Richtung ist weniger das Problem)
Hier soll es möglich sein diverse Statuswerte von Variablen an den PC zu senden, z.B. ADCValue=234.
Ich weiß das es eine Variante gibt, wo man zwei Byte sendet, wobei im ersten Byte das Kommando steht und im zweiten Byte die dazugehörigen Daten. Leider verstehe ich das ganze noch nicht richtig und weiß auch nicht wie die Pakete aussehen müssen, die ich vom PC aus sende. Veilleicht gibt es auch eine andere, vielleicht auch einfachere, Variante.
Es wäre echt nett wenn mir da jemand weiter helfen könnte. Vielleicht kennt jemand ein Tutorial im Netz, wo eine Protokoll-Implemenation erklärt?
Für die Uart-Kommunikation verwende ich den folgenden Code.:
#include "uart.h"
#include <avr/io.h>
#include <avr/signal.h>
/* UART Buffer */
#define UART_RX_BUFFER_SIZE 128 /* 2,4,8,16,32,64,128 or 256 bytes */
#define UART_TX_BUFFER_SIZE 128
#define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1 )
#if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK )
#error RX buffer size is not a power of 2
#endif
#define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1 )
#if ( UART_TX_BUFFER_SIZE & UART_TX_BUFFER_MASK )
#error TX buffer size is not a power of 2
#endif
/* Static Variables */
static uint8_t uart_rxbuf[UART_RX_BUFFER_SIZE];
static volatile uint8_t uart_rxhead;
static volatile uint8_t uart_rxtail;
static uint8_t uart_txbuf[UART_TX_BUFFER_SIZE];
static volatile uint8_t uart_txhead;
static volatile uint8_t uart_txtail;
/* Initialize UART */
void uart_init (uint8_t ubrr)
{
UBRRH = 0;
UBRRL = ubrr; /* Set the baud rate */
/* Enable UART receiver and transmitter, and receive interrupt */
UCSRB = ( (1<<RXCIE) | (1<<RXEN) | (1<<TXEN) );
/* enable 2 stopbits 8bit char size */
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); //syncron usart modus UMSEL
/* Flush receive buffer */
uart_rxtail = 0;
uart_rxhead = 0;
uart_txtail = 0;
uart_txhead = 0;
}
/* Interrupt handlers */
/*
* Receive Complete
*/
SIGNAL (SIG_UART_RECV)
{
uint8_t data;
uint8_t tmphead;
data = UDR; /* Read the received data */
/* Calculate buffer index */
tmphead = (uart_rxhead + 1) & UART_RX_BUFFER_MASK;
if (tmphead == uart_rxtail) {
/* ERROR! Receive buffer overflow */
tmphead = uart_rxhead;
}
uart_rxhead = tmphead; /* Store new index */
uart_rxbuf[tmphead] = data; /* Store received data in buffer */
}
/*
* Data Register Empty
*/
SIGNAL (SIG_UART_DATA)
{
uint8_t tmptail;
/* Check if all data is transmitted */
if (uart_txhead != uart_txtail) {
/* Calculate buffer index */
tmptail = ( uart_txtail + 1 ) & UART_TX_BUFFER_MASK;
uart_txtail = tmptail; /* Store new index */
UDR = uart_txbuf[tmptail]; /* Start transmition */
} else {
UCSRB &= ~ _BV (UDRIE); /* Disable UDRE interrupt */
}
}
/* Read and write functions */
uint8_t uart_get_char (void)
{
uint8_t tmptail;
while (uart_rxhead == uart_rxtail) { /* Wait for incomming data */
}
/* Calculate buffer index */
tmptail = (uart_rxtail + 1) & UART_RX_BUFFER_MASK;
uart_rxtail = tmptail; /* Store new index */
return uart_rxbuf[tmptail]; /* Return data */
}
uint8_t tx_buffer_size (void)
{
return (uart_txhead - uart_txtail);
}
uint8_t uart_put_char (uint8_t data)
{
uint8_t tmphead;
/* Calculate buffer index */
tmphead = ( uart_txhead + 1 ) & UART_TX_BUFFER_MASK;
/* Wait for free space in buffer */
while ( tmphead == uart_txtail ) {
}
uart_txbuf[tmphead] = data; /* Store data in buffer */
uart_txhead = tmphead; /* Store new index */
UCSRB |= _BV (UDRIE); /* Enable UDRE interrupt */
return 0;
}
uint8_t uart_data_available (void)
{
/* Return 0 (FALSE) if the receive buffer is empty */
return (uart_rxhead != uart_rxtail);
}
... also uart_get_char() und uart_put_char(data)