Benutzer:Martin: Unterschied zwischen den Versionen
Martin (Diskussion | Beiträge) |
Martin (Diskussion | Beiträge) K (+ Labortage 2022 / Workshop Code Golf) |
||
(6 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
Zeile 11: | Zeile 11: | ||
== Meine Vorträge == | == Meine Vorträge == | ||
* [https://madex.github.io/CodeGolfWorkshop/workshop.html Labortage 2022 / Workshop Code Golf] | |||
* [[Vortragsprogramm/2011/Optimierung durch Ganzzahlarithmetik für Microcontroller]] | * [[Vortragsprogramm/2011/Optimierung durch Ganzzahlarithmetik für Microcontroller]] | ||
* [[Vortragsprogramm/2010/Lightning Talks]] Multitasking ohne Betriebssytem im Mikrokontroller | * [[Vortragsprogramm/2010/Lightning Talks]] Multitasking ohne Betriebssytem im Mikrokontroller | ||
Zeile 18: | Zeile 19: | ||
== Meine Projekte == | == Meine Projekte == | ||
* [[Borg3d]] | * [[Borg3d]] | ||
* [[Farb Borg 3d]] | * [[Farb Borg 3d]] | ||
* Portierung des [[Farb Borg 3d]] auf Cortex M3 | * Portierung des [[Farb Borg 3d]] auf Cortex M3 | ||
* Optisches Stimmgerät [[Stimmmopped]]. | * Optisches Stimmgerät [[Stimmmopped]]. | ||
* Weitere Projekte auf meiner [https://github.com/madex github-Seite] | |||
== Mein Sudoku Solver == | == Mein Sudoku Solver == | ||
#include <stdio.h> | #include <stdio.h> | ||
Zeile 54: | Zeile 57: | ||
== Hilfreiche Funktionen == | == Hilfreiche Funktionen == | ||
Da ich viel mit Mikrocontrollern mache, hapert es oft an grundlegenden Ausgabemöglichkeiten. Dann sucht man sich immer den Wolf, oder kopiert die Sachen aus alten Projekten, so dass ich hier einfach mal so ein paar optimierte Lösungen zum rauskopieren liegen habe. Viele sind auf Geschwindigkeit getrimmt, oder haben besondere lieb gewonnene Eigenschaften. | |||
char* itoa(signed long val) { | char* itoa(signed long val) { | ||
/** Die Ausgabe von itoa(i) ist identisch zu | /** Die Ausgabe von itoa(i) ist identisch zu | ||
Zeile 307: | Zeile 312: | ||
} | } | ||
return result * sign; | return result * sign; | ||
} | |||
=== hexdump nur mit putchar === | |||
void hexDump(char *description, void *basisAddr, void *startAddr, unsigned long len) { | |||
unsigned char i = 0; | |||
unsigned long tempAdr; | |||
char hex[] = "0123456789abcdef"; | |||
unsigned char buff[17], *ptrBuf; | |||
unsigned char *pc = (unsigned char*) startAddr; | |||
if (description != NULL) { | |||
while (*description) | |||
putchar(*description++); | |||
putchar('\n'); | |||
} | |||
while (len--) { | |||
if (i >= 16) { | |||
i = 0; | |||
putchar(' '); | |||
putchar(' '); | |||
ptrBuf = buff; | |||
while (*ptrBuf) | |||
putchar(*ptrBuf++); | |||
putchar('\n'); | |||
} | |||
if (i == 0) { | |||
putchar(' '); | |||
putchar(' '); | |||
tempAdr = pc - (unsigned char*) basisAddr; | |||
putchar(hex[(tempAdr >> 28) & 0xf]); | |||
putchar(hex[(tempAdr >> 24) & 0xf]); | |||
putchar(hex[(tempAdr >> 20) & 0xf]); | |||
putchar(hex[(tempAdr >> 16) & 0xf]); | |||
putchar(hex[(tempAdr >> 12) & 0xf]); | |||
putchar(hex[(tempAdr >> 8) & 0xf]); | |||
putchar(hex[(tempAdr >> 4) & 0xf]); | |||
putchar(hex[tempAdr & 0xf]); | |||
putchar(' '); | |||
} | |||
putchar(' '); | |||
putchar(hex[(*pc >> 4) & 0xf]); | |||
putchar(hex[*pc & 0xf]); | |||
if ((*pc < 0x20) || (*pc > 0x7e)) | |||
buff[i] = '.'; | |||
else | |||
buff[i] = *pc; | |||
buff[i + 1] = '\0'; | |||
pc++; | |||
i++; | |||
} | |||
while (i++ < 16) { | |||
putchar(' '); | |||
putchar(' '); | |||
putchar(' '); | |||
} | |||
putchar(' '); | |||
putchar(' '); | |||
ptrBuf = buff; | |||
while (*ptrBuf) | |||
putchar(*ptrBuf++); | |||
putchar('\n'); | |||
} | } |
Aktuelle Version vom 19. Dezember 2022, 18:47 Uhr
Seit dem ersten Mikrokontollerworkshop (2005) bin ich im Labor aktiv. Zu meinen beliebtesten Projkten zählt der Borg3d sowie der Farb Borg 3d die ich entwickelt, erbaut und programmiert habe.
Meine Interessen liegen in der Programmierung von C und C++ auf Microcontrollern wie den AVR, Soc-lm32, Arm Cortex M3 aber auch auf PC.
Ich setze Mac OSX schon seit etlichen Jahren und helfe gerne bei Fragen zu OSX.
Außerdem spiele ich Bass in einer Band und beschäftige mich in meiner Freizeit auch viel mit Musik.
Man kenn mich auch als madex (oder Martin3D wegen den großen Intresse an Dreidiminsionalität).
Meine Vorträge[Bearbeiten | Quelltext bearbeiten]
- Labortage 2022 / Workshop Code Golf
- Vortragsprogramm/2011/Optimierung durch Ganzzahlarithmetik für Microcontroller
- Vortragsprogramm/2010/Lightning Talks Multitasking ohne Betriebssytem im Mikrokontroller
- Farbborgvortrag Labortage 09
- Crashkurs C-Programmierung für 16x16x16 Borg 3D für Felix 3d in Stade
- Grundlagen der 3D-Grafik mit OpenGL
Meine Projekte[Bearbeiten | Quelltext bearbeiten]
- Borg3d
- Farb Borg 3d
- Portierung des Farb Borg 3d auf Cortex M3
- Optisches Stimmgerät Stimmmopped.
- Weitere Projekte auf meiner github-Seite
Mein Sudoku Solver[Bearbeiten | Quelltext bearbeiten]
#include <stdio.h> #define _ 0 #define S(x) x, #define D(x) x x x #define L(x) D(S(x)) #define R(x) D(D(S(x))) #define E(f,x) f(x)f(x+1)f(x+2) char sudoku[] = { 1, _, _, _, _, 7, _, 9, _, _, 3, _, _, 2, _, _, _, 8, _, _, 9, 6, _, _, 5, _, _, _, _, 5, 3, _, _, 9, _, _, _, 1, _, _, 8, _, _, _, 2, 6, _, _, _, _, 4, _, _, _, 3, _, _, _, _, _, _, 1, _, _, 4, _, _, _, _, _, _, 7, _, _, 7, _, _, _, 3, _, _, }; char c[]={E(R,0)E(R,3)E(R,6)},q[]={D(D(E(S,0)E(S,3)E(S,6)))},w[]={D(E(L,0)) D(E(L,3))D(E(L,6))};v(char *b, char *r){int l[]={R(0)0},i=82,f,s;for(;--i;l[s] |=1<<f){f=*b++;s=*r++;if(f&&s<9&&l[s]&(1<<f))return 0;}return 1;}h(char *b,char **r){char *o;while(o=*r++)if(!v(b,o))return 0;return 1;}t(char n,char *b,char **r){char i=1;while(1){if(n>80)return 1;if(!b[n])break;n++;}for(;i<10;i++){ b[n]=i;if(h(b,r))if(t(n+1,b,r))return 1;}b[n]=0;return 0;}p(char*b){char j=0,l= 0,i=82;for(;--i;){printf(" %d",*b++);if((j%3)==2)printf(" ");if(++j==9){if(( l++%3)==2)puts("");j=0;puts("");}}}main(){char *b=sudoku,*r[]={q,c,w,0};p(b); if(t(0,b,r)){puts("solution:");p(b);}else puts("no solition found");return 0;}
Hilfreiche Funktionen[Bearbeiten | Quelltext bearbeiten]
Da ich viel mit Mikrocontrollern mache, hapert es oft an grundlegenden Ausgabemöglichkeiten. Dann sucht man sich immer den Wolf, oder kopiert die Sachen aus alten Projekten, so dass ich hier einfach mal so ein paar optimierte Lösungen zum rauskopieren liegen habe. Viele sind auf Geschwindigkeit getrimmt, oder haben besondere lieb gewonnene Eigenschaften.
char* itoa(signed long val) { /** Die Ausgabe von itoa(i) ist identisch zu * sprintf(buf, "%d", i); * für den gesamten signed 32 bit Bereich. Selbst auf dem PC wesentlich schneller. */ static char buf[13]; // vorsicht beim nächsten Aufruf von itoa ist str weg. char *sBuf = &buf[12]; unsigned char negative = val < 0; unsigned long value, valueOld; *sBuf = 0; if (negative) value = (unsigned long) -val; else value = (unsigned long) val; do { valueOld = value; value /= 10; // auch div 10 *--sBuf = '0' + valueAlt - (value * 10); // schneller als % 10 } while (value); if (negative) *--sBuf = '-'; return sBuf; }
Ohne Multiplikation und Division[Bearbeiten | Quelltext bearbeiten]
char *itoa(int32_t zahl) { static uint32_t subtractors[] = {1000000000,100000000,10000000,1000000, 100000,10000,1000,100,10,1}; static char string[12]; char *str = string, n; uint32_t u, *sub = subtractors; uint8_t i = 10; if (zahl < 0) { *str++ = '-'; u = (uint32_t) -zahl; } else u = (uint32_t) zahl; while (i > 1 && u < *sub) { i--; sub++; } while (i--) { char n = '0'; while (u >= *sub) { n++; u -= *sub; } *str++ = n; sub++; } *str = 0; return string; }
Ohne Multiplikation und Division mit fester Breite[Bearbeiten | Quelltext bearbeiten]
char *itoaFixedWidth(int32_t zahl) { static uint32_t subtractors[] = {1000000000,100000000,10000000,1000000, 100000,10000,1000,100,10,1}; static char string[12]; char n, *str = string, sign = zahl < 0 ? '-' : ' '; uint32_t *sub = subtractors; uint32_t u = zahl < 0 ? (uint32_t) -zahl : (uint32_t) zahl; uint8_t i = 10; *str++ = ' '; while (i > 1 && u < *sub) { i--; sub++; *str++ = ' '; } *(str-1) = sign; while (i--) { n = '0'; while (u >= *sub) { u -= *sub; n++; } *str++ = n; sub++; } *str = 0; return string; }
Schnelle Division / 10 mit Hilfe von Multiplikation und Schieben[Bearbeiten | Quelltext bearbeiten]
// (uint64_t val) 26 bis 11184819 korrekt, (uint32_t val) 19 bis 81920 korrekt #define BITS 19 #define MUL (((1L << BITS)/10) + 1) unsigned long div10(unsigned long val) { return ((unsigned long) val * MUL) >> BITS; }
getestet mit:
void main() { int i; printf("Multipilkator %d fuer %d Bits\n", MUL, BITS); for (i = 0; i < 99999999; i++) { if ((i/10) != div10(i)) { printf("Error At %d: %d != %d\n", i, i/10, div10(i)); return; } } }
Konfortable Ausgabe[Bearbeiten | Quelltext bearbeiten]
char *itoaUint32VarLen(uint32_t value, uint8_t fillWith0, uint8_t lenghtInChars) { static uint8_t sBuf0[12]; // maximum Value -2147483649 = 12 uint8_t *sBuf = &sBuf0[11], *sBufWerteBegrenzung; uint32_t valueAlt; // Alte Wert für schneller % 10 Berechnung *sBuf = 0; if (value == 0) { *--sBuf = '0'; lenghtInChars--; } else while (value) { if (!lenghtInChars) { sBufWerteBegrenzung = sBuf; while (sBufWerteBegrenzung < &sBuf0[11]) *sBufWerteBegrenzung++ = '9'; break; } valueAlt = value; value /= 10; *--sBuf = '0' + valueAlt - (value * 10); // schneller als *--sBuf = '0' + (valueAlt % 10) lenghtInChars--; } while (sBuf > sBuf0 && lenghtInChars--) // mit Nullen auffüllen *--sBuf = fillWith0 ? '0' : ' '; return *sBuf; }
Formatierte Augabe[Bearbeiten | Quelltext bearbeiten]
char *itoaInt16Formated(int16_t value) { static uint8_t sBuf0[7]; uint8_t *sBuf = &sBuf0[6]; uint8_t minus; uint16_t valueAlt; // Alte Wert für schnellere % 10 Berechnung uint16_t valueCalc; // muss unsigned weil signed short kann kein 32768 *sBuf = 0; if (value < 0) { // Vorzeichen behandeln minus = '-'; valueCalc = -value; } else { minus = ' '; valueCalc = value; } do { valueAlt = valueCalc; valueCalc = div10(valueCalc); // schneller als valueCalc /= 10; *--sBuf = '0' + valueAlt - (valueCalc * 10); // schneller als *--sBuf = '0' + (valueAlt % 10) } while (valueCalc); *--sBuf = minus; // Minuszeichen vor die höchstwertigste Stelle setzen while (sBuf > sBuf0) // mit Leerzeichen auffüllen *--sBuf = ' '; return sBuf; }
Mit dem IAR Compiler egiebt das folgenden AVR Assembler Output. Ohne externe Abhängigkeiten.
itoaInt16Formated: MOV R3, R26 MOVW R23:R22, R25:R24 MOVW R25:R24, R17:R16 LDI R30, LOW((??sBuf0 + 6)) LDI R31, HIGH((??sBuf0 + 6)) LDI R16, 0 ST Z, R16 TST R17 BRPL ??itoaInt16Formated_0 LDI R26, 45 MOV R16, R24 NEG R17 NEG R16 SBCI R17, 0 RJMP ??itoaInt16Formated_1 ??itoaInt16Formated_0: LDI R26, 32 MOV R16, R24 ??itoaInt16Formated_1: MOV R18, R16 OR R18, R17 BREQ ??itoaInt16Formated_2 ??itoaInt16Formated_3: MOVW R21:R20, R17:R16 LDI R16, 205 LDI R17, 204 CLR R2 MUL R17, R21 MOVW R19:R18, R1:R0 MUL R17, R20 MOV R17, R0 ADD R18, R1 ADC R19, R2 MUL R16, R21 ADD R17, R0 ADC R18, R1 ADC R19, R2 MUL R16, R20 ADD R17, R1 ADC R18, R2 ADC R19, R2 MOVW R17:R16, R19:R18 LSR R17 ROR R16 LSR R17 ROR R16 LSR R17 ROR R16 MOV R18, R20 SUBI R18, 208 MOV R20, R16 LDI R19, 10 MUL R20, R19 SUB R18, R0 ST -Z, R18 MOV R18, R16 OR R18, R17 BRNE ??itoaInt16Formated_3 ??itoaInt16Formated_2: OR R24, R25 BRNE ??itoaInt16Formated_4 LDI R16, 48 ST -Z, R16 ??itoaInt16Formated_4: ST -Z, R26 LDI R16, LOW(??sBuf0) LDI R17, (??sBuf0) >> 8 CP R16, R30 CPC R17, R31 BRCC ??itoaInt16Formated_5 ??itoaInt16Formated_6: LDI R18, 32 ST -Z, R18 CP R16, R30 CPC R17, R31 BRCS ??itoaInt16Formated_6 ??itoaInt16Formated_5: MOVW R17:R16, R31:R30 MOVW R25:R24, R23:R22 MOV R26, R3 RET
atoi[Bearbeiten | Quelltext bearbeiten]
int atoi(const char *c) { int result = 0; int sign = 1; if (!c) return 0; while (*c == ' ') c++; if (*c == '-') { sign = -1; c++; } while (*c >= '0' && *c <= '9') { result *= 10; result += *c++ - '0'; } return result * sign; }
hexdump nur mit putchar[Bearbeiten | Quelltext bearbeiten]
void hexDump(char *description, void *basisAddr, void *startAddr, unsigned long len) { unsigned char i = 0; unsigned long tempAdr; char hex[] = "0123456789abcdef"; unsigned char buff[17], *ptrBuf; unsigned char *pc = (unsigned char*) startAddr; if (description != NULL) { while (*description) putchar(*description++); putchar('\n'); } while (len--) { if (i >= 16) { i = 0; putchar(' '); putchar(' '); ptrBuf = buff; while (*ptrBuf) putchar(*ptrBuf++); putchar('\n'); } if (i == 0) { putchar(' '); putchar(' '); tempAdr = pc - (unsigned char*) basisAddr; putchar(hex[(tempAdr >> 28) & 0xf]); putchar(hex[(tempAdr >> 24) & 0xf]); putchar(hex[(tempAdr >> 20) & 0xf]); putchar(hex[(tempAdr >> 16) & 0xf]); putchar(hex[(tempAdr >> 12) & 0xf]); putchar(hex[(tempAdr >> 8) & 0xf]); putchar(hex[(tempAdr >> 4) & 0xf]); putchar(hex[tempAdr & 0xf]); putchar(' '); } putchar(' '); putchar(hex[(*pc >> 4) & 0xf]); putchar(hex[*pc & 0xf]); if ((*pc < 0x20) || (*pc > 0x7e)) buff[i] = '.'; else buff[i] = *pc; buff[i + 1] = '\0'; pc++; i++; } while (i++ < 16) { putchar(' '); putchar(' '); putchar(' '); } putchar(' '); putchar(' '); ptrBuf = buff; while (*ptrBuf) putchar(*ptrBuf++); putchar('\n'); }