/*-------------------------------------------------------- uartint_demo.c Demoprogramm fuer Timer2 bassierendes UART, farbige Terminalsteuerung und Ausgabe mittels abgespecktem printf Compiler : SDCC 4.0.3 MCU : PFS154 10.06.2026 R. Seelig -------------------------------------------------------- */ #include #include "pdk_init.h" #include "pfs1xx_gpio3.h" #include "softwareuart.h" #include "delay.h" /* Farbencodes der ESC-Sequenzen im Terminal sw bl gn cy rt mg br gr 30, 34, 32, 36, 31, 35, 33, 37 Vordergrund 40, 44, 42, 46, 41, 45, 41, 47 Hintergrund fuer helle Hintergrundfarben ist der Wert 60 hinzuzuaddieren Ausgabestring zur Farbeinstellung: "\033[Helligkeit Vordergundfarbe; Vordergrundfarbe; Hintergrundfarbe" Hinweis: nach Hintergrundfarbe muss ein Zeichen m angefuegt sein Beispiel fuer gelbe Schrift (intensives braun) auf hellblauem Hintergrund: gelb (helles braun) = 33 hellblau = 44 + 60 = 104 auszugebender String = "\033;1;33;104m" */ // Die Ansi-Sequenzen sind hier volatile, weil der SDCC, warum auch immer ohne volatile eine // Optimierung vornimmt, die dann den clrscr-string nicht mehr korrekt ablegt! const char col_yellow_cyan[] = "\033[;1;33;42m"; // gelb auf tuerkis const char col_white_black[] = "\033[;1;37;40m"; // weiss auf schwarz const char col_iblue_black[] = "\033[;1;34;40m"; // hellbaul auf schwarz const char col_igreen_black[] = "\033[;1;32;40m"; // hellbaul auf schwarz const char clrscr[] = "\033[2J\033[H"; // String fuer Terminalinhalt loeschen #define putint_putchar uart_putchar // Alias, auf der putint die Ausgaben macht /* -------------------------------------------------------- interrupt (ISR) der Interrupt-Handler. Innerhalb dieser Funktion muss bei mehreren Interruptquellen das Interrupt- request Register INTRQ ausgewertet werden. Hier eingehaengt Timer2, ueber das das Samplen des UART erfolgt -------------------------------------------------------- */ void interrupt(void) __interrupt(0) { // Timer2 Interrupt if (INTRQ & INTRQ_TM2) { uart_sample(); INTRQ &= ~INTRQ_TM2; // Interruptanforderung quittieren .... // sollte nie aufgerufen werden, da // Quittierung in uart_sample erfolgt } // hier koennen andere Interruptquellen eingehaengt werden } /* ------------------------------------------------------------ putint gibt einen Integer dezimal aus. Ist Uebergabe "komma" != 0 wird ein "Kommapunkt" mit ausgegeben. Bsp.: fuer komma== 2 12345 wird als 123.45 ausgegeben. ------------------------------------------------------------ */ void putint(int i, char komma) { typedef enum boolean { FALSE, TRUE }bool_t; static int zz[] = { 10000, 1000, 100, 10 }; bool_t not_first = FALSE; char zi; int z, b; komma= 5-komma; if (!i) { putint_putchar('0'); } else { if(i < 0) { putint_putchar('-'); i = -i; } for(zi = 0; zi < 4; zi++) { z = 0; b = 0; if ((zi==komma) && komma) { if (!not_first) putint_putchar('0'); putint_putchar('.'); not_first= TRUE; } while(z + zz[zi] <= i) { b++; z += zz[zi]; } if(b || not_first) { putint_putchar('0' + b); not_first = TRUE; } i -= z; } if (komma== 4) putint_putchar('.'); putint_putchar('0' + i); } } /* ---------------------------------------------------------- my_atoi my ascii to integer einfache Konvertierung eines Strings zu einem Integer- wert bei nicht vorhandensein eines atoi oder zu "teuer" Definition der Funktion bewusst ohne Multiplikation, weil auf manchen Controllern kein mul/div hardwareseitig vorhanden ist Uebergabe: *str: Zeiger, der einen im String enthaltenen Integerzahlenwert repraesentiert Rueckgabe: konvertierter Integerwert ---------------------------------------------------------- */ int my_atoi(const char *str) { int res = 0; unsigned char c; unsigned char neg = 0; // fuehrende Leerzeichen loeschen while ((c = *str++) == ' ' || (c >= 9 && c <= 13)); // Vorzeichen if (c == '-') { neg = 1; c = *str++; } else { if (c == '+') { c = *str++; } } // Ziffern while (c >= '0' && c <= '9') { res = (res << 3) + (res << 1) + (c - '0'); c = *str++; } // Vorzeichen setzen if (neg) { res = -res;} return res; } /* ---------------------------------------------------------- uart_readln liest einen String auf dem UART ein. Einlesen erfolgt solange, bis ein /cr (Return), ein /lf (LineFeed) eingegangen ist, oder die max. Anzahl Zeichen erreicht sind Uebergabe: *str: Zeiger auf ein Char-Array in das eingelesen wird maxchars: max. eingebare Zeichen ---------------------------------------------------------- */ void uart_readln(char *str, uint8_t maxchars) { uint8_t ch; uint8_t anz = 0; do { ch= uart_getchar(); if ((ch != '\r') && (ch != '\n')) { uart_putchar(ch); } *str = ch; str++; anz++; } while ((ch != '\r') && (ch != '\n') && (anz < maxchars)); *str = '\0'; } /* -------------------------------------------------------- main -------------------------------------------------------- */ void main(void) { /* uint16_t zahl1, zahl2; char ch; */ uint16_t counter = 0; int i; char zahlstr[7]; uart_init(); delay(100); uart_puts(clrscr); // Terminalt loeschen uart_puts(col_yellow_cyan); // Farbe setzen uart_puts("\n\n\r PFS154 - SoftwareUart - Demo \n\n\r"); uart_puts(col_white_black); uart_puts(" Integer Eingabe: "); uart_puts(col_igreen_black); uart_readln(zahlstr, 6); i= my_atoi(zahlstr); // String nach Integer konvertieren uart_puts(col_white_black); uart_puts("\n\n\r Eingabe war: "); putint(i,0); uart_puts("\n\n\r"); uart_puts(col_iblue_black); counter = i; // Zaehler-Endlosschleife while(1) { uart_puts(" Counter: "); putint(counter,0); uart_putchar('\r'); counter++; delay(1000); } }