Hallo

Ich habe nun einen kleinen Test mit 2*12 LEDs an 8 Pins gemacht. Gesteuert wird mit dem asuro (8MHz, ATMega in C. Die "Lücken" beim Schwenken sind die Impuls/Pause-Zeiten der PWM. Nochmal der Hinweis: Beim Charlieplexing brennt (pro Leiste) immer nur eine LED!

Bild hier  
http://www.youtube.com/watch?v=dboh5SFD29g

Das Programm gibt per ISR je LED-Leiste ein Bitmuster mit PWM aus:
Code:
#include <avr/io.h>
#include <avr/interrupt.h>

#define pin1a_on  DDRB |= (1<<PB1); PORTB |= (1<<PB1)
#define pin1a_off DDRB |= (1<<PB1); PORTB &=~(1<<PB1)
#define pin1a_x   DDRB &=~(1<<PB1); PORTB &=~(1<<PB1)
#define pin2a_on  DDRB |= (1<<PB2); PORTB |= (1<<PB2)
#define pin2a_off DDRB |= (1<<PB2); PORTB &=~(1<<PB2)
#define pin2a_x   DDRB &=~(1<<PB2); PORTB &=~(1<<PB2)
#define pin3a_on  DDRB |= (1<<PB4); PORTB |= (1<<PB4)
#define pin3a_off DDRB |= (1<<PB4); PORTB &=~(1<<PB4)
#define pin3a_x   DDRB &=~(1<<PB4); PORTB &=~(1<<PB4)
#define pin4a_on  DDRB |= (1<<PB5); PORTB |= (1<<PB5)
#define pin4a_off DDRB |= (1<<PB5); PORTB &=~(1<<PB5)
#define pin4a_x   DDRB &=~(1<<PB5); PORTB &=~(1<<PB5)

#define pin1b_on  DDRC |= (1<<PC0); PORTC |= (1<<PC0)
#define pin1b_off DDRC |= (1<<PC0); PORTC &=~(1<<PC0)
#define pin1b_x   DDRC &=~(1<<PC0); PORTC &=~(1<<PC0)
#define pin2b_on  DDRC |= (1<<PC1); PORTC |= (1<<PC1)
#define pin2b_off DDRC |= (1<<PC1); PORTC &=~(1<<PC1)
#define pin2b_x   DDRC &=~(1<<PC1); PORTC &=~(1<<PC1)

#define pin3b_on  DDRD |= (1<<PD4); PORTD |= (1<<PD4)
#define pin3b_off DDRD |= (1<<PD4); PORTD &=~(1<<PD4)
#define pin3b_x   DDRD &=~(1<<PD4); PORTD &=~(1<<PD4)
#define pin4b_on  DDRD |= (1<<PD5); PORTD |= (1<<PD5)
#define pin4b_off DDRD |= (1<<PD5); PORTD &=~(1<<PD5)
#define pin4b_x   DDRD &=~(1<<PD5); PORTD &=~(1<<PD5)

volatile unsigned char count72kHz, pwm;
unsigned int bitmustera=0b111111111111, bitmusterb=0b110010010011;

/* uses 72kHz timer => Sleep(x) = x/72kHz [sec] */
void Sleep(unsigned char time72kHz)
{
   count72kHz = 0;
   while (count72kHz < time72kHz);
}
void Msleep(unsigned char dauer)
{
   while(dauer--) Sleep(72);
}

int main(void)
{
   //unsigned char i;
	TCCR2 = (1 << WGM21) | (1 << COM20) | (1 << CS20);
   OCR2  = 0x6E; // 36kHz @8MHz
   TIMSK |= (1 << OCIE2); // 36kHz counter for sleep
   sei();
   while(1)
   {
		for(pwm=50; pwm > 0; pwm--) Msleep(5);
		for(pwm=0; pwm < 50; pwm++) Msleep(5);
	}

   return(0);
}
/* uses timer2 (36kHz for IR communication */
/* counts falling and rising edge => 36kHz*2 = 72kHz */
SIGNAL (SIG_OUTPUT_COMPARE2)
{
	static unsigned char  bit=0, count=0;
	count72kHz ++;
	pin1a_x;
	pin2a_x;
	pin3a_x;
	pin4a_x;
if(count < pwm) {
	if((bitmustera & (1<<bit))==1){
		pin1a_on;
		pin2a_off;
		pin3a_x;
		pin4a_x;
	}
	if((bitmustera & (1<<bit))==2){
		pin1a_on;
		pin2a_x;
		pin3a_off;
		pin4a_x;
	}
	if((bitmustera & (1<<bit))==4){
		pin1a_on;
		pin2a_x;
		pin3a_x;
		pin4a_off;
	}
	if((bitmustera & (1<<bit))==8){
		pin1a_off;
		pin2a_on;
		pin3a_x;
		pin4a_x;
	}
	if((bitmustera & (1<<bit))==16){
		pin1a_x;
		pin2a_on;
		pin3a_off;
		pin4a_x;
	}
	if((bitmustera & (1<<bit))==32){
		pin1a_x;
		pin2a_on;
		pin3a_x;
		pin4a_off;
	}
	if((bitmustera & (1<<bit))==64){
		pin1a_off;
		pin2a_x;
		pin3a_on;
		pin4a_x;
	}
	if((bitmustera & (1<<bit))==128){
		pin1a_x;
		pin2a_off;
		pin3a_on;
		pin4a_x;
	}
	if((bitmustera & (1<<bit))==256){
		pin1a_x;
		pin2a_x;
		pin3a_on;
		pin4a_off;
	}
	if((bitmustera & (1<<bit))==512){
		pin1a_off;
		pin2a_x;
		pin3a_x;
		pin4a_on;
	}
	if((bitmustera & (1<<bit))==1024){
		pin1a_x;
		pin2a_off;
		pin3a_x;
		pin4a_on;
	}
	if((bitmustera & (1<<bit))==2048){
		pin1a_x;
		pin2a_x;
		pin3a_off;
		pin4a_on;
	}
}
	pin1b_x;
	pin2b_x;
	pin3b_x;
	pin4b_x;
if(count > pwm) {
	if((bitmusterb & (1<<bit))==1){
		pin1b_on;
		pin2b_off;
		pin3b_x;
		pin4b_x;
	}
	if((bitmusterb & (1<<bit))==2){
		pin1b_on;
		pin2b_x;
		pin3b_off;
		pin4b_x;
	}
	if((bitmusterb & (1<<bit))==4){
		pin1b_on;
		pin2b_x;
		pin3b_x;
		pin4b_off;
	}
	if((bitmusterb & (1<<bit))==8){
		pin1b_off;
		pin2b_on;
		pin3b_x;
		pin4b_x;
	}
	if((bitmusterb & (1<<bit))==16){
		pin1b_x;
		pin2b_on;
		pin3b_off;
		pin4b_x;
	}
	if((bitmusterb & (1<<bit))==32){
		pin1b_x;
		pin2b_on;
		pin3b_x;
		pin4b_off;
	}
	if((bitmusterb & (1<<bit))==64){
		pin1b_off;
		pin2b_x;
		pin3b_on;
		pin4b_x;
	}
	if((bitmusterb & (1<<bit))==128){
		pin1b_x;
		pin2b_off;
		pin3b_on;
		pin4b_x;
	}
	if((bitmusterb & (1<<bit))==256){
		pin1b_x;
		pin2b_x;
		pin3b_on;
		pin4b_off;
	}
	if((bitmusterb & (1<<bit))==512){
		pin1b_off;
		pin2b_x;
		pin3b_x;
		pin4b_on;
	}
	if((bitmusterb & (1<<bit))==1024){
		pin1b_x;
		pin2b_off;
		pin3b_x;
		pin4b_on;
	}
	if((bitmusterb & (1<<bit))==2048){
		pin1b_x;
		pin2b_x;
		pin3b_off;
		pin4b_on;
	}
}
	if(bit<11) bit++; else { bit=0; if(count) count --; else count=49; }
}
Das ist allerdings echt nur ein Testcode, die ISR läuft gnadenlos über. Aber als Einstieg schon mal nicht schlecht. Mit ein paar Optimierungen sollten 36 LEDs kein Problem sein.

Gruß

mic