Ahoj.Mam k MCU pripojenou RGB LED a ovladam ji pomoci softwarovyho PWM ktery sem si napsal.Dioda mi ale ocas nepravidelne problikne.Deje se to kdyz v hlavni smycce napriklad plynule prolinam barvy.Kdyz v hlavni smycce dokola nastavuji statickou hodnotu PWM promenych tak se nic nedeja a dioda krasne sviti.
Dalsi pripad je ze kdyz diodu ovladam pomoci seriove linky a barvy nemenim tak problikava taky.Jakmile ale ser linku odpojim blikani prestane a dioda sviti podle posledni prijatych dat v klidu dal bez problikavani.
[code]#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
// Konstanty
#define TIME 50
#define REG_TCNT0 190 // frekvence PWM
#define CLOCK_SPEED 8000000 // systemovy hodiny 8Mhz
#define BAUD 9600 // rychlost ser. linky
#define MY_UBRR (CLOCK_SPEED/16/BAUD)-1 // vypocet registru UBRR
// Pozice
#define BITPOS_0 0
#define BITPOS_1 1
#define BITPOS_2 2
#define PORT_1 PORTB
// Makra
#define SET_BIT(BYTE,BIT)(BYTE|=(1<<BIT))
#define CLEAR_BIT(BYTE,BIT)(BYTE&=~(1<<BIT))
#define CHECK_BIT(BYTE,BIT)(BYTE&=(1<<BIT))
// Deklarace globalnich promennych
volatile unsigned char Red = 0,Green = 0,Blue = 0;
// Obsluha preruseni TIMER0 pri preteceni
ISR(TIMER0_OVF_vect)
{
static unsigned char Pwm;
TCNT0 = REG_TCNT0;
Pwm++;
if ((Pwm == 0) && (Red != 0)) SET_BIT(PORT_1,BITPOS_0);
if ((Pwm == Red) && (Pwm != 255)) CLEAR_BIT(PORT_1,BITPOS_0);
if ((Pwm == 0) && (Green != 0)) SET_BIT(PORT_1,BITPOS_1);
if ((Pwm == Green) && (Pwm != 255)) CLEAR_BIT(PORT_1,BITPOS_1);
if ((Pwm == 0) && (Blue != 0)) SET_BIT(PORT_1,BITPOS_2);
if ((Pwm == Blue) && (Pwm != 255)) CLEAR_BIT(PORT_1,BITPOS_2);
}
// Obsluha pri prijmu dat ze ser. linky
ISR(USART_RXC_vect)
{
static unsigned char Pole[3];
static unsigned char Index;
Pole[Index++] = UDR;
if(Index == 3)
{
Index = 0;
Red = Pole[0];
while ( !( UCSRA & (1<<UDRE)) );
UDR = Red;
Green = Pole[1];
while ( !( UCSRA & (1<<UDRE)) );
UDR = Green;
Blue = Pole[2];
while ( !( UCSRA & (1<<UDRE)) );
UDR = Blue;
}
if (CHECK_BIT(PORTC,BITPOS_1)) CLEAR_BIT(PORTC,BITPOS_1);
else SET_BIT(PORTC,BITPOS_1);
}
void main (void)
{
// Inicializace mcu
DDRA = 0xFF; // port A jako vystup
DDRB = 0xFF; // port B jako vystup
DDRC = 0xFF; // port C jako vystup
DDRD = 0xFE; // port D jako vystup
// Zhasne vsechny LED
PORTA = 0x00;
PORTB = 0x00;
PORTC = 0x00;
PORTD = 0x00;
// Globalni povoleni preruseni
sei();
// Nastaveni TIMER0 a Preruseni (Timer0 zajistuje softwarove PWM)
TCNT0 = REG_TCNT0;
TIMSK |= (1<<TOIE0) ; // Preruseni pri preteceni
TCCR0 |= (1<<CS01); // Normalni rezim,delicka 8.,
// Nastaveni Serive linky
UBRRH = (unsigned char)(MY_UBRR>>8); // Nastavi rychlost
UBRRL = (unsigned char)MY_UBRR;
//UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE); // Zapne vysilac a prijimac,povoli preruseni pri prijmu a dokonceni vysilani
UCSRC = (1<<URSEL)|(1<<USBS)|(1<<UCSZ0)|(1<<UCSZ1); // 8 datovych bitu,2 stop bit
// MAIN LOOP
for(;
{
for (; Green != 255 ; Green++) { _delay_ms(TIME); }
for (; Red != 0 ; Red--) { _delay_ms(TIME); }
for (; Blue != 255 ; Blue++) { _delay_ms(TIME); }
for (; Green != 0 ; Green--) { _delay_ms(TIME); }
for (; Red != 255 ; Red++) { _delay_ms(TIME); }
for (; Green != 255 ; Green++) { _delay_ms(TIME); }
for (; Blue != 0 ; Blue--)
{
Green--;
_delay_ms(TIME);
}
}
}
[/code]