PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : OCR0 lässt sich nicht zurücksetzen



popi
13.06.2006, 20:28
Hallo zusammen,

ich wollte eine LED über PWM ansteuern.

Ich weiß, das es genug Beispiele dafür gibt, wollte es aber mal alleine und nur nach Datenblatt probieren...

Ist nicht so einfach, wie ich dachte, denn die LED leuchtet nur ganz schwach.
Denkt jetzt bitte nicht, "DAS IST DOCH PWM"

Ich weiß, aber ich wollte uber die if-Bedingung die Heligkeit steuern wollen.

Könnt Ihr mir bitte sagen, was an meinem Code falsch ist und warum die if-Bedingung nich ausgeführt wird ???

Danke Euch im Voraus

MfG

popi

Hier der kurze Code:


#include <avr/io.h>



void main(void)
{

PORTB = (1<< PB4);
DDRB = (1<< DDB4);
OCR0 = 0xff;
TCCR0 = (1 << WGM00) |(1 << WGM01) | (1<< COM01) | (1<< CS00) | (1<< CS01) | (1<< CS01);

unsigned int wort,x;
x = 0;

while(x=0);
{

OCR0 = OCR0 + 1;

if (OCR0 = 0xff) OCR0 = 0x00;

}




} // Ende main

izaseba
13.06.2006, 21:22
if (OCR0 = 0xff) OCR0 = 0x00;


machmal if (OCR0 == 0xff) OCR0 = 0x00;

Wobei
1. wenn OCR0 = 0xFF und Du noch eins dazuaddierst wird OCR0 automatisch wieder 0
2. Es dürfte so schnell passieren, daß Du nichts merkst.

Gruß Sebastian

SprinterSB
13.06.2006, 21:35
Dir ist klar, was der Unterschied ist zwischen

while (x=0);
{
}
und

while (x==0)
{
}???

Dein momentanes Programm ist äquivalent hierzu:

#include <avr/io.h>

void main(void)
{
PORTB = (1<< PB4);
DDRB = (1<< DDB4);
OCR0 = 0xff;
TCCR0 = (1 << WGM00) | (1 << WGM01) | (1<< COM01) | (1<< CS00) | (1<< CS01) | (1<< CS01);

OCR0 = OCR0 + 1;

if (OCR0 = 0xff)
OCR0 = 0x00;

} // Ende main, landet in exit() (Endlosschleife)


Das wiederum ist nicht anderes als

#include <avr/io.h>

void main(void)
{
PORTB = (1<< PB4);
DDRB = (1<< DDB4);
OCR0 = 0xff;
TCCR0 = (1 << WGM00) | (1 << WGM01) | (1<< COM01) | (1<< CS00) | (1<< CS01) | (1<< CS01);

OCR0 = OCR0 + 1;
OCR0 = 0xff;
OCR0 = 0x00;

} // Ende main, landet in exit() (Endlosschleife)

Dein OCR0 ist also immer 0. Mach die den Unterschied klar zwischen = und == und ein überflüssiger ; hat schon so manche Schleife ausgeknockt. Beides und noch mehr steht in Fallstricke bei der C-Programmierung (https://www.roboternetz.de/wissen/index.php/Fallstricke_bei_der_C-Programmierung)

popi
13.06.2006, 22:27
Danke für die Antworten.

Es lässt sich nun dimmen...

Aber ich würde gerne den OCR0 Wert ändern können, um ein Zeit Variable zu gestalten, also damit die LED von dunkel auf hell hochdimmt.

Oder wie lösst man sowas?

Könnt Ihr bitte nochmal einen Blick auf meinen Code werfen und mir mit dem Problem helfen, die Impulsueit variable zu gestalten?

Danke im Voraus und Grüße

popi

Hier der Code, der zwar dimmt, aber nicht an OCR0 ändert, trotz eindeutigen Befehl, wie ich meine... denke... hoffe....

#include <avr/io.h>

void main(void)
{
PORTB = (1<< PB4);
DDRB = (1<< DDB4);
OCR0 = 0x10;
TCCR0 = (1 << WGM00) | (1<< COM01) | (1<< CS00) | (1<< CS01);

if (TCNT0 == 0x20) OCR0 = 0x00;
}

izaseba
13.06.2006, 22:53
Ich weiß jetzt nicht so recht, was Du vor hast.
Du willst Die Led hochdimmen, und dann wieder runter, oder wie ?

Also das Programm, was Du da jetzt geschrieben hast läuft Amok, genau so wie das davor, was Dir der Sprinter schon erklärt habe.
Mach mal eine Schleife, wo Du OCR0 inkrementierst und zwar mit einer kurzen pause zwischen, damit man das auch mitbekommt.
Vielleicht kommst Du damit (http://www.nongnu.org/avr-libc/user-manual/group__util__delay.html)weiter.

Gruß Sebastian

popi
14.06.2006, 01:35
Hallo Sebastian,

ich glaube, ich habs jetzt mit Eurer Hilfe hinbekommen.
Die LED ändern fließend die Helligkeit in einem "zufälligem Muster"...

Könnte man das kompakter schreiben?

Grüße

popi


#include <avr/io.h>


unsigned char x = 2;
unsigned short i;

void main(void)
{
PORTB = (1<< PB4);
DDRB = (1<< DDB4);
OCR0 = 0x00;
TCCR0 = (1 << WGM00) | (1<< COM01) | (1<< CS00);// | (1 << WGM01);


while(x==2)
{
while(OCR0 <= 0x60) {for (i=0;i<500;i++) asm volatile("NOP"); OCR0 = OCR0 + 1;}
while(OCR0 >= 0x40) {for (i=0;i<300;i++) asm volatile("NOP"); OCR0 = OCR0 - 1;}

while(OCR0 <= 0xCF) {for (i=0;i<700;i++) asm volatile("NOP"); OCR0 = OCR0 + 1;}
while(OCR0 >= 0x10) {for (i=0;i<100;i++) asm volatile("NOP"); OCR0 = OCR0 - 1;}

while(OCR0 <= 0x70) {for (i=0;i<300;i++) asm volatile("NOP"); OCR0 = OCR0 + 1;}
while(OCR0 >= 0x05) {for (i=0;i<500;i++) asm volatile("NOP"); OCR0 = OCR0 - 1;}

while(OCR0 <= 0xEE) {for (i=0;i<100;i++) asm volatile("NOP"); OCR0 = OCR0 + 1;}
while(OCR0 >= 0x05) {for (i=0;i<400;i++) asm volatile("NOP"); OCR0 = OCR0 - 1;}

while(OCR0 <= 0xfe) {for (i=0;i<100;i++) asm volatile("NOP"); OCR0 = OCR0 + 1;}
while(OCR0 >= 0x20) {for (i=0;i<50;i++) asm volatile("NOP"); OCR0 = OCR0 - 1;}
}
}

SprinterSB
14.06.2006, 13:37
Wenn du die Sequenz öfter brauchst würde ich eine Funcktion machen, weil sonst fast der gleiche Code mehrfach dasteht, mit Funktionen stehen nur die Aufrufe da.

Die Warteschleifen machst du besser mit _delay_loop_1(unsigned char) oder _delay_loop_2(unsigned int) aus util/delay.h (deprecated: avr/delay.h)

Da OCR0 volatile ist, wird der Code kleiner (und schneller), wenn du über ein temporäres Zwischenregister gehst:

uint8_t ocr0 = OCR0;
while (ocr0 <= ***)
{
_delay_loop_* (***);
OCR0 = ++ocr0;
}