Forum: Mikrocontroller und Digitale Elektronik Programm spinnt mit externem Quarz


von Philo (Gast)


Lesenswert?

Hi,

also ich hab folgendes Problem:

Ich habe ein Programm für meinen mega8-16PU geschrieben. Das Programm 
soll 2 LED's blinken lassen. 3 Taster und 2 LED's sind an den MC 
angeschlossen(an Port PD2-6). Einer der Taster soll die linke LED zum 
blinken bringen der andere die rechte LED und der dritte Schalter beide 
abwechselnd.Es hat auch geklappt.

Ich hab nun einen externen 16Mhz Quarz angeschlossen und das Programm 
als Test raufgespielt. Jedoch funktioniert es nicht mehr ;(

Ich hab erwartet, dass die LED's nicht mehr blinken sondern durchgehend 
leuchten da er ja schneller ist.
Und dachte wenn ich im Makefile den Eintrag F_CPU auf 16000000 
einstelle ändert sich das. Tat es aber nicht außerdem hat bei dem 
dritten Taster nur eine LED aufgeleuchtet statt beiden...

Hier der Code:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
4
int main(void){
5
  DDRD = 0x63;
6
  while(1){
7
    if((PIND & 0b00010000) == 16) {
8
      PORTD = 0x40;
9
      _delay_ms(20);
10
      PORTD = 0x00;
11
      _delay_ms(20);
12
    }else if((PIND & 0b00001000) == 8) {
13
      PORTD = 0x40;
14
      _delay_ms(20);
15
      PORTD = 0x20;
16
      _delay_ms(20);
17
    }else if((PIND & 0b00000100) == 4) {
18
      PORTD = 0x20;
19
      _delay_ms(20);
20
      PORTD = 0x00;
21
      _delay_ms(20);
22
    }else{
23
      PORTD = 0x00;
24
    }
25
    
26
  }
27
  
28
  return 0;
29
}

Ich hoffe mal ihr könnt mir helfen :D

von Olli R. (omr) Benutzerseite


Lesenswert?

Fuses richtig gesetzt? Schaltplan?

Olli

von Philo (Gast)


Lesenswert?

Fuses:

LOW: EE
High: 99

Die Fuses hab ich mit dem Fuse Calc für den atmega8 benutzt da der 
mega8-16PU nicht angegeben ist.

Naja Schaltplan hab ich nicht parat. Das sind 3 Taster mit 33k Pullup 
Widerstand an Port PD2,PD3 und PD4 und 2 LED'S an PD5 und PD6.

16 Mhz Quarz mit 2Kondensatoren(22pF) zur Masse.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> _delay_ms(20);

Wie war das mit dem _delay_ms() ?
1
The maximal possible delay is 262.14 ms / F_CPU in MHz.
262/16 = 16,37

Also dürfte dort höchstens
_delay_ms(16);
stehen   :-o

von Christian Erker (Gast)


Lesenswert?

Wenn du schon pastest, dann richtig!
1
The maximal possible delay is 262.14 ms / F_CPU in MHz.
2
3
When the user request delay which exceed the maximum possible one,
4
_delay_ms() provides a decreased resolution functionality. In this
5
mode _delay_ms() will work with a resolution of 1/10 ms, providing
6
delays up to 6.5535 seconds (independent from CPU frequency).  The
7
user will not be informed about decreased resolution.

AVR-GCC 20081205

Gruß,
Christian

von spess53 (Gast)


Lesenswert?

Hi

>Die Fuses hab ich mit dem Fuse Calc für den atmega8 benutzt da der
>mega8-16PU nicht angegeben ist.

Dir ist aber bewusst, das die Fusebit bei unterschiedlichen AVRs auch 
unterschiedliche Funktionen haben? Das kann für sehr unliebsame 
Überraschungen sorgen.

MfG Spess

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Tat es aber nicht außerdem hat bei dem
> dritten Taster nur eine LED aufgeleuchtet statt beiden...
Ein wenig scheint er ja zu tun... :-/
Und jetzt stell dir mal vor, die Delays würden nicht funktionieren.
Dann würde ich erwarten, dass z.B. von oberen und unteren Fall:
1
      PORTD = 0x40;
2
      _delay_ms(20);
3
      PORTD = 0x00;
4
      _delay_ms(20);
nur noch
1
      PORTD = 0x40;
2
      PORTD = 0x00;
und damit wirksam nur noch
1
      PORTD = 0x00;
übrig bleibt.

Im mittleren Fall wäre das dann
1
      PORTD = 0x50;
Also eine Leuchtdiode.


EDIT:
> AVR-GCC 20081205
Ja, das wissen wir aber nicht sicher, oder?
Siehe den Beitrag "Re: Problem mit _delay_ms()"

von Olli R. (omr) Benutzerseite


Lesenswert?

Philo wrote:

> Naja Schaltplan hab ich nicht parat. Das sind 3 Taster mit 33k Pullup
> Widerstand an Port PD2,PD3 und PD4 und 2 LED'S an PD5 und PD6.

Abblockkondensatoren? Resetbeschaltung?

Olli

von Johannes M. (johnny-m)


Lesenswert?

spess53 wrote:
> Hi
>
>>Die Fuses hab ich mit dem Fuse Calc für den atmega8 benutzt da der
>>mega8-16PU nicht angegeben ist.
>
> Dir ist aber bewusst, das die Fusebit bei unterschiedlichen AVRs auch
> unterschiedliche Funktionen haben? Das kann für sehr unliebsame
> Überraschungen sorgen.
Der ATMega8-16PU ist aber auch ein ATMega8, weshalb die Wahl korrekt 
ist. Das -16PU sagt lediglich, dass es sich um die "normale" 16 
MHz-Variante im PDIP-Gehäuse ("P") und RoHS-konform ("U") handelt. Das 
hat keinerlei Einfluss auf die Fuses.

von Johannes M. (johnny-m)


Lesenswert?

Philo wrote:
> Naja Schaltplan hab ich nicht parat. Das sind 3 Taster mit 33k Pullup
> Widerstand an Port PD2,PD3 und PD4 und 2 LED'S an PD5 und PD6.
Du weißt aber, dass der µC interne Pull-Ups hat? Da sind zusätzliche 
Verschwendung...

Und lies mal den Artikel Bitmanipulation. Wenn Du Ein- und Ausgänge 
am selben Port hast und beim Setzen der Ausgänge ständig den kompletten 
Port neu schreibst, kann alles Mögliche passieren. Auch mit externen 
Pull-Ups! Zumal 33 kOhm schon recht viel ist.

Die (fehlerträchtigen) Abfragen auf Gleichheit in den ifs ("== 4", "== 
8" usw.) lässt man besser ebenfalls weg.

von Philo (Gast)


Lesenswert?

>Dann würde ich erwarten, dass z.B. von oberen und unteren Fall:
>
>
1
PORTD = 0x40;
2
> _delay_ms(20);
3
> PORTD = 0x00;
4
> _delay_ms(20);
>
> nur noch
>
>
1
PORTD = 0x40;
2
> PORTD = 0x00;

das würde aber bedeuten dass bei den anderen Knöpfen gar keine LED mehr 
leuchten würde, oder?
Tun sie aber :D

> The maximal possible delay is 262.14 ms / F_CPU in MHz.

Falls es daran liegt wie kann ich das denn anders machen?

> Die (fehlerträchtigen) Abfragen auf Gleichheit in den ifs ("== 4", "==
> 8" usw.) lässt man besser ebenfalls weg.

Änder ich sofort ;) Aber soll ich dann != 0 nehmen?Oder noich was 
anderes gib ja mehrere Möglichkeiten

> Und lies mal den Artikel Bitmanipulation. Wenn Du Ein- und Ausgänge
> am selben Port hast und beim Setzen der Ausgänge ständig den kompletten
> Port neu schreibst, kann alles Mögliche passieren. Auch mit externen
> Pull-Ups! Zumal 33 kOhm schon recht viel ist.

Den Artikel werd ich mal zuendelesen. Und ich schließ die Tastere mal an 
einen anderen Port an.

Poste später nochmal wenn ich alles ausprobiert habe
Aber thx für die schnellen Antworten ;)

lg

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> das würde aber bedeuten dass bei den anderen Knöpfen gar keine LED mehr
> leuchten würde, oder?
> Tun sie aber :D
Steht aber nirgends  :-/
Fehlerbeschreibung mangelhaft, setzen!

von Johannes M. (johnny-m)


Lesenswert?

Philo wrote:
>> Die (fehlerträchtigen) Abfragen auf Gleichheit in den ifs ("== 4", "==
>> 8" usw.) lässt man besser ebenfalls weg.
>
> Änder ich sofort ;) Aber soll ich dann != 0 nehmen?Oder noich was
> anderes gib ja mehrere Möglichkeiten
Ich schrieb doch "weglassen". Also einfach
1
if(PIND & 0b00010000)
oder noch besser
1
if(PIND & (1 << PIND4))
Die Bedingung in den Klammern ist dann wahr, wenn der Ausdruck etwas 
anderes als Null ergibt. Und "PIND & (1 << PIND4)" egibt nunmal entweder 
0 (wenn PIND.4 nicht gesetzt ist) oder (1 << PIND4), was gleichbedeutend 
mit 16 oder 0x10 oder 0b00010000 und ungleich Null ist.

In C ist alles wahr was nicht falsch ist, und falsch ist ausschließlich 
die Null.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> In C ist alles wahr was nicht falsch ist,
> und falsch ist ausschließlich die Null.
Das ist wahr   ;-)

von Philo (Gast)


Angehängte Dateien:

Lesenswert?

> ...Ich schrieb doch "weglassen"...

gut mach ich :D

so das löst das Problem aber nicht... ;(

Ich schätze mal es liegt an dem makro _delay_ms(), oder?
Aber wie lösich das anders?

Geht es wenn ich einfach die Funktion in eine for schleife stecke?
1
 for(i=0; i==2; i++){ 
2
  _delay_ms(1);
3
}

Das mit den verschiedenen Ports ist es glaub ich nicht das es ja mit dem 
internen Quarz geht...(muss den Artikel immernoch durchleden :D)

>Fehlerbeschreibung mangelhaft, setzen!

Also ich beschreib das mal genauer:

Wenn man Taster 1 Drückt soll die LED1 aufblinken. Stattdessen leuchtet 
LED1 durgehend

Wenn man Taster 2 drückt sollen beideabechselnd leuchten. Stattdessen 
leuchtet nur LED2 durchgehend.

Wenn man Taster 3 drückt soll LED2 aufblinken. Stattdessen leuchtet LED2 
durchgehend

So genehm :D

von Johannes M. (johnny-m)


Lesenswert?

Philo wrote:
> Geht es wenn ich einfach die Funktion in eine for schleife stecke?
>
1
 for(i=0; i==2; i++){
2
>   _delay_ms(1);
3
> }
Im Prinzip keine schlechte Idee. Allerdings wird die Schleife, so wie 
sie da steht, gar nicht durchlaufen. Schau bitte mal in einem C-Buch 
nach, wie das mit den for-Schleifen geht...

> Das mit den verschiedenen Ports ist es glaub ich nicht das es ja mit dem
> internen Quarz geht...(muss den Artikel immernoch durchleden :D)
Einen internen Quarz gibt es nicht! Die interne Taktquelle ist ein 
RC-Oszillator und kein Quarz!

Und wenn Du Dich wunderst, dass die LEDs konstant leuchten: Das ist kein 
Wunder. Sie blinken ja auch mit 50 Hz, und das sollte schon zumindest 
schwierig sein, das optisch aufzulösen...

Taster schließt man übrigens üblicherweise gegen GND an, weil man dann 
die internen Pull-Ups benutzen kann.

Dass die LED an PORTD.2 gar nicht leuchtet, liegt daran, dass der Pin 
als Eingang konfiguriert ist ("DDRD = 0x63;" konfiguriert nur die Pins 
0, 1, 5 und 6 als Ausgänge). Bitte gewöhne Dir für alle Steuerbits die 
in Bitmanipulation beschriebene Schreibweise an! Dann passieren 
solche Sachen gar nicht erst. Und dass das mit dem internen Takt klappt, 
halte ich für ein Gerücht...

von Philo (Gast)


Lesenswert?

> ("DDRD = 0x63;" konfiguriert nur die Pins 0, 1, 5 und 6 als Ausgänge).

Richtig :D
0x63 = 0b01100011 AN PORTD" ist garkeine LED sondern ein Taster >.<  :D

> Bitte gewöhne Dir für alle Steuerbits die in Bitmanipulation beschriebene
> Schreibweise an!

Mach ich. Ich find das jedoch sehr unangenehm :´(

> Im Prinzip keine schlechte Idee. Allerdings wird die Schleife, so wie
> sie da steht, gar nicht durchlaufen. Schau bitte mal in einem C-Buch
> nach, wie das mit den for-Schleifen geht...

o.O habs nicht bemerkt :D
so natürlich :DD:
[c]for(i=0; i <= 20; i++){
     _delay_ms(1);
 }[/]

lg

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

1
for(i=0; i <= 20; i++)   
2
   _delay_ms(1);
Soweit ok, wird aber 21 mal durchlaufen  ;-)

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.