Forum: Mikrocontroller und Digitale Elektronik Arduino funktioniert nicht mit uint8_t


von Max (Gast)


Lesenswert?

Hallo,

wir behandeln im Rahmen einer Vorlesung Mikrocontroller.
Dies machen wir mit dem Arduino, allerdings ohne setup() und loop() und 
die Arduino-Funktionen sondern mit einer main() und einer while(1).

Ich habe auch schon einige Erfahrung mit Mikrocontrollern.
Nun habe ich ein kleines Problem, was mir und meinem Prof nicht ganz 
klar ist.

Zur Info: Ich nutze das AtmelStudio und die Arduino Software 1.6.12.
Durch eine Erweiterung kann ich im AtmelStudio programmieren und auch 
uploaden. Das Problem besteht in beiden Programmen.

Wenn ich nun ein Programm schreibe und eine
1
unsigned int xyz;
 erstelle, so funktioniert alles.

Nutze ich allerdings
1
uint8_t xyz;
 (egal wie viele Bit breit) so weigert sich der µC, irgendetwas zu 
machen.

Folgendes habe ich noch zum testen eingebunden:
1
#include <stdint.h>
2
#include <inttypes.h>
3
#include <avr/io.h>
4
#include <avr/interrupt.h>

Hat jemand eine Idee, woran das liegen kann?
Es ist jetzt nicht sooo mega wild. Allerdings wollte ich nun eine 16 Bit 
breite Variable erstellen und hab somit ein Problemchen ;)

von Jim M. (turboj)


Lesenswert?

Vollständigen Code posten. Auf Fehlermeldungen und Warnings des 
Compilers achten. Bei GCC: "-Wall" als Parameter schaltet viele Warnings 
an.

von iillii (Gast)


Lesenswert?

Schau Dir dir Datei stdint.h mal an. Dort müsste die Definition von 
uint8_t drin stehen. Tut sie das nicht?

von Max (Gast)


Lesenswert?

Das ging flott :)

Jim M. schrieb:
> Vollständigen Code posten. Auf Fehlermeldungen und Warnings des
> Compilers achten. Bei GCC: "-Wall" als Parameter schaltet viele Warnings
> an.

Code hänge ich ganz unten dran.
Habe mal alle Warnings aktiviert. Es kommt gar nix^^

iillii schrieb:
> Schau Dir dir Datei stdint.h mal an. Dort müsste die Definition
> von
> uint8_t drin stehen. Tut sie das nicht?

Nein, sie steht allerdings in "stdint-gcc.h". Die stdint.h verweist 
irgedwie auf sie.
Dort steht dies:
1
#ifdef __UINT8_TYPE__
2
typedef __UINT8_TYPE__ uint8_t;
3
#endif

C-Code ist noch nicht so viel. Gibt nur den Wert vom ADC 1x pro sek aus.
1
#include <stdint.h>
2
#include <inttypes.h>
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
6
#define INTERVALL 1000
7
8
volatile uint8_t result;
9
//volatile unsigned int result;
10
11
int main()
12
{
13
  //Arduino init(), da setup und loop nicht verwendet werden
14
  init();
15
  
16
  uint8_t zeit, prezeit;
17
  //unsigned int zeit, prezeit;
18
  zeit = prezeit = 0;
19
  
20
  Serial.begin(9600);
21
22
  //Interrupts global freigeben
23
  sei();
24
  
25
  // Den ADC aktivieren
26
  ADCSRA |= (1 << ADEN);
27
  // Teilungsfaktor auf 128 stellen
28
  ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
29
  // Kanal 0 des Multiplexers  -- Schon als 0 initialisiert, nur zur Sicherheit
30
  ADMUX &= ~( (1<<MUX0) | (1<<MUX1) | (1<<MUX2) | (1<<MUX3));
31
  // Interne 5V als Referenzspannung verwenden
32
  ADMUX |= (1 << REFS0);
33
  
34
  // AutoTrigger einschalten
35
  ADCSRA |= (1 << ADATE);
36
  // Triggerbedingung freilaufend
37
  ADCSRB &= ~((1 << ADTS2) | (1 << ADTS1) | (1 << ADTS0));
38
  // ADC Interrupt einschalten und starten
39
  ADCSRA |= (1 << ADIE) | (1 << ADSC);
40
    
41
  while (1)
42
  {
43
    //aktuelle Laufzeit
44
    zeit=millis();
45
    
46
    //Ergebnis jede Sekunde ausgeben
47
    if ((zeit-prezeit)>=INTERVALL)
48
    {
49
      Serial.println(result);
50
      prezeit=zeit;
51
    }
52
    
53
  }
54
}
55
56
57
ISR(ADC_vect) 
58
{
59
  //Wert speichern
60
  result = ADC;
61
}

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Max schrieb:
> Serial.println(result);

Da wird der Hase im Pfeffer liegen. Da hier C++ verwendet wird, wird 
eine der verschiedenen überladenen Varianten dieser Funktion aufgerufen, 
und mit uint8_t als Argument könnte das die Variante sein, die ein 
einzelnes Zeichen ausgibt, und nicht den numerischen Wert (was Du wohl 
erwartest).

Probier mal das hier aus:

Serial.println((unsigned int) result);

Ändert sich was?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Max schrieb:
>     if ((zeit-prezeit)>=INTERVALL)

Differenz zweier 8-Bit Werte wird >= 1000?

: Bearbeitet durch User
von Max (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Max schrieb:
>> Serial.println(result);
>
> Da wird der Hase im Pfeffer liegen. Da hier C++ verwendet wird, wird
> eine der verschiedenen überladenen Varianten dieser Funktion aufgerufen,
> und mit uint8_t als Argument könnte das die Variante sein, die ein
> einzelnes Zeichen ausgibt, und nicht den numerischen Wert (was Du wohl
> erwartest).
>
> Probier mal das hier aus:
>
> Serial.println((unsigned int) result);
>
> Ändert sich was?

Macht leider keinen Unterschied

Johann L. schrieb:
> Max schrieb:
>>     if ((zeit-prezeit)>=INTERVALL)
>
> Differenz zweier 8-Bit Werte wird >= 1000?

Da ist was dran^^
Allerdings funktioniert die Sekunde dennoch? :D

von R. F. (rfr)


Lesenswert?

Hallo all,


  //Arduino init(), da setup und loop nicht verwendet werden
  init();--> soweit ok.

  uint8_t zeit, prezeit;

-->also hier als Wert max 255.
  //unsigned int zeit, prezeit;

--> was soll denn dieser Kommentar?? Was das für ein Typ ist, kann ich 
doch links lesen. Schreib hier hin, was damit passiert. Also: zeit ist 
akt Laufzeit, prezeit ist...





  zeit = prezeit = 0;

  Serial.begin(9600);

  //Interrupts global freigeben
  sei();

  // Den ADC aktivieren
  ADCSRA |= (1 << ADEN);
  // Teilungsfaktor auf 128 stellen
  ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
  // Kanal 0 des Multiplexers  -- Schon als 0 initialisiert, nur zur 
Sicherheit

--> wieso?? entweder es geht oder nicht. Das ist 
Resourcenverschwendung!!



  ADMUX &= ~( (1<<MUX0) | (1<<MUX1) | (1<<MUX2) | (1<<MUX3));
  // Interne 5V als Referenzspannung verwenden
  ADMUX |= (1 << REFS0);

  // AutoTrigger einschalten
  ADCSRA |= (1 << ADATE);
  // Triggerbedingung freilaufend
  ADCSRB &= ~((1 << ADTS2) | (1 << ADTS1) | (1 << ADTS0));
  // ADC Interrupt einschalten und starten
  ADCSRA |= (1 << ADIE) | (1 << ADSC);

  while (1)
  {
    //aktuelle Laufzeit

--> nicht so knapp! Hier solltest du schreiben, was passiert.
    zeit=millis();

    //Ergebnis jede Sekunde ausgeben
    if ((zeit-prezeit)>=INTERVALL)

--> Das geht gar nicht. Die Differenz zweier uchar8_t ist niemals 
grösser als 1000. Hier wird nichts aufgerufen. Prüfe das durch 
fprintf-Anweisungen!!


    {
      Serial.println(result);
      prezeit=zeit;
    }

  }
}


ISR(ADC_vect)
{
  //Wert speichern
  result = ADC;
}

Gruss

Robert

: Bearbeitet durch User
von Brummbär (Gast)


Lesenswert?

R. F. schrieb:
> //unsigned int zeit, prezeit;
>
> --> was soll denn dieser Kommentar?? Was das für ein Typ ist, kann ich
> doch links lesen. Schreib hier hin, was damit passiert. Also: zeit ist
> akt Laufzeit, prezeit ist...

Wurde wohl nur testweise auskommentiert um etwas anders zu probieren.
Ich sehe darin kein Kommentar im eigentlichen Sinn.

von Keks (Gast)


Lesenswert?

> Da ist was dran^^
> Allerdings funktioniert die Sekunde dennoch? :D

Dann rechne doch stattdessen mit Hundertstel- oder Zehntelsekunden:
...
#define INTERVAL 10
...
zeit = millis/100;
...

von Max (Gast)


Lesenswert?

R. F. schrieb:
>   //unsigned int zeit, prezeit;
>
> --> was soll denn dieser Kommentar?? Was das für ein Typ ist, kann ich
> doch links lesen. Schreib hier hin, was damit passiert. Also: zeit ist
> akt Laufzeit, prezeit ist...

Das ist in dem Sinn kein Kommentar sondern habe ich das nur zum testen 
auskommentiert.

R. F. schrieb:
>   // Kanal 0 des Multiplexers  -- Schon als 0 initialisiert, nur zur
> Sicherheit
>
> --> wieso?? entweder es geht oder nicht. Das ist
> Resourcenverschwendung!!

Das stimmt. Da ich aber bei so einem Miniprogramm keine Platzproleme 
habe bzw Zeitprobleme sehe ich hier kein Problem ;)

R. F. schrieb:
>
>     //Ergebnis jede Sekunde ausgeben
>     if ((zeit-prezeit)>=INTERVALL)
>
> --> Das geht gar nicht. Die Differenz zweier uchar8_t ist niemals
> grösser als 1000. Hier wird nichts aufgerufen. Prüfe das durch
> fprintf-Anweisungen!!

Stimmt, das war das Problem.
Wenn man nur int nimmt, macht der Compiler wohl direkt eine 16 Bit 
Variable daraus. Bei uint8_t logischerweise nicht.
Daher DANKE :)
Du hast das Problem gelöst. Die Bedingung war, wie du sagst, nie 
erfüllt.

In dem Sinne vielen Dank an alle, die geholfen haben :))

von Peter D. (peda)


Lesenswert?

Max schrieb:
> volatile uint8_t result;
> ...
>   result = ADC;

10 Bit passen schlecht in 8Bit.

von R. F. (rfr)


Lesenswert?

"Wenn man nur int nimmt, macht der Compiler wohl direkt eine 16 Bit
Variable daraus. Bei uint8_t logischerweise nicht."

Der int ist 16 bit breit, hat aber ein Vorzeichen. Am besten ist hier 
die Verwendung von uint.


Ein long long geht aber auch  :-)

Grüsse

Robert

von Max (Gast)


Lesenswert?

R. F. schrieb:
> "Wenn man nur int nimmt, macht der Compiler wohl direkt eine 16
> Bit
> Variable daraus. Bei uint8_t logischerweise nicht."
>
> Der int ist 16 bit breit, hat aber ein Vorzeichen. Am besten ist hier
> die Verwendung von uint.
>
> Ein long long geht aber auch  :-)
>
> Grüsse
>
> Robert

Direkt wieder was gelernt :D
Ich dachte, wenn man auf einem 8-Bit µC arbeitet, wäre auch die 
Standardbreite 8 Bit.

Peter D. schrieb:
> Max schrieb:
>> volatile uint8_t result;
>> ...
>>   result = ADC;
>
> 10 Bit passen schlecht in 8Bit.

1000 Fehler mit sowas 0.o
Habe dann auch beide in einem Zug zu uint16_t geändert :D

von Irgendwer (Gast)


Lesenswert?

Max schrieb:
> Ich dachte, wenn man auf einem 8-Bit µC arbeitet, wäre auch die
> Standardbreite 8 Bit.

"Ich dachte", "ich glaube", "ich vermute", "ich nehme an" usw.
Mit solchen Wörtern fangen die meisten programmiertechnischen 
Katastrophen an.
Entweder man weiß es mit Sicherheit (weil man es schon mal 
nachgeschlagen hat) oder man liest es nach.

"- basic integer type. The keyword int may be omitted if any of the 
modifiers listed below are used. If no length modifiers are present, 
it's guaranteed to have a width of at least 16 bits......."
http://en.cppreference.com/w/cpp/language/types

von Dirk B. (dirkb2)


Lesenswert?

"Der Anfang jeder Katastrophe ist eine beschissene Vermutung."

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
Noch kein Account? Hier anmelden.