Und - klappt das jetzt? Wenn ja oder wenn nein - was hast Du geändert ?
Viel Erfolg, schönen Sonntag
Und - klappt das jetzt? Wenn ja oder wenn nein - was hast Du geändert ?
Viel Erfolg, schönen Sonntag
Ciao sagt der JoeamBerg
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
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.
Ciao sagt der JoeamBerg
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 < 3276
{
PORTB LED5_on
}
else
{
PORTB LED5_off
}
}
else
{
PORTB LED5_off
}
}
}
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
Mit copy & paste - ohne sonst was! - in die "Codeklammern" eingesetzt siehts schon fast gut aus.
Code:#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 [Code.][/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:
Nachtrag:Code:/* Diesda ist nur Kommentar */
Achtung mit ADLAR; Du weißt schon dass Du damit Du den Wert manipulieren kannst?
......Bild hier
Geändert von oberallgeier (23.12.2018 um 15:47 Uhr)
Ciao sagt der JoeamBerg
ich danke euch!
Programm funktioniert ! es war die variabel X das Problem
Viele Grüße
@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
Lesezeichen