Hallo zusammen
Aus freude an der Sache habe ich mir ein Entwicklungsboard MySmartUSB
(mit ATMEGA8 Prozessor) zugelegt und wage die ersten Schritte im
Programmieren. Dazu habe ich mir eine LED-Platine zusammengelötet um zu
experimentieren.
Die Idee sieht wie folgt aus: Wenn PINC0 aktiv ist sollen die LEDS an
PINB1 und PINB2 mit reduzierter Helligkeit leuchten (case 0xc1). Wenn
PINC1 zugeschaltet wird soll die LED an PINB1 mit voller Helligkeit
leuchten, d.h. ohne Soft-PWM und PINB2 weiterhin mit reduzierter
Helligkeit (case 0xc3).
Hier ist mein bestehender C-Code:
1
#include<avr/io.h>
2
#include<util/delay.h>
3
4
intmain(void)
5
{
6
7
DDRC=0x00;// Port C ist Eingang
8
PORTC=0xff;// Port C ist auf "high" gelegt
9
10
DDRB=0xff;// Port B ist Ausgang
11
PORTB=0x00;// Port B ist auf "low" gelegt
12
13
DDRD=0xff;// Port D ist Ausgang
14
PORTD=0x00;// Port D ist auf "low" gelegt
15
16
volatileunsignedcharinput;
17
18
while(1)
19
{
20
21
input=~PINC;// LEDs an Anode (+5V) und Kathode an GRD; also invertiert
PORTB=((1<<PINB1)|(1<<PINB2));// LED1 volle Helligkeit und LED2 reduziert
32
break;
33
34
default:// Zeigt das keine Inputs aktiv sind
35
PORTB=(1<<PINB3);// LED3 an PINB3
36
}
37
_delay_ms(1000);// Verzögerung um CPU Last zu reduzieren
38
}
39
}
Ich habe mir die Soft-PWM im Tutorial zu gemüte geführt. Leider fehlt
mir das Verständnis um meine Idee zu realisieren. Das Beispiel für
PWM-Modi unter
http://www.rn-wissen.de/index.php/Timer/Counter_(Avr)#Die_verschiedenen_PWM-Modi
scheint mir im Prinzip naheliegend (?). Hier kann man den PWM-Wert
festlegen, wobei ich die Output-Pins selber bestimmen möchte.
Vielleicht kann mir jemand helfen die Lösung zu erarbeiten.
Oliver schrieb:
>>while(1)>> bildet nun mal eine Endlosschleife. Da gibt es kein Entrinnen
Gibt es schon, nennt sich "break" und "return" (und noch ein paar
weniger gebräuchliche, wie "goto" oder "longjump()").
Sind im Code aber nicht vorhanden, also Endlosschleife = Endstation.
Ok, ich habe mir mal die 8-kanalige PWM mit intelligenter Lösungsansatz
probiert. Es funktioniert mit den angegebenen Test Values.
Als Anfänger komme ich jetzt leider nicht mehr weiter und bitte um
Starthilfe. Wie kann ich jetzt z.B. 8 LEDs mit unterschiedlicher
Helligkeit unten einbinden?
1
intmain(void)
2
{
3
// PWM Port einstellen
4
5
PWM_DDR=0xFF;// Port als Ausgang
6
7
// Timer 1 OCRA1, als variablem Timer nutzen
8
9
TCCR1B=2;// Timer läuft mit Prescaler 8
10
TIMSK|=(1<<OCIE1A);// Interrupt freischalten
11
12
sei();// Interrupts gloabl einschalten
13
14
volatileunsignedcharinput;
15
16
????????????
17
18
while(1)
19
{
20
input=~PINC;// LEDs an Anode (+5V) und Kathode an GRD; also invertiert
Jetzt hab ich's fast. Die LED Helligkeiten kann ich problemlos
bestimmen, aber sie blinken unregelmässig, als ob sie unter
"Wackelkontakt" leiden. Waran könnte das liegen?
1
volatileunsignedcharinput;
2
3
constuint8_tt1[8]={150,150,150,150,0,150,0,0};
4
constuint8_tt2[8]={0,200,200,200,0,50,0,0};
5
constuint8_td[8]={0,0,0,0,0,0,0,0};
6
7
while(1)
8
{
9
input=~PINC;// LEDs an Anode (+5V) und Kathode an GRD; also invertiert
@ Firebird (Gast)
>Jetzt hab ich's fast. Die LED Helligkeiten kann ich problemlos>bestimmen, aber sie blinken unregelmässig, als ob sie unter>"Wackelkontakt" leiden. Waran könnte das liegen?
Deine Tastenabfrage ist komisch. Mach es lieber einfach per
if(input&(1<<PINC1))// Schalter 1 offen, Schalter 2 zu
10
{
11
memcpy(pwm_setting,t2,8);
12
pwm_update();
13
}
14
if(input&((1<<PINC0)|(1<<PINC1)))// Schalter 1 und 2 zu
15
{
16
memcpy(pwm_setting,t3,8);
17
pwm_update();
18
}
19
else
20
{
21
memcpy(pwm_setting,d,8);// LEDs off
22
pwm_update();
23
}
24
}
25
return0;
Es funktioniert besser wobei dazu kommt, dass die einzelnen Fälle nicht
sauber erfasst werden:
Für (1<<PINC0) flackern die LEDs
Für (1<<PINC1) flackern sie ein bischen weniger
Für ((1<<PINC0)|(1<<PINC1)) leuchten die LEDs analog wie für (1<<PINC0)
Die else Anweisung wird nicht erkannt ausser wenn INPUT =~PINC
In meiner Switch Anweisung habe ich "0xc1" und "0xc3" verwendet um alle
PINC Zustände zu erfassen. Sobald ich dort mit einzelnen PINC Zustände
(analog oben) gearbeitet habe gab es die gleichen Probleme.
An meinem ATMEGA8 wird PINC6 für Reset verwendet und PINC7 ist gar nicht
vorhanden, deswegen die "c" in "0xC1".
Mit freundlichem Gruss
Firebird