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
Lesezeichen