Forum: Compiler & IDEs 10LED PWM auf Atmega8, wie gehts besser?


von Mirco B. (mblitz)


Lesenswert?

Hi,
ich bin neu hier und auch ziehmlich unerfahren im programmieren von 
Microcontrollern.

Mit ein bisschen klauen hier und da habe ich mir mein erstes PWM-Prog 
geschrieben.

10 LEd werden über ein Array angesteuert, das den ablauf vorgibt (Chase, 
Still, Fading etc).

Wichtig war mir vorallem, das es äuserst Variabel ist, denn die 
programmierung soll für verschiedene situationen angepasst werden 
können.

Allerdings denke ich das es endlos optimiert werden könne, ich hab nur 
kein plan wie.

Stoßt mich bitte in die richtge richtung :-)

Hier mein Code:

#define F_CPU 8000000
#define CLK 8000000

#include <stdlib.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <inttypes.h>
#include <util/delay.h>
#include <avr/interrupt.h>


/****************************
 LED POI over MATRIX
****************************/

//Hilfskonstruckt
//Delay
#define cycle(us) _delay_loop_2(us * (CLK/4000000))
//Bit An oder Aus
#define on(BYTE, BIT)  BYTE |= 1 << BIT;
#define off(BYTE, BIT) BYTE &= ~(1 << BIT);

//InLine used vars
volatile int time=0;
volatile int i,j=0;


//VARIABLER PART
//###################################################################### 
##

//Ablauf
volatile int cycletime = 2000; //Wartezeit bis die Matrix einen Wert 
vorrückt
//volatile int direction = 1;  //1=aus=0V  2=aus=5V

//Led-Variablen
volatile int led_count = 10;  //Anzahl der LED
volatile int led_bit[10] = {1,2,3,4,5,0,1,2,3,4};
volatile int led_port[10] = {1,1,1,1,1,2,2,2,2,2}; //Auf welchem Port? 
0=B 1=D
volatile int led_time[10] = {0,0,0,0,0,0,0,0,0,0}; //Initialwert der LED 
= -1 = aus

volatile int led_matrix_length = 33;
volatile int led_matrix[33][10] = {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
{ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4},
{ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5},
{ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6},
{ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7},
{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8},
{ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9},
{ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10},
{ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11},
{ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12},
{ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13},
{ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14},
{ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15},
{ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16},
{ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17},
{ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18},
{ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19},
{ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20},
{ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21},
{ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22},
{ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23},
{ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24},
{ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25},
{ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26},
{ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27},
{ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28},
{ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29},
{ 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},
{ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31},
{ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}};
//###################################################################### 
###

SIGNAL(SIG_OVERFLOW0) //Stellt Ports auf an oder aus in 64 Zyklen
{
  int numled=0;
  time++;      //Bei jedem clock overvlow (alle 256 zyklen) time 
hochzählen

  if(time>=32) time=0;

  for(numled=0; numled<led_count; numled++){ //Jede LED Durchgehen
  if(led_port[numled]==1){   //auf welchem Port liegt die LED? PORTB
      if(time>led_time[numled]){   //PWM Abfrage LED AN
          off(PORTB, led_bit[numled]);
    }else{                        //PWM-Abfrage LED AUS
          on(PORTB, led_bit[numled]);
    }
  }else{                            //PORTD
      if(time>led_time[numled]){
          off(PORTC, led_bit[numled]);
    }else{
        on(PORTC, led_bit[numled]);
    }
  }
  }

}



int main()
{
  DDRB=0xFF;  //PortB auf Ausgang
  DDRC=0xFF;  //PortC auf Ausgang
    PORTB=0x00; //PortB aus
    PORTC=0x00; //PortC aus

  //Timer 8Bit setup
  on(TCCR0, CS00);    //Int. CLK/1
  off(TCCR0, CS01);
  off(TCCR0, CS02);
  TCNT0 = 0x00;        //Timer-Reg. löschen
  on(TIMSK, TOIE0);    //Overflow-Int. enable
  sei(); //Interropt global

  i=0;
  while(1)  //endlosschleife des hauptprogramms
  {
    //Einen nach vorn in der Matrix
  for(i=0; i<led_matrix_length; i++){
      for(j=0; j<led_count; j++){
      led_time[j] = led_matrix[i][j];
    }
  cycle(cycletime);
  }
  }

}

von Falk B. (falk)


Lesenswert?

@ Mirco Blitz (mblitz)

>ich bin neu hier und auch ziehmlich unerfahren im programmieren von
>Microcontrollern.

Und im Umgang mit Foren. Lange Quelltexte gehören in den Anhang.
Siehe Netiquette.

>Mit ein bisschen klauen hier und da habe ich mir mein erstes PWM-Prog
>geschrieben.

Soft-PWM

Kann man relativ leicht auf 16/24/32 Kanäle aufbohren.

MfG
Falk

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.