Falsche Berechnungen mit ATtiny26

OP #4448937
Lesenswert?
• ▲
▼
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
Lesenswert?
• ▲
▼
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
Lesenswert?
• ▲
▼
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

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

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.