Hallo, ich habe ein Problem mit dem UART, das sich sicher leicht lösen lässt. Ich nutze einen EFM8SB1 MC von Silabs und möchte den Wert einer Stromquelle als Integer über den UART ausgeben. Der Strom nimmt maximal dreistellige Werte an (ist aber für später auf 4 ausgelegt). Die Beispiele zu anderen MCs habe ich mir angesehen, sie sagen mir als Anfänger aber wegen der anderen Bezeichnungen bei AVR und Arduino nicht viel. Meine Frage ist nun, wie ich diese Integer-Werte am besten in der richtigen Reihenfolge ausgebe, wie ich den Datentyp dafür anpassen muss und warum mein bisheriger Code nicht den gewünschten Wert 0xxx ausgibt, sondern nur Buchstaben. Ich habe mir gedacht, dass es mit einem Zählvariablen-Array am einfachsten geht, das zusammen mit dem Stromwert IREF0CN0 steigt und sinkt. Steigen und Sinken passiert identisch über jeweils eine Methode (Anhang). Die legt ein int-Array an (unschön realisiert), zählt dort hoch und kopiert dann am Ende die char-Werte der Zahlen in ein dafür vorgesehenes Array. Kann der UART das so lesen? Die Ausgabe erfolgt dann über SI_INTERRUPT (UART0_ISR, UART0_IRQn) { if(SCON0_TI==1) { IE|=IE_ES0__DISABLED; //disable UART interrupts SCON0_TI=0;//clear transmit flag bufPos=0; //type = int while(bufPos<3) { SBUF0=cvalc[bufPos]; //transmit bufPos++; } IE|=IE_ES0__ENABLED;//enable UART interrupts } … wobei das Transmit Flag in einer Timer ISR immer dann gesetzt wird, wenn der Strom steigt oder sinkt.
Die dreistellige Zahl wirst du wahrscheinlich in Ziffern (als char-BYTEs) zerlegen müssen, die du in geeigneter Reihenfolg an die UART für den Versand übergibst. Das Zerlegen geht über itoa() und Stringmanipulation, oder selbstgestrickten asm-Routinen. Kein Hexenwerk, aber einen Wurstel-Code im PNG-Format schau ich mir NICHT an! Beschreibe lieber, wie du da rangehst...
CharEiner = '0' + (i % 10); CharZehner = '0' + ((i/10) % 10); CharHunderter = '0' + ((i/100) % 10); PS: Lese mal in einem C-Buch den Abschnitt "Operatoren" durch und versuche den "Modulo-Operator" (%) zu verstehen.
Alles klar, ich reiche den Code zeitnah noch mal passend nach. Sorry. Er macht nichts anderes, als mit if-Abfragen hochzuzählen, von 0001 bis 0009, dann 0010 usw. Und dabei zerlegt er mehrstellige Zahlen in einzelne integer.
Nochmal als hoffentlich richtiges Format, Siehe increaseCval und decreaseCval.
In BCD zählen bis zum gesuchten Wert ?!? Das dauert ja ewig !!! Bei einem kurzen Blick auf das Bild von Deinem Quellcode sind mir 2 Dinge ins Auge gesprungen : - das arrptr zu Beginn eines Durchlaufes der for-Schleife auf 3 stehen muss, es aber Wege durch die Schleife gibt, die die Variable auf einem anderen Wert stehen lassen. - Du benötigst die einzelnen Ziffern vermutlich nicht als BCD im Bereich von 0...9 sondern als die ASCII-Codes der Ziffern. Schau Dir die Lösung von Markus M. (mmvisual) an, die ist einfacher und schneller als Deine. Kannst ja gerne Deine mal zum Laufen bringen. Wenn Du die verschiedenen Ziffern eh nicht in einer Schleife abhandelst kannst Du arrptr gerne rauskicken. Dann solltest Du aber mal die Zeit für die Ausgabe von 999 abstoppen. Danach versuche die andere Lösung zu verstehen und diese dann einbauen und schlussendlich nochmal die Zeit stoppen.
fop schrieb: > In BCD zählen bis zum gesuchten Wert ?!? Das dauert ja ewig !!! Auf einem 20 oder 24,5 MHz EFM8 dürfte das für 9600 Baud sogar ausreichend schnell sein - jedenfalls für einen Wertebereich bis 999. Die Dinger wuppen einiges weg. Die Lösung von Markus M. ist nicht nur schneller sondern auch kleiner, was bei nur 8KB Flash deutlich wichtiger sein wird.
fop schrieb: > Schau Dir die Lösung von Markus M. (mmvisual) an, die ist einfacher und > schneller als Deine. Werde ich machen. Vor allem geht es mir bei der Frage aber darum, wie der richtige Datentyp bzw ein Zahlenmuster der Art xxxx ausgegeben wird, und vor allem nur einmal pro Erhöhung. Habe das Programm gerade noch mal getestet und bekomme im Terminal nur einen wild umherspringenden Cursor und alles voller Nullen. Es wird wohl eher daran liegen, dass der UART Interrupt Befehl fehlerhaft ist.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.