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
unsignedintxyz;
erstelle, so funktioniert alles.
Nutze ich allerdings
1
uint8_txyz;
(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 ;)
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
volatileuint8_tresult;
9
//volatile unsigned int result;
10
11
intmain()
12
{
13
//Arduino init(), da setup und loop nicht verwendet werden
14
init();
15
16
uint8_tzeit,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
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?
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
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
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.
> Da ist was dran^^> Allerdings funktioniert die Sekunde dennoch? :D
Dann rechne doch stattdessen mit Hundertstel- oder Zehntelsekunden:
...
#define INTERVAL 10
...
zeit = millis/100;
...
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 :))
"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
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
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