Falsche Berechnungen mit ATtiny26

OP #4448937
Hallo,
Ich habe folgendes Programm auf einen ATtiny26 geflasht:
1
#include <avr/io.h>
2

3
#include <avr/interrupt.h>
4
#include <avr/sleep.h>
5

6
volatile uint16_t counter;
7
volatile uint32_t adcValue;
8

9
void showNumber(uint16_t value) {
10
    // Code zur Anzeige auf 7-Segment-Anzeigen ...
11
    // Verwendet Timer1 (zählt auch die "counter" Variable hoch)
12
}
13

14
void startAnalogConversion() {
15
    // Prepare ADC noise cancelling mode
16
    set_sleep_mode(SLEEP_MODE_ADC);
17
    sleep_mode();
18
    // Loop if the interrupt that woke the cpu was something other than the ADC finishing the reading
19
    while((ADCSR & (1<<ADSC)) != 0) {
20
        sleep_mode();
21
    }
22
    // Vordefinierter Wert zu Testzwecken
23
    adcValue = 200;
24
    
25
    showNumber(adcValue);             // funktioniert:       Zeigt 200 an.
26
    showNumber((adcValue * 50) / 55); // funktioniert:       Zeigt 181 an.
27
    showNumber((adcValue * 96) / 100);// funktioniert nicht: Zeigt 102 an.
28
}
29

30
void setup() {
31
    // Analog-Digital-Converter (ADC)
32
    ADMUX = (1<<REFS1) | (1<<REFS0); // select internal reference source (2.56V) and input channel ADC0
33
    ADCSR = (1<<ADEN)  | (1<<ADIE) | (1<<ADPS2);   // enables ADC with prescaler 16 and activates interrupt
34

35
    counter = 0;
36

37
    sei();
38

39
    startAnalogConversion();
40
}
41

42
int main(void)
43
{
44
    setup();
45
    
46
    for(;;) {
47
        if (counter >= 500) {
48
            counter = 0;
49
            startAnalogConversion();
50
        }
51
    }
52
    return 0;   /* never reached */
53
}
54

55
ISR(ADC_vect)
56
{
57
    adcValue = ADC;
58
}

In der Funktion "startAnalogConversion" möchte ich den Wert von 
"adcValue" * 0.96 rechnen. Diese Berechnung ( (adcValue * 96) / 100 ) 
funktioniert jedoch nicht so wie erwartet. Wenn adcValue den Wert 200 
hat, sollte das Resultat 192 sein. Es kommt jedoch immer 102 als 
Ergebnis raus. Im Anhang habe ich das verwendete Makefile angehängt.

Was könnte der Grund sein, dass diese Berechnung nicht funktioniert?

Beste Grüsse,
Sandro
Angehängte Dateien:
OP #4449151
A. K. schrieb:
> Bei Soll=192 und Ist=102 käme evtl. auch ein Fehler in der 7-Segment
> Ausgabe in Frage. Was kommt denn bei showNumber(192) raus?

bei showNumber(192) wird auch 102 ausgegeben. Muss wohl doch an der 
Ansteuerung der Anzeige liegen..

In showNumber extrahiere ich die einzelnen Ziffern, welche danach per 
Timer ISR an die 7-Segment-Anzeigen ausgegeben werden:
1
void showNumber(uint16_t value) {
2
    digits[0] = value / 100;
3
    value -= digits[0] * 100;
4
    digits[1] = value / 10;
5
    digits[2] = value - (digits[1] * 10);
6
}

Ich habe den Fehler gefunden. Da habe ich doch glatt etwas ganz banales 
übersehen. Ich habe in der Timer ISR geprüft, ob die Ziffer < 9 ist 
(müsste Ziffer < 10 sein). Falls nicht, wird "0" angezeigt.

Besten Dank für die vielen Tipps.
OP #4449156
Nobody schrieb:
> Das Auslesen von adcValue muss sowieso ATOMIC erfolgen.
> Aber das Problem würde dann nur sporadisch auftreten, wäre also eher
> schwer reproduzierbar.

Um adcValue korrekt auszulesen, muss ich folgende Schritte einbauen:
1. Die globalen Interrupts deaktivieren
2. adcValue auslesen
3. Die globalen Interrupts wieder aktivieren

Habe ich das so richtig verstanden?

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 10 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.