Hallo allemaal,
Ik ben een RGB fadend LEDje aan het maken met een ATtiny2313, alleen doet 1 kanaal het niet.
Situatie:
Ik gebruik dus 3 uitgangen, omdat ik de hardware PWM niet aan de gang kreeg (dus de Set output on Compare A match bijvoorbeeld). Ik heb maak nu gewoon de pinnen handmatig hoog of laag in de ISR.
Dit werkt prima, bij bepaalde combinaties van pinnen koppelen aan ISR's.
Zie de volgende code:
#include <tiny2313.h>
#include <delay.h>
#define WAIT 25
#define TOP 128
interrupt [TIM0_OVF] void timer0_ovf_isr(void){PORTD.4=0;}
interrupt [TIM0_COMPA] void timer0_compa_isr(void){PORTD.4=1;}
interrupt [TIM1_OVF] void timer1_ovf_isr(void) {PORTD.5=0; PORTD.3=0;}
interrupt [TIM1_COMPA] void timer1_compa_isr(void){PORTD.3=1;}
interrupt [TIM1_COMPB] void timer1_compb_isr(void) {PORTD.5=1;}
/////////////////
// Red=OC1B //
// Green=OC1A //
// Blue=OC0A //
/////////////////
void put_color(unsigned char red, unsigned char green, unsigned char blue){
OCR1BH=255-red;
OCR1BL=0;
OCR1AH=255-green;
OCR1AL=0;
OCR0A=255-blue;
}
void color_fade() {
unsigned char i;
for(i=0;i<TOP;i++){ //red on, green fade in, blue off
put_color(TOP,i,0);
delay_ms(WAIT);
}
for(i=TOP;i>0;i--){ //red fade out, green on, blue off
put_color(i,TOP,0);
delay_ms(WAIT);
}
for(i=0;i<TOP;i++){ //red off, green on, blue fade in
put_color(0,TOP,i);
delay_ms(WAIT);
}
for(i=TOP;i>0;i--){ //red off, green fade out, blue on
put_color(0,i,TOP);
delay_ms(WAIT);
}
for(i=0;i<TOP;i++){ //red fade in, green off, blue on
put_color(i,0,TOP);
delay_ms(WAIT);
}
for(i=TOP;i>0;i--){ //red on, green off, blue fade out
put_color(TOP,0,i);
delay_ms(WAIT);
}
}
void main(void)
{
// Crystal Oscillator division factor: 1
CLKPR=0x80;
CLKPR=0x00;
// Input/Output Ports initialization
PORTA=0x00;
DDRA=0x00;
PORTB=0x00;
DDRB=0x7F;
PORTD=0x00;
DDRD=0x7F;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 8000.000 kHz
// Mode: Normal top=FFh
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x01;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 8000.000 kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
TCCR1A=0x00;
TCCR1B=0x01;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
GIMSK=0x00;
MCUCR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0xE2;
// Andere meuk
USICR=0x00;
ACSR=0x80;
// Global enable interrupts
#asm("sei")
while(1) {
color_fade();
}
}
Bovenin bij de ISR's wijzig ik dus de toewijzing van de pinnen en daar komt de volgende tabel uit:
| P | P | P | P | P | P |
| D | D | D | D | D | D |
+------------+---+---+---+---+---+---+
|Timer 0A | 5 | 5 | 3 | 3 | 4 | 4 |
|Timer 1A | 4 | 3 | 5 | 4 | 5 | 3 |
|Timer 1B | 3 | 4 | 4 | 5 | 3 | 5 |
+------------+---+---+---+---+---+---+
|Functioneel | 4 | 4 |4+5|4+5| 5 | 5 |
+------------+---+---+---+---+---+---+
Met functioneel bedoel ik dat de LED doet wat ie moet doen (dimmen). Anders is de LED gewoon uit.
Dit zou voor mijn gevoel niet uit mogen maken.. PD3 doet dus uberhaupt niets. Als ik een ander programma maak met daarin PD3 aan werkt deze uitgang wel gewoon. DDR voor die poort is allemaal op output.
Nu is mijn vraag: hoe kan dit en waar wordt dit door veroorzaakt?
Marcel
AVR C tutorial http://expand.xs4all.nl/avr
Ik zie dat je nog geen response hebt gekregen.
Wellicht wil het helpen om je code nog wat op te duidelijken. Niet indereen heeft behoefte om eerst hex waardes uit te pluizen alvorens je te kunnen helpen. Daarmee doel ik bijvoorbeeld hier op:
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0xE2;
// Andere meuk
USICR=0x00;
ACSR=0x80;
Zou je die register waarden willen voorzien van commentaar of nog veel beter bit definities zoals Atmel die zelf ook gebruikt in de documentatie.
Verder is het handig compiler en versie te noemen. Dat het C voor AVR is, is me duidelijk. Maar er zijn nogal wat C compilers voor AVR. Het is in elk geval geen AVRGCC, maar wat dan wel?
Dan het programma. Zo op het eerste gezicht (zonder alle register instelling uit te pluizen) zou je code moeten werken. Ik zal het hier eens proberen. Dan moet ik het wel wat aanpassen omdat ik AVRGCC gebruik.
Natuurlijk is het nog mooier om gewoon de hardware PWM te gebruiken. Waarom krijg je dat niet aan de gang? Op mij site staat een voorbeeld (AVRGCC) met PWM op een servo.
Marcel
AVR C tutorial http://expand.xs4all.nl/avr
Zoals beloofd even getest met AVRGCC. De symptomen zijn hetzelfde, dus hoogstwaarschijnlijk geen compiler fout.
Nader bekeken blijkt (nou was ik dus toch verplicht om die hex waardes uit te pluizen) dat het interrupt OCIE0A helemaal niet aan staat.
Had je TIMSK=0xE2 uitgeschreven met bit definities dan was je dat vast opgevallen. Met bit definities ziet het er zo uit.
TIMSK = (1 << TOIE1) | (1 << OCIE1A) | (1 << OCIE1B) | (1 << TOIE0);Dat is ook de schrijfwijze die Atmel toepast in datasheets en application notes.
Ook zie ik dat je de timers ongelijk gebruik. Timer 0 (8-bits) gebruik je 8-bits. Maar timer 1 (16-bits) gebruik je 16 bits. Zo krijg je een enorm verschil in PWM frequentie. Timer 1 heeft een modus waarbij je zelf de TOP waarde kan instellen, waarmee je die dus ook 8-bits kan instellen.
Maar dit blijft natuurlijk behelpen als het gewoon met hardware PWM kan.
Hoi Marcel,
Bedankt voor je input. Ik ben dit weekend nauwelijks thuis geweest dus heb even geen tijd meer gehad om dit te checken.
OCIE0A staat inderdaad niet aan, dat is een fout geweest in de project wizard van CodeVisionAVR. Ook ondersteunt deze geen bit definities, TOIE1 kent ie bijvoorbeeld niet.
Ik gebruik wel een 16-bits timer maar de 8LSB zijn altijd 0 dus effectief toch een 8-bits timer. Ik ga nu even wat dingen proberen met de hardware PWM, misschien dat dat wel toch werkt.. Tot over een uur 
Edit: Het is gelukt! Heb de datasheet nog een keer uitgeplozen en allerlei dingen geprobeerd en tis nu gelukt met Fast PWM met TOP=0xFF voor timer 0 en 0x00FF voor timer 1.. Bedankt!
Gebruik nu dus hardware PWM dus heb geen ISR's meer nodig..
[Bericht gewijzigd door Henry S. op (40%)]
pros
Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
Als je er niet uitraakt, kijk dan eens naar dit voorbeeld.
Marcel
AVR C tutorial http://expand.xs4all.nl/avr
Hé, bekend stukje code 
Lijkt me erg behelpen als je compiler geen bit definities ondersteund. Nou ja compiler, het is in principe een onderdeel van de include file. Zo kan je nooit voorbeelden van Atmel overnemen zonder ze eerst helemaal te moeten herschrijven. Ik zeg AVRGCC. Kost niets, heeft geen beperkingen m.b.t. maximum code formaat of ondersteunde AVR's en integreert in AVR Studio.
pros
Prosper, yop la boum, c'est le roi du macadam (aldus Maurice Chevalier)
Op 8 oktober 2007 22:28:53 schreef Marcel:
Hé, bekend stukje code
'k Heb het ergens vandaan, ja. Maar vraag me niet van waar.
Het lijkt enigzins op code op jouw webstek, maar dan toch weer anders...
Lijkt me erg behelpen als je compiler geen bit definities ondersteund.
Volledig mee eens. Voor een klein programma is de code al onduidelijk. En ga maar eens fouten zoeken, als je code een 3000 regels bedraagt. Brrr...
Marcel
AVR C tutorial http://expand.xs4all.nl/avr
Die code heb ik een tijdje geleden een keer gepost. Maakt verder ook niet uit. Na aanleiding van dit topic heb ik dat net gisteren op m'n site geplaatst.