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


von Daniel C. (cagara)


Angehängte Dateien:

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 :)


1
#include "avr/io.h"
2
#include "util/delay.h"
3
#include "avr/interrupt.h"
4
#include "uart.h"
5
#include "rprintf.h"
6
7
#define TASTER  PB1
8
#define TASTER_GEDRUECKT()  (PINB & (1<<TASTER))
9
10
#define LEDAN   PORTD|=(1<<5)  
11
#define LEDAUS  PORTD&=(~(1<<5))
12
13
#define _MESSAGE_WELCOME_ "Daniel Cagara's Tetsprogramm v0.1\nAwaiting Commands through UART\n"
14
15
16
uint8_t led;
17
uint8_t refresh=0;
18
19
// Interrupt based UART Command Buffers
20
volatile char uartRecvString[125];
21
volatile uint8_t positionCnt=0;
22
volatile uint8_t dirty=0;
23
24
void voidTxBufferWrapper(u08 data)
25
{
26
  uartAddToTxBuffer(data);
27
}
28
29
void executeCommand(char* command)
30
{
31
  // Check for LED Command ON
32
  if(strcmp(command,"LEDON") == 0)
33
  {
34
    LEDAN;
35
    rprintf("LED IS ON NOW\n");
36
    dirty=1;
37
  }
38
  // Check for LED Command ON
39
  else if(strcmp(command,"LEDOFF") == 0)
40
  {
41
    LEDAUS;
42
    rprintf("LED IS OFF NOW\n");
43
    dirty=1;
44
  }
45
  // Otherwise we have an unknown command
46
  else
47
  {
48
    rprintf("Unknown Command, I don't know what to do\n");
49
    dirty=1;
50
  }
51
52
}
53
54
void setRecvStringEmpty()
55
{
56
  positionCnt=0;
57
  int i=0;
58
  for(i=0;i<125;i++)
59
    uartRecvString[i]=0;
60
}
61
    
62
void uartRxHandler(unsigned char c)
63
{
64
  if(c!=0x0D){ // If no new line char, then fill uart recv buffer!
65
    uartRecvString[positionCnt]=c; 
66
    positionCnt++;
67
  } else {
68
    rprintf("Received Command: ");
69
    rprintfStr(uartRecvString); // send welcome message
70
    rprintf("\n");
71
    executeCommand(&(uartRecvString[0]));
72
    dirty=1;
73
    setRecvStringEmpty();
74
  }
75
} 
76
77
78
void initializeUart()
79
{
80
  uartInit();                 // initialize UART (serial port)
81
    uartSetBaudRate(9600);      // set UART speed to 9600 baud
82
  rprintfInit(voidTxBufferWrapper);  // configure rprintf to use UART for output
83
  setRecvStringEmpty();
84
  uartSetRxHandler(uartRxHandler);
85
    rprintfStr(_MESSAGE_WELCOME_); // send welcome message
86
  dirty=1;
87
}
88
89
void initializePorts()
90
{
91
DDRD  |= (1 << 5); // Set Ports here, example: PORTD5 = LED, set as output
92
}
93
94
95
void mainLoop()
96
{
97
  while(1)
98
  {
99
    if(dirty==1){ // send any buffers out, and set dirty flag back to zero,
100
      uartSendTxBuffer();
101
      dirty=0;
102
    }
103
  }
104
}
105
106
107
int main(){
108
  initializePorts();
109
  initializeUart();
110
  mainLoop();
111
}

von Daniel C. (cagara)


Lesenswert?

Eine Kleinigkeit stimmt noch nicht ... je länger der Befehl den ich 
eingebe, desto mehr wird von der Ausgabe abgeschnitten ...
1
Daniel Cagara's Tetsprogramm v0.1
2
Awaiting Commands through UARtest
3
Received Command: test
4
Unknown Command, I don't know what to do
5
Received Command: 
6
Unknown Command, I don't know what to do
7
TESTNUMBERONE
8
Rceived Command: TESTNUMBERONE
9
Unknown Command, I don't know w
10
Received Command: 
11
Unknown Command, I don't know what to do

Ich hoffe ich finde gleich den fehler!

von Daniel C. (cagara)


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.

von Daniel C. (cagara)


Angehängte Dateien:

Lesenswert?

Version 2 :)

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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.