PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Fuse-Bit nicht sichtbar // Frage zu einem Programm



gioR
15.12.2018, 08:43
Hallo zusammen,


ich beschäftige mich aktuell mit dem Atmega 8.
Der Prozessor wird wie ich mehrfach gelesen habe mit gesetztem Fuse-Bit CKIV8 ausgeliefert.
Leider wird dieses Fuse-Bit bei mir nicht im Atmel Studio 7 angezeigt. (Programmer oben links sichtbar)

Kann mir jemand sagen woran das liegt?

33851


Eine andere Frage noch:

Ich bin aktuell dabei einen Schalt-blitz für mein Auto zu programmieren.
Die ADC-Wandlung funktioniert soweit und auch. Bei Steigender Spannung gehen die LEDS nacheinander an.
Nun möchte ich aber die letzte LED beim erreichen blinken lassen...

Wie setze ich das am einfachsten um?
Delay einfügen funktioniert ja nicht, da sonst das ganze Programm "gebremst" wird.
Ich brauche nur einen Tipp... Evtl Timer?

Danke und Viele Grüße :-)

markusj
15.12.2018, 10:19
ich beschäftige mich aktuell mit dem Atmega 8.
Der Prozessor wird wie ich mehrfach gelesen habe mit gesetztem Fuse-Bit CKIV8 ausgeliefert.
Leider wird dieses Fuse-Bit bei mir nicht im Atmel Studio 7 angezeigt. (Programmer oben links sichtbar)

Doch, wird es. Die komplette Information versteckt sich in der letzten Zeile (LOW.SUTC_KSEL). Damit stellst du die Taktquelle ein, im Hintergrund passt Atmel Studio dann die nötigen Fusebits an.


Ich bin aktuell dabei einen Schalt-blitz für mein Auto zu programmieren.
Die ADC-Wandlung funktioniert soweit und auch. Bei Steigender Spannung gehen die LEDS nacheinander an.
Nun möchte ich aber die letzte LED beim erreichen blinken lassen...

Wie setze ich das am einfachsten um?
Delay einfügen funktioniert ja nicht, da sonst das ganze Programm "gebremst" wird.
Ich brauche nur einen Tipp... Evtl Timer?

Timer ist ein gangbarer Weg. Entweder lässt du den Timer dann direkt die LED an- und ausschalten, oder du löst damit einen Interrupt aus und wackelst selbst am Pin.

Viele Grüße,
Markus

oberallgeier
15.12.2018, 11:03
Den Hinweis auf LOW.SUTC_KSEL hatte ja schon markusj gegeben.


.. ich beschäftige mich aktuell mit dem Atmega 8. Der Prozessor wird wie ich mehrfach gelesen habe mit gesetztem Fuse-Bit CKIV8 ausgeliefert ..Da hast Du falsche Auskünfte bekommen/gelesen. Ein Fuse-Bit CKIV8 existiert beim mega8 nicht (heißt aber, WENN es existiert, z.B. CKDIV8.) - die Takte können im Studio7, wie von markusj beschrieben wurde, eingestellt werden. Dies nur als Ergänzung zum Hinweis von Markus.

Nachtrag: es lohnt sich immer das spezifische Datenblatt zu lesen. Ohne das zugehörige Datenblatt zu lesen ist der Umgang mit Mikrocontrollern eins der letzten großen Abenteuer unserer Tage.

gioR
22.12.2018, 13:25
Hallo,

ich danke euch für die Antworte... Ich habe ein Buch das behandelt den Atmega 88. In meinem Fall ist es der Atmega 8, bei dem ist es so wie Ihr es beschrieben habt...
Vielen Dank !!

Ich hänge aktuell an einer Kleinigkeit..

Ich möchte an meinen Schalt-blitz die letzte LED beim erreichen der Drehzahl blinken lassen ohne das die anderen LED`s ausgehen.
Deshalb kann ich ja kein interrupt verwenden oder?

Ich bekomme über den 16 Bit-Timer die Led einfach nicht zum blinken...




#include <avr/io.h>
#include <util/delay.h>


int main(void)
{
DDRB |= (1<<PB1); // PB0 Als Ausgang

// Init Timer

TCCR1B |= (1<<CS12) | (1<<CS10); // Prescaler CPU Takt/1024


while (1)
{


if (TCNT1 < 32768)
{
PORTB |= (1 << PB1);
}

else
{

PORTB &= ~(1 << PB1);


}

}
}




Eigentlich müsste doch die LED unter dem Wert 32768 an sein und ansonsten aus? Wo ist mein Denkfehler?
Ich finde ausschließlich nur beispiele mit Interrupt

Vielen Dank im voraus und schöne Weihnachten :-)

Searcher
22.12.2018, 13:59
DDRB |= (1<<PB1); // PB0 Als Ausgang
Eigentlich müsste doch die LED unter dem Wert 32768 an sein und ansonsten aus?


Hallo,
ich bin nicht besonders in C aber sehe ich auch so wie Du.

Der Kommentar hinter der "DDRB.." Zeile stimmt nicht: Ist die LED am richtigen Pin, nämlich PB1 nach Programm, mit welchem Vorwiderstandswert angeschlossen?

Leuchtet die LED überhaupt nicht, oder ist sie immer an?

In welchem zeitlichen Rhythmus soll sie blinken?

Wie sind die Fuses jetzt eingestellt? Auf 8 oder 1 MHz?


Gruß
Searcher

PS Schließe Deinen Code in Code Tags [CODE ] program [/CODE ] ohne die Blanks vor der letzten Klammer ein. Ist dann besser lesbar und die Emoticons erscheinen auch nicht mehr unfreiwillig :-) Code Tags sind in der Vorschau (Button "Erweitert" bzw "Vorschau" ) auch mit dem # Zeichen erreichbar.

gioR
22.12.2018, 14:44
Hi searcher,

danke für Deine Antwort. Ich habe den Kommentar abgeändert.. Ich habe zum probieren aktuell das Oszi angeschlossen... Das zeigt dauerhaft 5 V an (Ausgangszuorndung passt).
Die Blinkzeit ist relativ egal... soll halt Blinken deshalb ist der Wert frei erfunden also 3276 .. Der Prozessor läuft aktuell auf 1 MHZ

Danke und viele Grüße :-)

Searcher
22.12.2018, 16:40
das Oszi angeschlossen... Das zeigt dauerhaft 5 V an (Ausgangszuorndung passt).
Hab keine weitere Idee außer vielleicht nochmal die Verdrahtung überpüfen. Daß keine ungewollte Verbindung sonstwo hin am Ausgangspin vorliegt.

Mit dem Wert < 3276 im TCNT1 wird PB1 etwa 3,3 Sekunden auf high und dann ca. 64 Sekunden auf low geschaltet. Das das auch beim Oszi berücksichtigt wird und richtig abgelesen wird?

Sonst ra(d)tlos :-)
Gruß
Searcher

oberallgeier
22.12.2018, 16:48
..
// Init Timer
TCCR1B |= (1<<CS12) | (1<<CS10); // Prescaler CPU Takt/1024
..
Hier wurde die Waveform noch nicht definiert. Auf die Schnelle mal (m)eine Initialisierung für nen mega328, die wird (na ja, nicht getestet, aber ich bin sicher) so auch auf nem mega8 funktionieren. Ergibt ein 36 kHz-Signal bei nem 20MHz-Quarz auf dem Pinn PB1/OC1A, das ich für ne IR-Signalübertragung benutze. Die Parameter müsstest Du eben selbst anpassen bzw ne andere Waveform wählen.


// ================================================== =========================== =
// == PWM-Routinen zur IRLED-ansteuerung auf OC1A/PB1 ====================== =
// Target MCU : ATmega328p (als arduino-nano, Clone)
void TC1PWM_init(void) // Tmr/Ctr1 = PWM-Signal 36 kHz - EIN?schalten
{ //
TCCR1A |= (1<<COM1A1); // enable Clear/set OC1A on Compare Match
// also Port PB3, vgl. auch PWM-routine unten
TCCR1B |= (1<<CS10); // cs10 <=> clk/1 => no prescaling
TCCR1B |= (1<<WGM13); // PWM, Phase+Frequency correct
ICR1 = 278; // =>PWM-Frequenz 20MHz/(2*278) => 36,0kHz/27,8µs
}
// ================================================== ==============================

oberallgeier
23.12.2018, 10:03
Und - klappt das jetzt? Wenn ja oder wenn nein - was hast Du geändert ?
Viel Erfolg, schönen Sonntag

021aet04
23.12.2018, 11:16
In dem Programm ist kein Fehler zu erkennen und auch mit dem Simulator funktioniert es (ca. 33s ein/aus). Zum Testen passe ich Zeiten häufig an damit man es schön beobachten kann (wenn möglich). Wenn man eine Led anschließt verwende ich Zeiten zwischen ca. 0,5 bis 5s / Periode (also die Gesamtzeit Led ein + Led aus).

MfG Hannes

oberallgeier
23.12.2018, 12:28
In dem Programm ist kein Fehler zu erkennen und auch mit dem Simulator funktioniert es (ca. 33s ein/aus) ..MMM...ähhh..Mein Fehler. Ich hab garnicht mehr daran gedacht, dass mit WGM1[3:0]=0 der Modus "Normal" gefahren wird. Und dieser Zustand ist ja aktuell nach jedem Power-on.

Es wäre dem Kollegen gioR also allenfalls nur zu raten die Initialisierung des Timers auf
......TCCR1B |= (1<<CS11) | (1<<CS10); // Prescaler CPU Takt/64
also langsames Blinken zu setzen oder mit
......TCCR1B |= (1<<CS11) ; // Prescaler CPU Takt/8
ein schnell(er)es Blinken zu fahren - ca. 18 "Blitze" in 10 Sekunden.

gioR
23.12.2018, 13:12
Hallo,

ich hab den Fehler entdeckt... Es funktioniert tatsächlich.... peinlich peinlich...

Ich habe nun mein Schalt-blitz soweit fertig das er FAST funktioniert wie er soll... Allerdings hängt sich das Programm öfters auf...
Findet jemand den Fehler?

Danke und viele Grüße






#include <avr/io.h>
#include <util/delay.h>

// Status LED on

#define LED1_on |= (1<<PB0);
#define LED2_on |= (1<<PB1);
#define LED3_on |= (1<<PB2);
#define LED4_on |= (1<<PB3);
#define LED5_on |= (1<<PB4);

// Status LED off

#define LED1_off &= ~(1<<PB0);
#define LED2_off &= ~(1<<PB1);
#define LED3_off &= ~(1<<PB2);
#define LED4_off &= ~(1<<PB3);
#define LED5_off &= ~(1<<PB4);


int main(void)
{

uint16_t x, ergebnis; // Variablen für nachfolgendes Programm festlegen
DDRB = 0xFF; // Alle Bits als Ausgang
PORTC = 0x00; // Beim Einfang keine Pullups


// Init Timer

TCCR1B |= (1<<CS10); // 16bit Timer und Prescaler 1

// Init ADC


ADMUX = (1<<REFS0) | (1<<MUX0); // AVCC 5V als Vergleichsspannung und festlegen des Messkanales ADC1
ADCSRA = (1<<ADEN) | (1<<ADPS0) | (1<<ADPS1); // ADC Aktivieren und Vorteiler für die ADC Wandlung festlegen auf 8 festlegen (125 khz)
ADMUX |= (1<<ADLAR); // Ausgabe linksbündig


// Dummy Readout
ADCSRA |= (1<<ADSC); // Start ADC-Wandlung
while (ADCSRA &(1<<ADSC)); // Auf Abschluss der Konvertierung warten
x = ADC; // Das Ergebnis der 1. Wandlung in x speichern


while (1)
{





ADCSRA |= (1<<ADSC); // Start ADC-Wandlung
while (ADCSRA &(1<<ADSC)) // Führe ADC-Wandlung solange aus bis abgeschlossen
ergebnis = ADC; // Ergebnis in ADC Port speichern
ergebnis = ergebnis >> 6; // Ergebnis 6x nach rechts veschieben




if(ergebnis > 200)

{
PORTB LED1_on
}

else
{
PORTB LED1_off
}





if(ergebnis > 400)

{
PORTB LED2_on
}

else
{
PORTB LED2_off
}





if(ergebnis > 600)

{
PORTB LED3_on
}

else
{
PORTB LED3_off
}




if(ergebnis > 800)

{
PORTB LED4_on
}


else
{
PORTB LED4_off

}






if(ergebnis > 999)

{

if (TCNT1 < 32768)

{
PORTB LED5_on
}


else

{
PORTB LED5_off

}

}

else

{
PORTB LED5_off


}


}

}

021aet04
23.12.2018, 14:02
Das Programm ist sehr schwer zu lesen. Bitte schreibe es (wie schon weiter oben geschrieben) in Code Tags, damit es so aussieht wie in Beitrag 8.

Warum parametrierst du den ADC eigentlich linksbündig und schiebst das Ergebnis nach rechts? Mit "ADLAR = 0" hast du das selbe Ergebnis nur das du nicht nach rechts schieben musst. "ADLAR = 1" verwendet man nur wenn man mit 8Bit rechnet (der ADC wird erst aktualisiert wenn man ADCH gelesen hat).

Die Variable "x" benötigst du nicht, das Ergebnis kannst du auch dort schon in die variable "ergebnis" schreiben, da es in der "while"-Schleife sofort überschrieben wird (weil zuerst der ADC neu gestartet und anschließend in "ergebnis" geschrieben wird).

Was mir noch aufgefallen ist (was die Ursache sein kann). In der "while" Schleife startest du den ADC, Anschließend schreibst du solange "ADSC == 1" den ADC Wert in die Variable "ergebnis" und wenn die Wandlung fertig ist schreibst du den richtigen Wert nicht mehr in "ergebnis", weil du das ";" hinter der Zeile "while (ADCSRA &(1<<ADSC)) // Führe ADC-Wandlung solange aus bis abgeschlossen" vergessen hast.

MfG Hannes

oberallgeier
23.12.2018, 15:36
Mit copy & paste - ohne sonst was! - in die "Codeklammern" eingesetzt siehts schon fast gut aus.


#include <avr/io.h>
#include <util/delay.h>

// Status LED on

#define LED1_on |= (1<<PB0);
#define LED2_on |= (1<<PB1);
#define LED3_on |= (1<<PB2);
#define LED4_on |= (1<<PB3);
#define LED5_on |= (1<<PB4);

// Status LED off

#define LED1_off &= ~(1<<PB0);
#define LED2_off &= ~(1<<PB1);
#define LED3_off &= ~(1<<PB2);
#define LED4_off &= ~(1<<PB3);
#define LED5_off &= ~(1<<PB4);


int main(void)
{

uint16_t x, ergebnis; // Variablen für nachfolgendes Programm festlegen
DDRB = 0xFF; // Alle Bits als Ausgang
PORTC = 0x00; // Beim Einfang keine Pullups


// Init Timer

TCCR1B |= (1<<CS10); // 16bit Timer und Prescaler 1

// Init ADC


ADMUX = (1<<REFS0) | (1<<MUX0); // AVCC 5V als Vergleichsspannung und festlegen des Messkanales ADC1
ADCSRA = (1<<ADEN) | (1<<ADPS0) | (1<<ADPS1); // ADC Aktivieren und Vorteiler für die ADC Wandlung festlegen auf 8 festlegen (125 khz)
ADMUX |= (1<<ADLAR); // Ausgabe linksbündig


// Dummy Readout
ADCSRA |= (1<<ADSC); // Start ADC-Wandlung
while (ADCSRA &(1<<ADSC)); // Auf Abschluss der Konvertierung warten
x = ADC; // Das Ergebnis der 1. Wandlung in x speichern


while (1)
{





ADCSRA |= (1<<ADSC); // Start ADC-Wandlung
while (ADCSRA &(1<<ADSC)) // Führe ADC-Wandlung solange aus bis abgeschlossen
ergebnis = ADC; // Ergebnis in ADC Port speichern
ergebnis = ergebnis >> 6; // Ergebnis 6x nach rechts veschieben




if(ergebnis > 200)

{
PORTB LED1_on
}

else
{
PORTB LED1_off
}





if(ergebnis > 400)

{
PORTB LED2_on
}

else
{
PORTB LED2_off
}





if(ergebnis > 600)

{
PORTB LED3_on
}

else
{
PORTB LED3_off
}




if(ergebnis > 800)

{
PORTB LED4_on
}


else
{
PORTB LED4_off

}






if(ergebnis > 999)

{

if (TCNT1 < 32768)

{
PORTB LED5_on
}


else

{
PORTB LED5_off

}

}

else

{
PORTB LED5_off


}


}

}



Dazu in der "erweiterten" Ansicht den Button mit dem Hash/Lattenzaun anklicken: diesen da: [#], dann bekommst Du ins Editorfenster die Folge
.[/COLOR]][/Code.] eingefügt. Und mitten zwischen diese beiden Klammerausdrücke scheibst Du dann Deinen Ausdruck:

[Code.]/* Diesda
ist
nur Kommentar */[/Code.]

Vorsicht - um den Automatismus zu betuppen habe ich als Demo in den Codeklammern oben einen "unsichtbaren" Punkt eingefügt. Das Ergebnis ist dann:
[CODE]/* Diesda
ist
nur Kommentar */

Nachtrag:
Achtung mit ADLAR; Du weißt schon dass Du damit Du den Wert manipulieren kannst?

......https://dl.dropbox.com/s/uaip6pfkxin6sif/adlar.JPG?dl=0

gioR
23.12.2018, 16:40
ich danke euch!

Programm funktioniert ! es war die variabel X das Problem :-)


Viele Grüße

021aet04
23.12.2018, 19:11
@oberallgeier
Es geht um einen Atmega8, dieser hat nur Single Ended ADCs.

@gioR
Ich glaube nicht das es an der Variable "x" liegt, diese wird nur einmal geschrieben und dann passiert damit nichts mehr (weder lesen noch schreiben).

MfG Hannes