Jag håller på med lite julbelysning så här och hade några attiny4313 över från tidigare projekt.
Nu har jag kopplat en RGB diod samt en varmvit diod till den.
Tanken är att kunna bygga en enkel "flickery flame" att montera in i en värmeljusstake.
Jag har skrivit lite kod för att testa och får ett litet lustigt resultat.
PWM dimmning fungerar perfekt på OCR0A och OCR1B utan problem.
PWM dimmning fungerar INTE alls på OCR0B och OCR1A utan där blinkar dioden bara (utan märkbar förändring i frekvensen).
Min första tanke var att felet skulle ligga i själva adresseringen men jag kan inte finna något problem och hoppas ni kan hjälpa mig.
Kod: Markera allt
#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <util/delay.h>
#include <inttypes.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include "pwm_logtable.h"
#define PINBLU PD5 //pin 9 - OC0B - 8bit
#define PINRED PB2 //pin 14 - OC0A - 8bit
#define PINGRN PB3 //pin 15 - OC1A -16bit
#define PINWHI PB4 //pin 16 - OC1b - 16bit
#define PWM_PORT_B PORTD
#define PWM_PORT_R PORTB
#define PWM_PORT_G PORTB
#define PWM_PORT_W PORTB
#define PWM_DDR_B DDRD
#define PWM_DDR_R DDRB
#define PWM_DDR_G DDRB
#define PWM_DDR_W DDRB
#define BLU_LED_OFF PWM_PORT_B &= ~(1<<PINBLU)
#define RED_LED_OFF PWM_PORT_R &= ~(1<<PINRED)
#define GRN_LED_OFF PWM_PORT_G &= ~(1<<PINGRN)
#define WHI_LED_OFF PWM_PORT_W &= ~(1<<PINWHI)
#define BLU_LED_ON PWM_PORT_B |= 1<<PINBLU
#define RED_LED_ON PWM_PORT_R |= 1<<PINRED
#define GRN_LED_ON PWM_PORT_G |= 1<<PINGRN
#define WHI_LED_ON PWM_PORT_W |= 1<<PINWHI
//#define STARTUP_EFFECT 0
typedef struct _color {
uint8_t r;
uint8_t g;
uint8_t b;
uint8_t w;
} Color;
Color led_curr_color;
int main(void){
#define Test_Mode
#define TestColor
#if defined (TestColor)
led_curr_color.r = 0;
led_curr_color.b = 0;
led_curr_color.g = 0;
led_curr_color.w = 0;
#else
led_curr_color.r = 100;
led_curr_color.g = 0;
led_curr_color.b = 60;
led_curr_color.w = 40;
#endif
#if defined ( Test_Mode )
int8_t rMod=-1, gMod=1, bMod=1, wMod=-1;
led_curr_color.r = 0;
led_curr_color.b = 0;
led_curr_color.g = 0; //255;
led_curr_color.w = 0; //255;
#endif
PWM_DDR_R |= 1<<PINRED;
PWM_DDR_G |= 1<<PINGRN;
PWM_DDR_B |= 1<<PINBLU;
PWM_DDR_W |= 1<<PINWHI;
ICR1 = 0xFFFF; //Timer1 "TOP value"
TIFR = (1<< TOV1) | (1<< TOV0); //Timer0 clear interrupts on overflow
TIMSK = (1<< TOIE1) | (1<< TOIE0); //Timer0 enable overflow ISR
//Setup Timer1 -16bit Timers
TCCR1B = (1<< WGM12) | (1<< WGM13) //Sets Timer1 to PWM(Fast), ICR(TOP), TOV(TOP) 1,1,1,0
|(0<< CS12)|(0<< CS11)|(1<< CS10); //Timer1 start, no Prescaling 0,0,1
TCCR1A = (1<< WGM11) | (0<< WGM10) //see TCCR1B
|(1<< COM1A1) | (1<< COM1A0) //Set to Timer1A to Compare match, Clear on TOP
|(1<< COM1B1) | (1<< COM1B0); //Set to Timer1B to Compare match, Clear on TOP
//Setup Timer0 - 8bit Timers
TCCR0A = (1<< WGM01) | (1<< WGM00) //Sets Timer0 to Fast PWM, TOP(0xFF), OCRX updates(TOP), TOV(TOP) 0,1,1
|(1<< COM0A1) | (1<< COM0A0) //Set OC0A on Compare, clear at TOP
|(1<< COM0B1) | (1<< COM0B0); //Set OC0B on Compare, clear at TOP (if WGM02 TOP(0xFF))
TCCR0B = //(0<< WGM02) //(0<< WGM02) //see TCCR0A
//|(0<< CS02)|(0<< CS01)|
(1<< CS00); //Timer start, no Prescaling 0,0,1
sei(); //Enable Interrupts
for(;;) {
#if defined( Test_Mode )
if ((led_curr_color.r == 255) || (led_curr_color.r == 0)) rMod =- rMod;
if ((led_curr_color.g == 255) || (led_curr_color.g == 0)) gMod =- gMod;
if ((led_curr_color.b == 255) || (led_curr_color.b == 0)) bMod =- bMod;
if ((led_curr_color.w == 255) || (led_curr_color.w == 0)) wMod =- wMod;
//led_curr_color.r += rMod; //8-bit - OCR0A OK
//led_curr_color.g += gMod; //16-bit - OCR1A
led_curr_color.b += bMod; //8-bit - OCR0B
//led_curr_color.w += wMod; //16-bit - OCR1B OK
_delay_ms(100);
#endif
}
return 1;
}
ISR(TIMER1_OVF_vect){
static uint16_t pwm_period_whi;
static uint16_t pwm_period_grn;
pwm_period_whi = PWM_LOG(led_curr_color.w);
pwm_period_grn = PWM_LOG(led_curr_color.g);
OCR1A = pwm_period_grn;
OCR1B = pwm_period_whi;
}
ISR(TIMER0_OVF_vect) {
static uint16_t pwm_period_blu;
static uint16_t pwm_period_red;
pwm_period_red = 255 - led_curr_color.r; //PWM_LOG(led_curr_color.r);
pwm_period_blu = 255 - led_curr_color.b; //PWM_LOG(led_curr_color.b);
OCR0A = pwm_period_red;
OCR0B = pwm_period_blu;
}
Olyckligtvis tar arduino en av de tillgängliga timers som jag har förstått det vilket gör det svårt som jag vill ha alla 4 till detta projekt.
Samtidigt så ser jag det som ett intressant projekt för att lära sig AVR programmering lite bättre.
Tack på förhand...