Forum: Mikrocontroller und Digitale Elektronik AT90CAN128 - Beeper und Simulation dessen gehen nicht


von spaxx (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe ein µC- Problem und komme alleine nicht mehr weiter.
Ich arbeite mit dem AT90CAN128 µC und wollte den Piepser per Output 
Compare Interrupt im CTC mode ansteuern.

Der Piepser soll nicht durchgehend, sondern 2x kurz ein- und 
ausgeschaltet werden. Beim Ausschalten liegt das eine Problem, denn er 
bleibt einfach an.
Das wollte ich erreichen, indem ich den Prescaler auf 0 (inaktiv) 
stelle. Ist das der falsche Ansatz?

Ich habe versucht, meinen Code zu simulieren, da bin ich mir schon nicht 
sicher, ob das Simulieren von Interrupts möglich ist,
jedenfalls geht das total schief.

Ich verwende Timer1 für einen 100ms Task, der mitzählt, wie lange der 
Piepser ein- oder aus ist. Und Timer3 zur Erzeugung der gewünschten 
Frequenz für den Piepser.
Jedesmal, wenn ich in die ISR von Timer1 komme, sind die globalen Zähler 
wieder auf dem Anfangswert, wie sie global initialisiert wurden.
Wenn ich den µC flashe, wird der Piepser aktiviert, aber nicht mehr 
ausgeschaltet.


Ich steh total auf dem Schlauch, weiß jemand wo das Problem liegt?
Gibt es eine bessere/einfachere Möglichkeit, den Piepser anzusteuern?

von Krapao (Gast)


Lesenswert?

Bei Verdacht auf Probleme mit der Hardware:

Wie ist der Piepser an den AT90CAN128 µC angeschlossen, direkt an PE3 
(Schaltplan, Vcc)?

Kommt der Piepser mit den elektrischen Werten am Ausgang PE3 aus, also 
max (Datenblatt)?

Bei Verdacht auf Probleme mit PWM/Timer in der Software:

Funktioniert die Ansteuerung ohne Timer mit einfachen Warteschleifen in 
Software (delay_ms oder delay_us)?

K.I.S.S.: Man braucht bestimmt keine drei Timer um einen Piepser 
anzusteuern.

von spess53 (Gast)


Lesenswert?

Hi

Ich würde einfach behaupten, das du ihn nach dem Ausschalten mit


>      BeeperActive = 0;
>          --NumberOfBeeps;
>        }
>      }

>      if(BeeperActive == 0)

gleich wieder einschaltest.

MfG Spess

von spaxx (Gast)


Angehängte Dateien:

Lesenswert?

@ Krapao

Der Piepser befindet sich auf einer externen Platine. Ich habe den 
Ausgang von PE3 direkt an Spkr 1 (siehe Schematic) angelötet. Der kann 
auch über die Relays angesteuert werden (bis zu 24V). Da PE3 ja nur 5V 
ausgibt, dachte ich, löte ich den Ausgang direkt an den Speaker, der mit 
3,3V und 5V angesteuert werden kann laut Datenblatt.

Ich habe ihn bisher nur zum Dauerpiepen gebracht mit verschiedenen 
Frequenzen. Dann wollte ich zwei kurze Warntöne erzeugen und diese in 
ein anderes Programm einbauen, das bereits diesen 100ms Task (Timer1) 
und Timer2 schon verwendet. Deshalb verwende ich ja nur 1 weiteren Timer 
für die Tonfrequenz.. (ist doch okay so oder?)

Ich versuch das mal mit den Warteschleifen, allerdings versteh ich 
nicht, warum im Simulator die globalen Flags/Zähler bei jedem Eintreten 
in die ISR wieder auf Initialwerten sind.

@ spess53

Der wird nicht gleich wieder eingeschaltet, sondern BeeperTime wird 5 
mal (100ms) dekrementiert bis 0, und dann wieder eingeschaltet oder seh 
ich das falsch!?

von Krapao (Gast)


Lesenswert?

Ich würde versuchen das Programm zu vereinfachen.
In etwa so (ohne Simulation/Test)
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <stdint.h>
4
5
// ### GLOBALS ###
6
uint16_t delay = 10;
7
volatile int BeeperTime;
8
volatile int BeeperActive;
9
volatile int NumberOfBeeps;
10
11
#define BEEPERTIMER   5
12
#define NUMBEROFBEEPS 2
13
14
void initBeeper(void)
15
{          
16
  DDRE = (1 << DDE3); // Pin PE3 (Piepser) Ausgang
17
  // Timer 3 für Piepser Frequenz  
18
  // toggle Channel A,  CTC (Mode 4) WGM:0100               
19
  TCCR3A = (1 << COM3A0);
20
  // TCCR3B (Mode & Prescaler) wird in beeper_on()/beeper_off() gesetzt
21
  beeper_off();
22
  // in CTC mode TCNT3 (counter) and OCR3A will be compared consequently,
23
  // if equal, Channel A is toggled and TCNT3 is set to 0
24
  OCR3AH = 0x00;
25
  OCR3AL = 0x10;     //  f = 16Mhz / (2N (1 + OCR3))
26
  TIMSK3 &= ~(1<<OCIE3A); // KEINE Interrupts auf Comp Wert A zulassen
27
}
28
29
void beeperOn(void)
30
{                    
31
  TCCR3B = (1 << WGM32)|(1<<CS02)|(1<<CS00); // Timer3 Prescaler 1024
32
  BeeperTime = BEEPERTIMER;
33
  BeeperActive = 1;
34
}
35
36
void beeperOff(void)
37
{                    
38
  TCCR3B = (1 << WGM32); // Timer3 Prescaler 0 (off)
39
  BeeperTime = BEEPERTIMER;
40
  BeeperActive = 0;
41
}
42
43
void beep(void)
44
{
45
  NumberOfBeeps = NUMBEROFBEEPS;
46
  beeperOn();
47
}
48
49
void warte_5s(void)
50
{
51
  for (int i = 0; i < 50; i++)
52
    delay_ms(100);
53
}
54
55
// ####################### MAIN ##################################
56
int main(void)
57
{
58
  initBeeper();
59
60
  // 100 ms Timer1: CTC-Mode, Top-Value OCR1A, Prescaler 256
61
  TCCR1B |= (1<<WGM12)|(1<<CS12); 
62
  OCR1A = 6250-1;
63
  TIMSK1 |= (1<<OCIE1A); 
64
65
  sei();
66
67
  while(1)
68
  { 
69
    beep();
70
    warte_5s();
71
  }
72
}
73
74
// ### Interrupt ###
75
ISR (TIMER1_COMPA_vect) //100ms Task
76
{    
77
  if(NumberOfBeeps > 0)
78
  {  
79
    if(BeeperActive == 1)
80
    {
81
      if(--BeeperTime == 0)
82
      {
83
        beeperOff();
84
        --NumberOfBeeps;
85
      }
86
    } else {
87
      if(--BeeperTime == 0)
88
      {
89
        beeperOn();
90
      }
91
    }
92
  }
93
}

von Krapao (Gast)


Lesenswert?

Ersetze beeper_off() noch durch beeperOff()

von spaxx (Gast)


Lesenswert?

Ja wunderbar, funktioniert wie gewollt..
Ich erkenne nur nicht genau die Ursache des nun gelösten Problems.
Trotzdem danke :-)

von spaxx (Gast)


Lesenswert?

Ahh, es lag an dem TIMER1_COMPA_vect, da habe ich den COMPB_vect 
verwendet..

Kann ich den COMPB_vect beibehalten, indem ich Channel B toggle?

Statt "TCCR3A = (1 << COM3A0);" einfach "TCCR3A = (1 << COM3B0);" ???

Das mit den Channels ist mir nicht ganz klar, steht auch nichts unter 
AVR - Interrupts.. Aber ich denke das war das Problem.

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.