www.mikrocontroller.net

Forum: Projekte & Code AVR per UART asynchron und auf Interruptbasis Steuern und Regeln


Autor: Daniel Cagara (cagara)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Für alle die, welche ihren Mikrocontroller Asynchron auf Interruptbasis 
per UART steuern möchten, habe ich folgendes Programm zusammengestellt.

Es arbeitet Interruptgesteuert, sodass die Mainloop entlastet ist, 
sprich: Wenn nichts kommt wird auch nicht gearbeitet.

Das Programm ist sehr einfach und leicht nachvollziehbar. Es wird nach 
und nach per UART der command buffer befüllt und wenn ein \n, also Neue 
Zeile, kommt wird der Befehl evaluiert.

Im moment habe ich zwei Befehle implementiert, LEDON und LEDOFF welche 
auf meinem Pollin AVR Funk Evaluationsboard die LED an PortD5 an bzw 
wieder ausschalten.

Natürlich ist das einfach um weitere befehle erweiterbar, z.b. schicke 
"XYZ" per Funk, oder stelle frequenz ein, etc etc etc.



Im Anhang befindet sich das komplette AVRStudio projekt auf basis der 
Procyon AVRLib, und hier ist nochmal für alle die Hauptdatei:

Ich hoffe ihr könnt etwas damit anfangen, ich werde dann mal weiter 
spielen und per hyperterminal die LED auf meinem EVAL Board an und 
ausschalten :)


#include "avr/io.h"
#include "util/delay.h"
#include "avr/interrupt.h"
#include "uart.h"
#include "rprintf.h"

#define TASTER  PB1
#define TASTER_GEDRUECKT()  (PINB & (1<<TASTER))

#define LEDAN   PORTD|=(1<<5)  
#define LEDAUS  PORTD&=(~(1<<5))

#define _MESSAGE_WELCOME_ "Daniel Cagara's Tetsprogramm v0.1\nAwaiting Commands through UART\n"


uint8_t led;
uint8_t refresh=0;

// Interrupt based UART Command Buffers
volatile char uartRecvString[125];
volatile uint8_t positionCnt=0;
volatile uint8_t dirty=0;

void voidTxBufferWrapper(u08 data)
{
  uartAddToTxBuffer(data);
}

void executeCommand(char* command)
{
  // Check for LED Command ON
  if(strcmp(command,"LEDON") == 0)
  {
    LEDAN;
    rprintf("LED IS ON NOW\n");
    dirty=1;
  }
  // Check for LED Command ON
  else if(strcmp(command,"LEDOFF") == 0)
  {
    LEDAUS;
    rprintf("LED IS OFF NOW\n");
    dirty=1;
  }
  // Otherwise we have an unknown command
  else
  {
    rprintf("Unknown Command, I don't know what to do\n");
    dirty=1;
  }

}

void setRecvStringEmpty()
{
  positionCnt=0;
  int i=0;
  for(i=0;i<125;i++)
    uartRecvString[i]=0;
}
    
void uartRxHandler(unsigned char c)
{
  if(c!=0x0D){ // If no new line char, then fill uart recv buffer!
    uartRecvString[positionCnt]=c; 
    positionCnt++;
  } else {
    rprintf("Received Command: ");
    rprintfStr(uartRecvString); // send welcome message
    rprintf("\n");
    executeCommand(&(uartRecvString[0]));
    dirty=1;
    setRecvStringEmpty();
  }
} 


void initializeUart()
{
  uartInit();                 // initialize UART (serial port)
    uartSetBaudRate(9600);      // set UART speed to 9600 baud
  rprintfInit(voidTxBufferWrapper);  // configure rprintf to use UART for output
  setRecvStringEmpty();
  uartSetRxHandler(uartRxHandler);
    rprintfStr(_MESSAGE_WELCOME_); // send welcome message
  dirty=1;
}

void initializePorts()
{
DDRD  |= (1 << 5); // Set Ports here, example: PORTD5 = LED, set as output
}


void mainLoop()
{
  while(1)
  {
    if(dirty==1){ // send any buffers out, and set dirty flag back to zero,
      uartSendTxBuffer();
      dirty=0;
    }
  }
}


int main(){
  initializePorts();
  initializeUart();
  mainLoop();
}


Autor: Daniel Cagara (cagara)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine Kleinigkeit stimmt noch nicht ... je länger der Befehl den ich 
eingebe, desto mehr wird von der Ausgabe abgeschnitten ...
Daniel Cagara's Tetsprogramm v0.1
Awaiting Commands through UARtest
Received Command: test
Unknown Command, I don't know what to do
Received Command: 
Unknown Command, I don't know what to do
TESTNUMBERONE
Rceived Command: TESTNUMBERONE
Unknown Command, I don't know w
Received Command: 
Unknown Command, I don't know what to do

Ich hoffe ich finde gleich den fehler!

Autor: Daniel Cagara (cagara)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gefunden:

Das kann man  umgehen indem man in der global.h die Sendebuffer grösser 
setzt, da er den ganzen befehl auch mit in den TX Buffer steckt.

#define UART_TX_BUFFER_SIZE 125
für 125 bytes z.b.

Autor: Daniel Cagara (cagara)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Version 2 :)

Speichert sogar den letzten Zustand der LED im EEprom ab und lädt ihn 
wieder beim neustart!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.