premier
13.08.2005, 13:08
Hallo Robotikfreaks,
Was AVRs angeht bin ich ein ziemlicher NOOB!
Habe mir vor kurzem ein atmega16 Testboard bei ebay gekauft und habe es geschafft mal was über USART am PC auszugeben.
Ich habe das fertige C-Skript von Christian Schifferle angepasst, und man sollte eigentlich über ein Terminal Programm eine Eingabe der Form:
<Kanal 1..4>:<Wert von 0...255>
machen. die an den Ausgängen angeschlossenen LEDs sollten dann heller oder dunkler leuchten, aber bei mir sind sie die ganze Zeit "mittelhell" egal welchen Wert ich eingebe. :-s
Hier das Skript:
#include <avr/io.h>
#include <stdint.h> // Wir brauchen Zugriff auf die I/O's des Controllers
#include <string.h> // und eine Stringfunktion (strchr)
#include <stdlib.h> // sowie die Standardfunktion atoi aus stdlib
#define USART_BAUD_RATE 9600 /* 9600 baud */
// Berechnung des Inhalts des UBBR-Registers
#define USART_BAUD_SELECT (F_CPU/(USART_BAUD_RATE*16l)-1)
// Datentypdefinitionen
typedef unsigned char BYTE;
typedef unsigned short WORD;
#define CR 0x0d // Definition für Carriage Return
#define CHANNELS 4 // Anzahl PWM-Kanäle
#define MAX_BUFFER 15 // Maximal 15 Zeichen lange Befehlszeile zulassen
BYTE szBuffer[MAX_BUFFER+1]; // Puffer mit maximal 15 Zeichen plus Nullbyte
BYTE nBuffer; // Anzahl Zeichen im Puffer
BYTE nChannels[CHANNELS]; // PWM-Werte der 4 Kanäle
// Prototypen der lokalen Funktionen
void HdlBuffer (void);
void USART_Init(void);
void USART_transmit (unsigned char c);
unsigned char USART_receive (void);
void USART_transmit_string (unsigned char *string);
int main (void)
/************************************************** **************************
Hier ist der Programmeinstiegspunkt.
*/
{
register BYTE c; // Letztes empfangenes Zeichen
register BYTE nCnt; // Aktueller Zählerwert
register BYTE n; // Hilfsvariable
register BYTE nPortB; // Hilfsvariable
/* UART Control Register laden. Wir verwenden (immer noch)
keine Interrupts. Hier wollen wir nur empfangen, also wird
nur das Receiver Enable Flag gesetzt. */
USART_Init();
// Port B der Einfachheit halber komplett als Ausgang konfigurieren
DDRB=0xff;
// Timer/Counter0 (8-Bit-Timer) initialisieren
// Wir verwenden den Vorzähler 1024. Warum? Einfach so.
// Wenn wir einen zu kleinen Vorteiler wählen, dann kommt unser Programm nicht
// mehr mit und die Ausgangsignale werden unstabil.
TCCR0|=(1<<CS02)|(1<<CS00); // Vorzaehler = 1024
USART_transmit_string("Bitte Kanal:Wert eingeben\r\n");
// Und jetzt in die Hauptschleife
for (;;) {
// Prüfen, ob ein Zeichen empfangen wurde.
if ((UCSRA) & (1 << RXC)) { // Bit RXC im USR gesetzt ?
// Zeichen einlesen
c = UDR;
// Falls CR, dann Empfangspuffer auswerten, sonst Zeichen speichern,
// wenn der Puffer nicht bereits überlaufen ist.
if (c == CR) {
// Puffer auswerten
szBuffer[nBuffer] = '\0'; // Abschliessendes Nullbyte eintragen
HdlBuffer ();
nBuffer = 0; // Puffer wieder initialisieren
}
else {
if (nBuffer < MAX_BUFFER) {
szBuffer[nBuffer++] = c;
}
}
}
// Zählerwert abfragen
nCnt = TCNT0;
nPortB = 0; // Portinhalt mit 0 initialisieren
for (n=0; n<CHANNELS; n++) {
if (nChannels[n] >= nCnt) {
// Portbit setzen
nPortB |= (1 << n);
}
}
// Resultat auf Port B ausgeben
PORTB=nPortB;
}
} /* end of main */
void HdlBuffer (void)
{
BYTE *pColon; // Position des Doppelpunktes
BYTE nChannel, nVal;
// Doppelpunkt suchen, wenn keiner da ist -> Fehler
pColon = strchr (szBuffer, ':');
if (pColon) {
// Kanal bestimmen
nChannel = atoi (szBuffer);
// PWM-Wert bestimmen
nVal = atoi (pColon + 1);
// Die Kanalnummer wird zwischen 1 und 4 erwartet
if (nChannel >= 1 && nChannel <= 4) {
// und im Array abgespeichert.
// Achtung: Array-Indizes beginnen immer bei 0, deshalb das - 1
nChannels[nChannel-1] = nVal;
}
}
} /* end of HdlBuffer */
void USART_Init(void) {
UCSRB = (1<<RXCIE) | (1<<TXCIE) | (1<<RXEN) | (1<<TXEN);
UCSRB = (1<<RXEN) | (1<<TXEN);
UBRRL = (unsigned char) USART_BAUD_SELECT;
}
void USART_transmit (unsigned char c) {
while (!(UCSRA & (1<<UDRE))) {}
UDR = c;
}
unsigned char USART_receive (void) {
while(!(UCSRA & (1<<RXC))) {}
return UDR;
}
void USART_transmit_string (unsigned char *string) {
while (!(UCSRA & (1<<UDRE))) {}
while ( *string)
USART_transmit (*string++);
}
bitte helft mir!
Was AVRs angeht bin ich ein ziemlicher NOOB!
Habe mir vor kurzem ein atmega16 Testboard bei ebay gekauft und habe es geschafft mal was über USART am PC auszugeben.
Ich habe das fertige C-Skript von Christian Schifferle angepasst, und man sollte eigentlich über ein Terminal Programm eine Eingabe der Form:
<Kanal 1..4>:<Wert von 0...255>
machen. die an den Ausgängen angeschlossenen LEDs sollten dann heller oder dunkler leuchten, aber bei mir sind sie die ganze Zeit "mittelhell" egal welchen Wert ich eingebe. :-s
Hier das Skript:
#include <avr/io.h>
#include <stdint.h> // Wir brauchen Zugriff auf die I/O's des Controllers
#include <string.h> // und eine Stringfunktion (strchr)
#include <stdlib.h> // sowie die Standardfunktion atoi aus stdlib
#define USART_BAUD_RATE 9600 /* 9600 baud */
// Berechnung des Inhalts des UBBR-Registers
#define USART_BAUD_SELECT (F_CPU/(USART_BAUD_RATE*16l)-1)
// Datentypdefinitionen
typedef unsigned char BYTE;
typedef unsigned short WORD;
#define CR 0x0d // Definition für Carriage Return
#define CHANNELS 4 // Anzahl PWM-Kanäle
#define MAX_BUFFER 15 // Maximal 15 Zeichen lange Befehlszeile zulassen
BYTE szBuffer[MAX_BUFFER+1]; // Puffer mit maximal 15 Zeichen plus Nullbyte
BYTE nBuffer; // Anzahl Zeichen im Puffer
BYTE nChannels[CHANNELS]; // PWM-Werte der 4 Kanäle
// Prototypen der lokalen Funktionen
void HdlBuffer (void);
void USART_Init(void);
void USART_transmit (unsigned char c);
unsigned char USART_receive (void);
void USART_transmit_string (unsigned char *string);
int main (void)
/************************************************** **************************
Hier ist der Programmeinstiegspunkt.
*/
{
register BYTE c; // Letztes empfangenes Zeichen
register BYTE nCnt; // Aktueller Zählerwert
register BYTE n; // Hilfsvariable
register BYTE nPortB; // Hilfsvariable
/* UART Control Register laden. Wir verwenden (immer noch)
keine Interrupts. Hier wollen wir nur empfangen, also wird
nur das Receiver Enable Flag gesetzt. */
USART_Init();
// Port B der Einfachheit halber komplett als Ausgang konfigurieren
DDRB=0xff;
// Timer/Counter0 (8-Bit-Timer) initialisieren
// Wir verwenden den Vorzähler 1024. Warum? Einfach so.
// Wenn wir einen zu kleinen Vorteiler wählen, dann kommt unser Programm nicht
// mehr mit und die Ausgangsignale werden unstabil.
TCCR0|=(1<<CS02)|(1<<CS00); // Vorzaehler = 1024
USART_transmit_string("Bitte Kanal:Wert eingeben\r\n");
// Und jetzt in die Hauptschleife
for (;;) {
// Prüfen, ob ein Zeichen empfangen wurde.
if ((UCSRA) & (1 << RXC)) { // Bit RXC im USR gesetzt ?
// Zeichen einlesen
c = UDR;
// Falls CR, dann Empfangspuffer auswerten, sonst Zeichen speichern,
// wenn der Puffer nicht bereits überlaufen ist.
if (c == CR) {
// Puffer auswerten
szBuffer[nBuffer] = '\0'; // Abschliessendes Nullbyte eintragen
HdlBuffer ();
nBuffer = 0; // Puffer wieder initialisieren
}
else {
if (nBuffer < MAX_BUFFER) {
szBuffer[nBuffer++] = c;
}
}
}
// Zählerwert abfragen
nCnt = TCNT0;
nPortB = 0; // Portinhalt mit 0 initialisieren
for (n=0; n<CHANNELS; n++) {
if (nChannels[n] >= nCnt) {
// Portbit setzen
nPortB |= (1 << n);
}
}
// Resultat auf Port B ausgeben
PORTB=nPortB;
}
} /* end of main */
void HdlBuffer (void)
{
BYTE *pColon; // Position des Doppelpunktes
BYTE nChannel, nVal;
// Doppelpunkt suchen, wenn keiner da ist -> Fehler
pColon = strchr (szBuffer, ':');
if (pColon) {
// Kanal bestimmen
nChannel = atoi (szBuffer);
// PWM-Wert bestimmen
nVal = atoi (pColon + 1);
// Die Kanalnummer wird zwischen 1 und 4 erwartet
if (nChannel >= 1 && nChannel <= 4) {
// und im Array abgespeichert.
// Achtung: Array-Indizes beginnen immer bei 0, deshalb das - 1
nChannels[nChannel-1] = nVal;
}
}
} /* end of HdlBuffer */
void USART_Init(void) {
UCSRB = (1<<RXCIE) | (1<<TXCIE) | (1<<RXEN) | (1<<TXEN);
UCSRB = (1<<RXEN) | (1<<TXEN);
UBRRL = (unsigned char) USART_BAUD_SELECT;
}
void USART_transmit (unsigned char c) {
while (!(UCSRA & (1<<UDRE))) {}
UDR = c;
}
unsigned char USART_receive (void) {
while(!(UCSRA & (1<<RXC))) {}
return UDR;
}
void USART_transmit_string (unsigned char *string) {
while (!(UCSRA & (1<<UDRE))) {}
while ( *string)
USART_transmit (*string++);
}
bitte helft mir!