Entwickler-Ecke

Off Topic - Amtel AVR - C - Assembler


Nersgatt - So 07.11.10 21:30
Titel: Amtel AVR - C - Assembler
Moin,

ich weiß, dass Mikrocontrollerprogrammierung nicht wirklich hier her passt. Aber hier gibts ja einige schlaue Leute, daher hoffe ich auf Hilfe.
Meine Kenntnisse in C und Assembler sind seeeehr - sagen wir mal - rudimentär :D

Es geht um ein Programm, geschrieben in C für einen Amtel ATMEGA8515. Ich möchte auf einem LCD-Display sowas wie eine Progressbar anzeigen.

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
void bargraphEx (uint8_t spalte, uint8_t max_wert, uint8_t wert) {

    uint8_t laenge;
    uint8_t voll, einzeln;
    int8_t i;

    /* Länge berechnen */
    laenge = (wert / max_wert) * (5 * 8);

    /* volle Kästchen und Teil-Kästchen berechnen */
    voll = laenge / 5;
    einzeln = laenge % 5;


    lcd_setcursor(spalte, 0);
    
    // Volle Kästchen ausgeben, ASCII Code 0xFF, siehe Datenblatt
    for (i=0; i<voll; i++) 
    lcd_data(0xFF);

    // letztes Kästechen, clever über Sonderzeichen mit 0..4 senkrechten
    // Streifen
    if (i != LCD_MAX_CHAR_PER_LINE) {
        lcd_data(einzeln);

        // Den Rest löschen

        i = LCD_MAX_CHAR_PER_LINE - voll - 1;

        while(i>0) {
            lcd_data(' ');
            i--;
        }
    }
}


Dabei gehts mir eigentlich nur um die erste Zeile der Prozedur. Irgendwie wird sie nicht komplett ausgeführt.
Im Disassembler sieht das so aus:
disassembler

Bei max_wert 100 und wert 10 würde ich erwarten, dass in laenge 4 steht. Tuts aber nicht. Ich sehe auch gar keinen Zugriff auf R22, das macht mich schon mal stutzig. Kann mir jemand das erklären??? :gruebel:

Danke!


jfheins - So 07.11.10 22:19

Logo.

Integerdivision rundet ab. 10/100 => 0

Du kannst das aber mit der Reihenfolge beeinflussen. Wenn du die Variablen auf 16 bit erweitern kannst und dann

laenge = (wert * 40) / max_wert;

schreibst, sollte es gehen ;)


F34r0fTh3D4rk - So 07.11.10 22:45

Ändere die Zeile mal in:

C#-Quelltext
1:
laenge = (40*wert)/maxwert;                    

Prinzipiell gilt: Dividiere ganz am Ende, vermeide, dass der Compiler auf die Idee kommt, zwischen drin abzurunden. Das ist aber nicht nur in C so.

Der gemeine user profile iconjfheins hat meine Lösung geklaut :(


Nersgatt - So 07.11.10 22:50

Ich bedanke mich recht herzlich. :zustimm:


jfheins - So 07.11.10 22:50

user profile iconF34r0fTh3D4rk hat folgendes geschrieben Zum zitierten Posting springen:
Ändere die Zeile mal in:

C#-Quelltext
1:
laenge = (40*wert)/maxwert;                    

Prinzipiell gilt: Dividiere ganz am Ende, vermeide, dass der Compiler auf die Idee kommt, zwischen drin abzurunden. Das ist aber nicht nur in C so.

Das geht aber nur, wenn es dabei zu keinem Überlauf kommt. Bei der Benennung würde ich aber glatt mal 8 bit Variablen vermuten. (Nein, ich habe keine Lust, mir das Datenblatt zu suchen)
user profile iconF34r0fTh3D4rk hat folgendes geschrieben Zum zitierten Posting springen:
Der gemeine user profile iconjfheins hat meine Lösung geklaut :(

Wer zu spät kommt, den bestraft das Leben :P


F34r0fTh3D4rk - So 07.11.10 22:58

user profile iconjfheins hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconF34r0fTh3D4rk hat folgendes geschrieben Zum zitierten Posting springen:
Ändere die Zeile mal in:

C#-Quelltext
1:
laenge = (40*wert)/maxwert;                    

Prinzipiell gilt: Dividiere ganz am Ende, vermeide, dass der Compiler auf die Idee kommt, zwischen drin abzurunden. Das ist aber nicht nur in C so.

Das geht aber nur, wenn es dabei zu keinem Überlauf kommt. Bei der Benennung würde ich aber glatt mal 8 bit Variablen vermuten. (Nein, ich habe keine Lust, mir das Datenblatt zu suchen)

Stimmt, 16bit Integer machen an dieser Stelle mehr Sinn. Ich gehe mal davon aus, dass die größte Eingabe 100 ist, dann ist 40*100 = 4000 schon etwas größer als 255 :mrgreen:
Zitat:

user profile iconF34r0fTh3D4rk hat folgendes geschrieben Zum zitierten Posting springen:
Der gemeine user profile iconjfheins hat meine Lösung geklaut :(

Wer zu spät kommt, den bestraft das Leben :P

Nur war ich leider eine Minute vor dir :twisted: