hallo,
ich als Anfänger habe ein Problem was, so wie ich mir das denke,
wahrscheinlich garnicht realisierbar ist. Also ich habe eine Schaltung
(siehe Anhang: allerdings noch ohne Laserdiode) und möchte damit eine
Temperatur messen. Den Spannungwert schicke ich dann an ADC0 also im
falle meines Atmega16 PA0. Ab dort soll nun mein Programm den Wert
erstmal digitalisieren und danach am PortB wieder ausgeben. Hierbei
allerdings nur an einem Pin des PortB (in diesem Fall PB0). Hier soll
die Bitfolge einfach hintereinander weg ablaufen und für jede 0 0V und
jede 1 5V ausgeben. Da ich am Ausgang ein Ozziloskop angeschlossen habe
kann ich dieses auch überprüfen. Leider komme ich zu keinen brauchbaren
Ergebnissen. Ich werde direkt im Anschluss auch noch mein Code posten.
Ich hoffe jemand kann mir dabei helfen oder direkt sagen das ich das
ganz anders angehen muss.
mfg andre
Vorher natürlich noch PB0 als Ausgang konfigurieren:
DDRB |= 0x01;
Hab den Code nicht getestet und es gibt jede Menge Möglichkeiten, das
eleganter zu machen.
@Andre
F_CPU ist die Taktfrequenz deiner CPU. Diese muss natürlich vor dem
Include von delay.h bekannt sein. Ein paar Makros in delay.h wollen
nämlich damit Berechnungen anstellen.
danke für die schnellen antworten:)
ein paar kleine probleme sind hierbei jetz leider aufgetreten.
1. der ADC-Wert der sich hinter result verbirgt ist im uint16_t format.
Dadurch spuckt er mir den Fehler aus das die Datei declarationen nicht
ganz passen. Naja ist eigentlich nur ne Warnung.
2. und viel wichtiger ist: Ich habe garkeine delay.h :( jedenfalls sagt
er das beim kompilieren. Ich benutze das STK500 mit AVR Studio 4 falls
das irgendetwas ändert.
eine kleine Frage habe ich dann noch zu der Frequenz: lediglich den
Zahlenwert in der Definition angeben, d.h. bei mir 4 die ich über den
Externen Quarz habe oder 4 MHz?
mfg andre
Andre wrote:
> danke für die schnellen antworten:)>> ein paar kleine probleme sind hierbei jetz leider aufgetreten.>> 1. der ADC-Wert der sich hinter result verbirgt ist im uint16_t format.> Dadurch spuckt er mir den Fehler aus das die Datei declarationen nicht> ganz passen. Naja ist eigentlich nur ne Warnung.
Die allerdings in deinem Fall ernst zu nehmen ist. Aber das wirst du
schon noch sehen, wenn du dir die Werte erst mal extern ansiehst. :-)
> 2. und viel wichtiger ist: Ich habe garkeine delay.h :( jedenfalls sagt> er das beim kompilieren. Ich benutze das STK500 mit AVR Studio 4 falls> das irgendetwas ändert.
die ist in <util/delay.h>
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#avr-libc_Versionen_ab_1.6> lediglich den Zahlenwert in der Definition angeben, d.h. bei mir 4> die ich über den Externen Quarz habe oder 4 MHz?
#define F_CPU 4000000
danke schon mal im vorraus. compileren tut er jetz schon mal ohne
probleme. ich programmiere das mal fix auf meinen µc und versuche dann
die schaltung zu komplettieren.
mfg andre
hier nun noch mal die neue code-datei mit allen anpassungen. habe ich
noch irgendwelche fehler gemacht? beim declarieren erhalte ich jetz
keine warnungen oder fehler mehr.
mfg andre
upps... ja das hatte ich vorhin leicht hin und her verschoben... weil
irgendwer meinte das es besser sei die referenzspannung nicht jedesmal
neu einzustellen sondern nur einmal. aber so müsste es doch jetz stimmen
oder?
mfg andre
leider funktioniert anscheinend das programm immer noch nicht.
jedenfalls zeigt das ozilloskop keinen einzigen ausschlag auf 5V an die
spannung klemmt eher die ganze zeit auf 0V. ich habe langsam die
vermutung das ich mir veilleicht vorher schon den µc zerschossen haben
könnte. aber dann würde mein stk den doch garnicht mehr erkennen und
programmieren oder?
mfg andre
Haben wir alle übersehen
> uint16_t send_data(uint16_t data)> {> uint8_t i;> for (i=0; i<7; ++i)> {> if (data | 0x01) PORTB |= 0x01;> else PORTB &= 0xFE;> data <<= 1;
falsche Richtung. muss lauten
data >>= 1;
> _delay_ms(10);> }> return 0;> }
Gib halt mal zur Kontrolle das Datenbyte auch auf Port C aus. Dann hast
du eine Komponente (nämlich das Raustakten auf B) weniger, die
fehlerhaft sein kann.
Du kannst ja mal in der Endlosschlaufe nur send_data(0xAA) ausführen
lassen, dann siehst du schon mal, ob der Teil mit dem Port funktioniert.
So sollte der Pin ca. im 100ms Takt zwischen 0 V und 5 V wechseln.
Kleines Detail: Es genügt, PB0 nur einmal als Ausgang zu konfigurieren.
D. h. DDRB = 0xff; kannst du vor die Endlosschlaufe setzen.
Dein ganzer AD-Teil scheint mir ein wenig abeteuerlich. Lies nochmals
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#ADC_.28Analog_Digital_Converter.29
Mit welcher Auflösung möchtest du Sampeln? 8 Bit genügt in vielen
Fällen, und dann musst du schauen, dass das Ergebnis im ADC-Register
richtig ausgerichtet ist. Bei 8 Bit optimalerweise rechtsbündig.
Noch ein Detail: result /= 4; kann man auch als result >>= 2; schreiben.
Weiss nicht, ob der Compiler das sowieso schon optimisiert, aber schaden
tut's sicher nicht.
Und nochmals: Vielen Dank Karl Heinz, ich erschrecke immer wieder, wie
viele Fehler ich mache ;-)
Ralf Schwarz wrote:
> Noch ein Detail: result /= 4; kann man auch als result >>= 2; schreiben.> Weiss nicht, ob der Compiler das sowieso schon optimisiert, aber schaden> tut's sicher nicht.
Ja tut er. Ich kenn keinen einzigen Compiler, der das nicht drauf hat
(auch in schwierigeren Fällen, bei denen n keine 2-er Potenz ist)
Hier gilt die Regel: Schreibs so, wies für einen Menschen am klarsten
ist. Bei einem arithmetischen Mittel ist die Division sicherlich klarer
als irgendwelche Shifts. Alles andere überlass dem Compiler. Der kennt
schon noch ein paar Tricks um Taktzyklen zu sparen, die 95% aller C
Programmierer nicht kennen. Und die, die wir alle kennen, die hat er
sowieso drauf.
Das ermöglicht dann auch, einen potentiellen Fehler zu vermeiden (den
der OP glaub ich sogar schon gemacht hat)
1
#define SAMPLES 4
2
3
uint16_tReadChannel()
4
{
5
uint8_ti;
6
uint16_tresult;
7
ADCSRA|=(1<<ADSC);
8
while(ADCSRA&(1<<ADSC))
9
;
10
result=ADCW;
11
result=0;
12
for(i=0;i<SAMPLES;i++)
13
{
14
ADCSRA|=(1<<ADSC);
15
while(ADCSRA&(1<<ADSC))
16
;
17
18
result+=ADCW;
19
}
20
returnresult/SAMPLES;
21
}
und schon kann es nicht mehr passieren, dass mit einer anderen Zahl
dividiert wird als der Anzahl an Messungen. Und einfach anzupassen ist
diese Anzahl dann auch :-)
Die ADC Routine hab ich mir jetzt nicht weiter im Detail angesehen. Im
kurzen Überfliegen ist mir nichts mehr ins Auge gestochen
hi
nachdem ich jetz all eure weitern hinweise beherzigt habe und auch mal
die ports durchprobiert habe und sogar auf internen takt zurückgestellt
habe um auszuschlißen das der quarz kaputt ist gehe ich davon aus das er
µc kaputt ist denn es rührt sich immer noch garnichts an den ausgängen.
sagt zumindestens mein ozilloskop. bei dem gehe ich allerdings davon aus
das es funktioniert da es alles andere problemlos messen kann. ich danke
euch trotz dessem und hoffe das das programm und die schaltung mit einem
neuen µc funktioniert. falls irgendeinem noch etwas in meinem programm
auffällt das totaler blödsinn ist meldet ecuh bitte:)
mfg andre
ich habe eben mit erstaunen entdeckt das ich mit dem abgeänderten
programm an PC3 und PC5 um die 3,5V anliegen habe... allerdings auch
ständig ohne das sich an dem wert was ändert. da ich im programm
allerdings den gesamten port als ausgang geschaltet habe und auch auf
den gesamten port meine daten sende müsste meiner meinung auf dem
gesamten port auch dasselbe ausgangssignal anliegen oder? die restlichen
pins von portc sind übrigens auf 0V. es ist aber auch immer noch ein und
der selbe µc. habe es noch nicht geschafft einen neuen zu besorgen.
mfg andre
> µc kaputt ist denn es rührt sich immer noch garnichts an den ausgängen.
In so einem Fall fall ich sofort zurück auf Plan Alpha:
Schalt einfach mal an einem Port das Bitmuster 0xAA auf und schau nach
ob abwechselnd ein Pin 0 bzw. 1 ist.
Wenn das kommt, dann ist der µC nicht defekt
int main()
{
DDRB = 0xFF;
PORTB = 0xAA;
while( 1 )
;
}
Mega16 und Probleme am Port C. Das JTAG hast du per Fuse abgeschaltet?
Wie programmierst du eigentlich deinen Mega16. In deinem Schaltplan da
oben ist kein ISP Interface eingezeichnet.
Welchen Programmer benutzt du (ist mir passiert: benutzte einen
Minimalprogrammer direkt am Parallelport vom PC, und das sch... Windows
hat mir den Prozessor ständig im Reset gehalten)
ja das habe ich angewendet. im send_data und auch einfach im
main-programm. aber kein resultat... alle pins bleiben tot bis auf die
beiden pins von portc, was sehr verwunderlich ist. anbei ist nochmals
das programm, nicht das ich da was falsch interpretiert habe. bei der
simulation im avr zeigt er mir das auch schön an. nur mein
microcontroller macht irgendwie nix von dem was ich ihm auftrage...
mfg
achso ich benutze ein stk500. die fusebits sind eigentlich im default
zusatnd bis auf der externe takt den ich auf EXT. Crystal/resonator
gestellt habe. sonst würde er ja meinen quarz garnicht verwenden. laut
dem avr-studio benutze ich PP/HVSP als programm mode. also keine in
system programmierung. die einstellungen auf dem board sind auch
dementsprechend.
positiv ist nachdem ich jtag ausgeschaltet habe habe ich keine 3,5V mehr
auf PC3 und PC5:) leider habe ich niergenswo irgendwelche V. alles ist
auf 0V. ich fand aber die idee mit dem reset sehr interessant. kann das
auch mit dem stk500 passieren? oder kann es sein das ich mich durch die
fusebits aus dem µc ausgesperrt habe? vielleicht läuft er ja einfach
garnicht mehr an...
mfg
Mit dem STK500 sollte es solche Probleme eigentlich nicht geben.
Was ist mit einem Minimalprogramm? Einfach mal einen Port komplett auf 1
setzen
int main()
{
DDRC = 0xFF;
PORTC = 0xFF;
while( 1 )
;
}
machen die Pins mit?
(So ein Testprogramm ist in 0 Komma Nix geschrieben und es geht nur
darum festzustellen, ob den µC schon geschrottet ist oder nicht, ob du
dich ausgesperrt hast, ob die Programmierung klappt, ...)
Eine eigene Frage?
Dieser Thread ist über 17 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.