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 | }
|