www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATmega48 Initialisierung der timer1 + timer2 stören sich


Autor: Squat *** (squat)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe folgendes Problem. Ich stelle bei ATmega48 den Timer1 und 
Timer2 ein und lasse diese dann durchlaufen, jeodch funktioniert nur der 
Programmteil vom Timer2. Wenn ich diesen jedoch nicht einstelle, läuft 
der zuvor eingestellte Timer1.
//TIMER1 initialize - prescale:64
// WGM: 0) Normal, TOP=0xFFFF
// desired value: 100mSec
// actual value: 100,000mSec (0,0%)
void timer1_init(void)
{
 TCCR1B = 0x00; //stop
 TCNT1H = 0xCF; //setup
 TCNT1L = 0x2C;
 OCR1AH = 0x30;
 OCR1AL = 0xD4;
 OCR1BH = 0x30;
 OCR1BL = 0xD4;
 ICR1H  = 0x30;
 ICR1L  = 0xD4;
 TCCR1A = 0x00;
 TCCR1B = 0x03; //start Timer
}


//TIMER2 initialize - prescale:1
// WGM: CTC
// desired value: 10uSec
// actual value: 10,125uSec (1,2%)
void timer2_init(void)
{
 TCCR2B = 0x00; //stop
 ASSR  = 0x00; //set async mode
 TCNT2 = 0xB0; //setup
 OCR2A = 0x50;
 OCR2B = 0x00;
 TCCR2A = 0x02; 
 TCCR2B = 0x01; //start
}

Irgendwie verstelle ich wohl beim Timer2 die Einstellung vom Timer1. 
Zumindest scheint es mir so, da beide unabhängig von einander laufen.

Vielleicht fällt jemandem was auf und kann mir somit weiter helfen.

Autor: Squat *** (squat)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gerade habe ich nochmal was ausprobiert und festgestellt, dass wohl doch 
nichts verstellt ist, jedoch die Timer sich trotzdem irgendwie stören.

Ich habe den Interrupt vom Timer2 mal entfernt.
TIMSK1 = 0x01; //timer 1 interrupt sources
TIMSK2 = 0x00; //timer 2 interrupt sources
Dann lief wieder der Programmteil vom Timer1.

Autor: Magnus M. (magnetus) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Squat *** schrieb:
> jeodch funktioniert nur der Programmteil vom Timer2. Wenn ich diesen
> jedoch nicht einstelle, läuft der zuvor eingestellte Timer1.

Wie hast du das festgestellt?

Gruß,
Magnetus

Autor: Squat *** (squat)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe unterschiedliche Funktione ausgeführt, diese laufen über jeden 
der Timer (Lauflicht, Analog-Digital-Wandlung, Blicklicht etc.) Jedoch 
immer nur über den einen oder den anderen Timer.

Autor: Magnus M. (magnetus) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zeig mal dein Programm.

Autor: Squat *** (squat)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jetzt wolte ich Dir gerade das Programm verkürzt zusammenpacken (in eine 
Datei). Leider funktionieren jetzt beide Timer.

Jetzt habe ich die Schritte nachvollzogen und bin auf das Problem 
gestoßen.

Ich habe in dem 10usec (Timer2) eine Funktion ausgeführt, die drei 
Servos auf Softwarebasis ansteuert. Dies hat auch wunderbar 
funkerioniert, jedoch wollten aus diesem Grund die anderen Funktionen 
des Timer1 irgendwie nicht ausgeführt werden.

Ich werde mal versuchen, das Programm so hier darzustellen und hoffe, 
dass mir jemand eine andere Lösung für die Servoansteuerung bzw. das 
ausführen der Funktion mitteilen kann.

Bitte entschuldigt, wenn es etwas unübersichtlich ist. Ich lerne immer 
noch dazu.
//ICC-AVR application builder : 13.04.2010 16:15:44
// Target : m48
// Crystal: 8.0000Mhz

#include <iom48v.h>
#include <macros.h>


unsigned int RulInt = 9;
unsigned int WarnInt = 49;

unsigned int f_1sec;
unsigned char f_100ms;


//------------------------------------------------------------------------------
             // Port-Zuweisung
//------------------------------------------------------------------------------

/* PORT B */
//#define  PB7
//#define  PB6
#define jump2 PB5
#define jump1 PB4
#define servo3 PB3
#define servo2 PB2
#define servo1 PB1
#define pin_taster PB0

/* PORT C */
#define poti1 PC7
#define reset PC6
#define pinnchen PC5
//#define  PC4
//#define  PC3
#define sound1 PC2
#define poti3 PC1
#define poti2 PC0

/* PORT D */
#define ziel_led PD7
#define pump1 PD6
#define pump2 PD5
#define R_LED4 PD4
#define R_LED3 PD3
#define R_LED2 PD2
#define sound2 PD1
#define R_LED1 PD0



void port_init(void)
{
 PORTB = 0xF1;
 DDRB  = 0x0E;
 PORTC = 0x43; 
 DDRC  = 0xBC;
 PORTD = 0x00;
 DDRD  = 0xFF;
}
//TIMER1 initialize - prescale:64
// WGM: 0) Normal, TOP=0xFFFF
// desired value: 100mSec
// actual value: 100,000mSec (0,0%)
void timer1_init(void)
{
 TCCR1B = 0x00; //stop
 TCNT1H = 0xCF; //setup
 TCNT1L = 0x2C;
 OCR1AH = 0x30;
 OCR1AL = 0xD4;
 OCR1BH = 0x30;
 OCR1BL = 0xD4;
 ICR1H  = 0x30;
 ICR1L  = 0xD4;
 TCCR1A = 0x00;
 TCCR1B = 0x03; //start Timer
}
#pragma interrupt_handler timer1_ovf_isr:iv_TIM1_OVF
void timer1_ovf_isr(void)
{
 static unsigned int t1;
 //TIMER1 has overflowed
 TCNT1H = 0xCF; //reload counter high value
 TCNT1L = 0x2C; //reload counter low value
  if(t1) {t1=9; f_1sec=1;}
    else   --t1;

}


//----------------------------------------------------------------------------//
         // Servo
//----------------------------------------------------------------------------//

// Bei dieser Funktion werden jeweils 2000x 10usec gezählt um 20milisec für das PPM-Signal zu erzeugen.

volatile unsigned char servo1pos; //(98,7 =1msec bis 197,5 = 2msec)
volatile unsigned char servo2pos; //(98,7 =1msec bis 197,5 = 2msec)
volatile unsigned char servo3pos; //(98,7 =1msec bis 197,5 = 2msec)

void servoweg(void)
 {
static int count1;
static int count2;
static int count3;
//----Servo 1-----------------------------------------------------------------//

  if(count1>servo1pos) {PORTB &= ~(1<<servo1);}
  else PORTB|=(1<<servo1);
  
  if(count1<2000+servo1pos)count1++;
  else count1=0;
//----Servo 2-----------------------------------------------------------------//
  
  servo2pos = 20;
  if(count2>servo2pos) {PORTB&=~(1<<servo2);}
  else PORTB|=(1<<servo2);

  if(count2<2000+servo2pos)count2++;
  else count2=0;
//----Servo 3-----------------------------------------------------------------//
                
  if(count3>servo3pos)PORTB&=~(1<<servo3);
  else PORTB|=(1<<servo3);
  
  if(count3<2000+servo3pos)count3++;
  else count3=0;
  

}

//TIMER2 initialize - prescale:1
// WGM: Normal
// desired value: 10uSec
// actual value: 10,000uSec (0,0%)
void timer2_init(void)
{
 TCCR2B = 0x00; //stop
 ASSR  = 0x00; //set async mode
 TCNT2 = 0xB0; //setup
 OCR2A = 0x50;
 OCR2B = 0x00;
 TCCR2A = 0x00; 
 TCCR2B = 0x01; //start
}
#pragma interrupt_handler timer2_ovf_isr:iv_TIM2_OVF
void timer2_ovf_isr(void)
{
 static unsigned int t2;
 TCNT2 = 0xB0; //reload counter value

 //servoweg();                                          //HIER IST DER ÜBELTÄTER
 
 if(t2) {t2=9; f_100ms=1;}
    else   --t2;
}
//ADC initialize
// Conversion time: 6uS
void adc_init(void)
{
 ADCSRA = 0x00; //disable adc
 ADMUX = 0x00;  //select adc input 0
 ACSR  = 0x80;
 ADCSRB = 0x00;
 ADCSRA = 0x01;
}

unsigned char taster = 0;
//----------------------------------------------------------------------------//
         // Tasterabfrage
//----------------------------------------------------------------------------//
void funkt_tast(void)
{
 static char rw = 0;
    if(taster == 0 && !(PINB & (1<<pin_taster)))   //Taster wird gedrueckt (steigende Flanke)
    {
        taster = 1;
        rw = 1;
    }
    else if (taster == 1 && !(PINB & (1<<pin_taster)))   //Taster wird gehalten
    {
         taster = 2;
         rw = 0;
    }
    else if (taster == 2 && (PINB & (1<<pin_taster)))   //Taster wird losgelassen (fallende Flanke)
    {
        taster = 3;
        rw = 0;
    }
    else if (taster == 3 && (PINB & (1<<pin_taster)))   //Taster losgelassen
    {
        taster = 0;
        rw = 0;
    }

   
   
}
unsigned char i = 0;

unsigned int result;
unsigned int poti_1;
unsigned int poti_2;
unsigned int poti_3;
unsigned int batt;


//----------------------------------------------------------------------------//
       //         AD-Wandlung
//----------------------------------------------------------------------------//
 void ad(void)
 {
       // Dummy-Readout
       ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1);  // ADC aktivieren, Frequenzvorteiler: setzen auf 64 (8 MHz / 64 = 125 kHz) und ADC aktivieren            
       ADMUX |= (1<<REFS0) | (1<<REFS1);        // interne Referenzspannung nutzen 
       ADCSRA |= (1<<ADSC);               // eine ADC-Wandlung
       while(!(ADCSRA & (1<<ADIF)));          // auf Abschluss der Konvertierung warten (ADIF-bit)
       result = ADC;                    // ADC muss einmal gelesen werden,
                                        // sonst wird Ergebnis der nächsten Wandlung
                                        // nicht übernommen.
       
       //ADC-Messung mit arithmetischen Mittel aus 4 Messungen
       result = 0;
       for (i=0;i<4;i++)
            {
          ADCSRA |= (1<<ADSC);             // Messung ausfuehren
        while ( ADCSRA & (1<<ADSC) );        // Konvertierung abwarten
        result += ADC;                     // aufaddieren zur Mittelwertbildung (ADC auslesen der zwei Bits
        }
        ADCSRA &= ~(1<<ADEN);               // ADC ausschalten
        
        result /= 4;                 // 
        

}

//----------------------------------------------------------------------------//
       //         AD-Wandlung für Poti 1-3 und Batterie
//----------------------------------------------------------------------------//
 void adc(void)
 {
 //Poti 1
 ADMUX = 0x00;// Kanal waehlen (ADC0)
 ad();
 result /= 4;//auf 8 Bit reduzieren
 poti_1 = result;
 OCR0A = poti_1;
 // Poti 2
 ADMUX = 0x01;// Kanal waehlen (ADC1)
 ad();
 result /= 4;//auf 8 Bit reduzieren
 poti_2 = result;
 OCR0B = poti_2;
  //Poti 3
 ADMUX = 0x07;// Kanal waehlen (ADC7)
 ad();
 result /= 4;//auf 8 Bit reduzieren
 poti_3 = result;
 OCR0A = poti_3;
 
  //Batteriespannung
 ADMUX = 0x02;// Kanal waehlen (ADC2) 
 ad();
 batt = result;
 

 
}
 

 //----------------------------------------------------------------------------//
       //         Akkuwarnung
//----------------------------------------------------------------------------//
 
void warn(void)
{
static unsigned int delay;
        if (delay>WarnInt)
      {
      delay=0;
      adc();
      if (poti_3>40)//if (batt < 500) Momentan noch auf einem Poti gelegt
      {PORTC ^= (1<<pinnchen);}
      else {PORTC |= (1<<pinnchen);}
      }
      else delay++;
}

//----------------------------------------------------------------------------//
       //         RundUmLicht
//----------------------------------------------------------------------------//
unsigned char blink_state = 0;
unsigned char countLED = 0;
void rul(void)
{
  switch (blink_state)
 {

  case 0: // R_LED1 ein
  {
   PORTD &= ~((1<<R_LED2) | (1<<R_LED3) | (1<<R_LED4));
   PORTD |= (1<<R_LED1);
   break;  
  }
  case 1: // R_LED2 ein
  {
   PORTD &= ~((1<<R_LED1) | (1<<R_LED3) | (1<<R_LED4));
   PORTD |= (1<<R_LED2);
   break;  
  }  
  case 2: // R_LED3 ein
  {
   PORTD &= ~((1<<R_LED1) | (1<<R_LED2) | (1<<R_LED4));
   PORTD |= (1<<R_LED3);
   break;  
  }  
  case 3: // R_LED4 ein
  {
   PORTD &= ~((1<<R_LED1) | (1<<R_LED2) | (1<<R_LED3));
   PORTD |= (1<<R_LED4);
   break; 
  } 
 }
countLED++;
if (countLED>RulInt) //Hier stellt man die Drehzahl der Rundumleuchte ein
{
countLED=0;
blink_state++;
}
if (blink_state>3) {blink_state=0;     // Lauflicht neustarten
   }
}


////////////////////////////////////////////////////////////////////////////////
// Hauptprogramm
////////////////////////////////////////////////////////////////////////////////
void main(void)
{
 //stop errant interrupts until set up
 CLI(); //disable all interrupts
 port_init();
 timer1_init();
 timer2_init();
 adc_init();

 MCUCR = 0x00;
 EICRA = 0x00; //extended ext ints
 EIMSK = 0x00;
 
 TIMSK0 = 0x00; //timer 0 interrupt sources
 TIMSK1 = 0x01; //timer 1 interrupt sources
 TIMSK2 = 0x01; //timer 2 interrupt sources
 
 PCMSK0 = 0x00; //pin change mask 0 
 PCMSK1 = 0x00; //pin change mask 1 
 PCMSK2 = 0x00; //pin change mask 2
 PCICR = 0x00; //pin change enable 
 PRR = 0x00; //power controller
 SEI(); //re-enable interrupts
 //all peripherals are now initialized
   
 while(1)
  {
    if(f_1sec)
    {
  f_1sec=0;
  rul();              // RundUmLicht
  }
    if(f_100ms)
    {
  f_100ms=0;
  adc();           // AD-Wandlung aller 4 Kanäle (3x Poti, 1x Batteriespannung)
  warn();         // Unterspannungswarnung
    funkt_tast();     // Taster
   if (taster == 1)  PORTD |= (1<<ziel_led); // LED an
  if (taster == 0)  PORTD &= ~(1<<ziel_led);// LED aus
  }
  }return;
}

Autor: Ich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Poste doch sowas bitte als Anhang!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.