Anfängerfrage Timer/Counter

Gast #2162261
Lesenswert?

Hallo zusammen,

ich möchte gerne ein GSM-Modem ansteuern. Sprich ein anderes Modem 
anrufen.
Wenn nach einer bestimmten Zeit das Modem nicht antwortet will ich eine 
andere Nummer wählen.

ATD+xxxxxxxx;
bspw. 10 sek warten!
Wenn keine Antwort, neue Nummer wählen!

Ich verwende eine Arduino Mega Board: ATmega2560 mit 16MHz.
Counter und Timer bereiten mir noch etwas Kopfzerbrechen und ich steig 
nicht so richtig durch und weiß nicht so richtig, wie ich das angehen 
soll. Muss man das mit Interrupts machen?
Gruß
Michel
Gast #2162399
Lesenswert?

Hi!

Also wenn du einen Timer starten willst, hab ich hier mal was für dich:
1
#include <avr/interrupt.h>
2
//#include <avr/math.h>
3

4

5
#define MCU_FREQ 16000000
6
#define SAMPLINGRATEHZ 300
7
#define PRESCALER 8
8
//1 Tick = 16e6 / 8 Prescaler => 2.000.000 Ticks pro Sekunde => 2.000.000/HERTZ = TimerTicks 
9
//(entspricht bei 300Hz 6666 Ticks = 0x1A0B) => Timer Offset muss auf 0xFFFF-0x1A0B gestellt werden
10
// damit alle 0x1A0B Ticks ein Overflow entsteht
11

12
int timer1Offset = 0xFFFF - (MCU_FREQ/(PRESCALER*SAMPLINGRATEHZ));
13

14
void setup()
15
{  
16
  //Configure Timer 1
17
  PRR &= ~(1<<PRTIM1); //disable Power Reduction Timer 1 (PRTIM1); 
18
  TCCR1A = 0x00; //Normal Mode
19
  TCNT1 = timer1Offset; //Setz den Timer auf den Startwert.
20
  
21
  
22
  if (1== PRESCALER) TCCR1B =    0b0000001; //Normal mode with prescaler 1
23
  if (8== PRESCALER) TCCR1B =    0b0000010; //Normal mode with prescaler 8
24
  if (64== PRESCALER) TCCR1B =   0b0000011; //Normal mode with prescaler 64
25
  if (256== PRESCALER) TCCR1B =  0b0000100; //Normal mode with prescaler 256
26
  if (1024== PRESCALER) TCCR1B = 0b0000101; //Normal mode with prescaler 1024
27

28
  TIMSK1 |= (1<<0); //Enable Overflow Interrupt
29
  sei(); //set_interrupts(), nicht sicher, ob man das auch noch braucht
30
  
31
}
32

33

34
//diese Funktion wird aufgerufen, wenn der Timer überlauft (TCNT1 == 0xFFFF)
35
ISR (TIMER1_OVF_vect)
36
{ 
37
   // ändere die wählnummer hier
38

39
  //reset des Timers auf den Startwert
40
  TCNT1 = timer1Offset;
41
}

In diesem Beispiel wird der Timeroverflow 300 mal/sekunde aufgerufen.

Um auf einmal in 10 Sek. zu kommen müsstest du dein timer1Offset so 
berechnen:

0xFFFF - ((MCU_FREQ/PRESCALER) * 10), was aber nicht geht weil selbst 
bei Prescaler 1024 kommst du beim Klammernterm auf 156250, was keine 
16bit Zahl mehr ist!

Daher kannst du nur zb. 0xFFFF - ((MCU_FREQ/PRESCALER) * 2) ausrechnen, 
also bei 1024 Prescaler 0xFFFF - 0x7A12 = 0x85ED.

Dann wird die Interruptroutine alle 2 Sekunden aufgerufen.
Die musst du dann so ändern, dass der Code nur jedes 5te mal ausgeführt 
wird:
1
int i = 0;
2
ISR (TIMER1_OVF_vect)
3
{ 
4
   i++;
5
   if (i>5) 
6
   {   
7
      // ändere die wählnummer hier
8
      i=0;
9
   }
10

11
  //reset des Timers auf den Startwert
12
  TCNT1 = timer1Offset;
13
}

Ich hoffe das war verständlich und v.a. dass ich mich nicht verrechnet 
hab.
Bitte zu bedenken, dass ich selbst auch noch Anfänger bin es geht sicher 
noch besser/schöner, aber so sollte es funktionern.

Viel Glück!
Gast #2162566
Lesenswert?

Hallo,
vielen Dank für die Antworten. Ich habs nun mal probiert, aber es klappt 
noch nicht so richtig. Also im Grunde will ich eine Nummer anrufen und 
wenn die/der nach 15 Sekunden ran geht, die Verbindung beenden und eine 
andere Nummer wählen.

Ich hab also zwei Nummern, die abwechselnd anrufen will, bis jemand ran 
geht, bzw. durch Auflegen bemerkbar macht, dass er da ist. Ich erhalte 
dann vom Modem die Antwort BUSY. Mit gsm_ans = 1 springe ich in 
gsm_antwort()und warte/werte die Antwort des Modems ab/aus. Wenn nicht 
BUSY detektiert wurde soll der Anruf nach 15 min mit ATH beendet und das 
Ganze von vorne beginnen. Wenn das Modem nach ATD+xxxxx; sendet erhöhe 
ich init_step um eins.

Ich habs nun mal mit einer Nummer versucht und es klappt nicht 
richtig...Ich seh den Fehler nicht...zum Haare raufen!

Es wäre wirklich nett wenn mir jemand weiterhelfen könnte. VG


  do
    if ( gsm_ans == 0 )
    {

      if ( init_step == 0 )
      {
        uarts( "ATD" );

        uarts( number1 );

        uarts( ";" );

        gsm_ans = 1;
      }


      if ( init_step == 1 )
      {

        for( int i = 0; i<15000; i++)
        {
             _delay_ms(1);

          if( busy == 1 )
          {
             break;
          }
        }


        if( busy == 1 )
        {
          uarts("BUSY detektiert");
          busy = 0;
        }

        else
        {
          uarts( "ATH" );
          init_step = 0;
        }

        gsm_ans = 1;

      }

    }

    else
    gsm_antwort();

  while( init_step <= 1 );

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren