Forum: Mikrocontroller und Digitale Elektronik Schaltnetzteil steuern mit Atmega8 PWM an Port B5


von Vadim E. (eisenstein)


Lesenswert?

Sehr geehrte Spezialisten,

Ich bastele eine Ladevorrichtung zum Laden von Akkus. Mein Problem ist, 
dass ich fast PWM nicht nur an Port B1 und B2 realisieren möchte sondern 
auch  an Port B4 oder B5.
Ich habe ein Gegentakt gesteuertes Durchfluss Wandler gebaut was ich 
sehr schön an PB0 und PB1 steuere, jetzt versuche ich dasselbe Ergebnis 
auch an anderen Ports wie PB3-PB5 zu ermöglichen.

Ich bin gut in Elektronik aber Microkontroller Welt ist für mich neu!!!

Vielen Dank im Voraus!!!

Mein gebasteltes :) (Google) Code in AVR-C

//---------------------------------------------------------------------- 
---
// Prozessor : ATmega8
// Takt : 3686400 Hz
// Sprache : AVR-C
// Datum : 13.5.2011
// Version : 1.0
// Autor : Vadim Eisenstein
// Programmer: mySmartUSB Light
// Port : Port 3
//---------------------------------------------------------------------- 
-----

//Heder Initiirung
#define  F_CPU   3686400
#include <avr/io.h>
#include <util\delay.h>
#include <stdint.h>
#include <stdio.h>
#include "messen.h"
#include "lcd-routines.h"

// PWM Timer sowie Ausgabe Funktion Initialisieren
void ausgabe(int wert)
  {       int x=0, vorkomma, nachkomma;
    char messwert_vorkamma[20];
    char messwert_nachkomma[20];


    x=4.8876*wert;
    vorkomma=x/1000;
    nachkomma=x-(vorkomma*1000);
    nachkomma=nachkomma/10;

    lcdGoto (1,6); lcdString (".   ");

    sprintf(messwert_vorkamma, "%d", vorkomma);
    lcdGoto (1,5);
    lcdString (messwert_vorkamma);

    sprintf(messwert_nachkomma, "%d", nachkomma);
    lcdGoto(1,7);  if (nachkomma<10) lcdString ("0");
    lcdString (messwert_nachkomma);
  }


// Timer einstellen
void timer_init(void)
{
   // OC1A auf Ausgang
  DDRB = (1 << PB5 );




  TCCR1A = (1<<COM1A1) | (1<<WGM11);
  TCCR1B = (1<<WGM13) | (1<<WGM12) | (1<<CS10);




    ICR1 = 0x0080;



}



//////////////////////////////////////////////////////////////////////// 
/////
// Main-Funktion
//////////////////////////////////////////////////////////////////////// 
/////
int main(void)
{
  int zaeler=1;
  int beenden=1;

     DDRB &= ~_BV(PB0);
     PORTB |= _BV(PB0);
     DDRB &= ~_BV(PB1);
     PORTB |= _BV(PB1);
     DDRB &= ~_BV(PB2);
     PORTB |= _BV(PB2);


   //Begrüßung
     lcdInit();
     lcdGoto (1, 6);lcdString ("Willkomen");
    lcdGoto (2, 1);lcdString ("Lade Station Rev:1.0 Bitte Warten....");
    _delay_ms(60000);
  lcdClear();

     while(1)
     { while(beenden)
    { lcdGoto (1, 1);lcdString ("Menu:");
    if (zaeler==1){ lcdGoto (1, 7); lcdString("Laden   ");}
  if (zaeler==2){ lcdGoto (1, 7);lcdString ("Entladen");}
  if (zaeler==3){ lcdGoto (1, 7);lcdString ("Lagern  ");}

    if (bit_is_clear(PINB,0))
       { zaeler =zaeler+1;
       if (zaeler==4)
         zaeler=1;
      _delay_ms(100);
      }

    if (bit_is_clear(PINB,1))
       beenden=0;
      }
     lcdClear();

  switch(zaeler)
    { case 1:
    do {
  lcdGoto (1, 1); lcdString ("Menu LADEN gewaelt");
      _delay_ms(20000);
      lcdClear();
      lcdGoto (1, 1); lcdString ("Ich werde LADEN....");
      _delay_ms(20000);
      lcdClear();
 uint16_t buffer;
timer_init();
    OCR1A = 0x0000;
    char messwertOCR1A[20];

  while( 1 )
      {
  cdGoto (1, 1); lcdString ("C-0:");
    ausgabe(MESSWERT(0));
  lcdGoto (2, 1); lcdString ("OCR1A:");
                sprintf(messwertOCR1A, "%d", OCR1A);
                lcdGoto(2,8);  if (OCR1A<10) lcdString (" ");
                lcdGoto(2,9);  if (OCR1A<100) lcdString (" ");
                lcdGoto(2,7);lcdString (messwertOCR1A);

        buffer = MESSWERT(0);


  OCR1A = (buffer>>3);

if (bit_is_clear(PINB,2))
                     break;
                   }


  } while(bit_is_set(PINB,2));
      beenden=1;
    lcdClear();

  case 2:
    do {
  lcdGoto (1, 1); lcdString ("Menu Entladen...");
  _delay_ms(20000);
    lcdClear();
  lcdGoto (1, 1); lcdString ("Ich werde Entladen..");
    _delay_ms(20000);
    lcdClear();
  while (1)
  {

lcdGoto (1, 1); lcdString ("Ich entlade...");

  if (bit_is_clear(PINB,2))
  break;
     }


   } while(bit_is_set(PINB,2));
   beenden=1;
  lcdClear();

     }


  }

}

von Krapao (Gast)


Lesenswert?

1) Kommentar zu ausgabe() ist falsch: PWM wird dort nicht initialisiert.

2) Die Zeile DDRB = (1<<PB5); in timer_init() zerstört die vorherigen
Einstellungen von DDRB in main(). Das ist hier nicht schwerwiegend, weil 
die sonstigen Einstellungen die Pins auf Eingang schalten.

3) _delay_ms(60000); Wirklich 60s lang die Dummymeldung "Lade Station 
Rev:1.0 Bitte Warten...." anzeigen, ohne dass der µC arbeitet?

4) vor case 2: fehlt das break von case 1:; break von case 2 fehlt auch. 
Der Akku wird direkt nach dem Laden wieder entladen!

5) zaeler kann die Werte 1,2,3 annehmen. Im switch fehlt case 3 
(Lagern). Die Benutzereingabe ist danach nicht mehr möglich.

6) Die Benutzereingaben über Taster (?) an PB0 und PB1 sind ohne 
Entprellung.

7) AVRs können nur an bestimmten Pins Hardware-PWM ausgeben. Wenn du 
andere Pins brauchst, kannst du dort per Software-PWM arbeiten. Dazu 
brauchst du eine Interrupt-Service-Routine ISR. Das Thema Software-PWM 
ist in der Artikelsammlung erklärt.

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.