Forum: Mikrocontroller und Digitale Elektronik Port Einleseproblem in ISR und C++


von Gert Birkner (Gast)


Lesenswert?

Hallo Leute,
ich habe heute eine ISR in C++ implementiert, die alle 10µs ausgeführt 
werden soll (F_CPU = 16MHz). Die ISR funktioniert soweit ganz gut, aber 
beim Einlesen des PORTB (PINB) reagiert die if nicht, obwohl ich weiß 
(Oszi) dass das PINB1 garantiert 400µs auf 1 ist.

CodeAusschnitt:
1
void ultrasonic::isrTimer()
2
{
3
 switch(m_Status)  {
4
  case inAktive:
5
  m_Status = triggerActive;
6
  (*TriggerPort) |= (1 << TriggerPin);
7
  break;
8
 case triggerActive:
9
  m_Status = awaitingEcho;
10
  (*TriggerPort) &=  ~(1 << TriggerPin);
11
  break;
12
 case awaitingEcho:
13
  if((*EchoPort) & EchoPin)     // !!!!!!  wird nie true ??? !!!!!!!!
14
   m_Status = measureActive;
15
  m_distanceCount=1;
16
  break;
17
 case measureActive:
18
  if((*EchoPort) & EchoPin)
19
   m_distanceCount++;
20
  else {
21
   if (m_Behavior == single) {
22
    TCCR0B &= ~(1 << CS00);       // Timer stoppen
23
    TCNT0 = 0;
24
   } 
25
   (*TriggerPort) &=  ~(1 << TriggerPin);
26
   m_Status = inAktive;
27
   }
28
  break;
29
 } // switch
30
}
bis case awaitingEcho: funktioniert alles sehr gut. Der TriggerPin wird 
gesetzt, beim nächsten Durchgang gelöscht. Und dann sollte auf das Echo 
gewartet werden um die Messzählung zu starten. Aber die if wird nie 
true!

Aufgebaut mit: ATmega1284, die Adressen der Ports stimmen mit dem 
Datenblatt überein. Für das EchoPort wird PINB übergeben und EchoPin = 
1.

Hab ich hier einen Denkfehler?

: Bearbeitet durch User
von Justus S. (jussa)


Lesenswert?

Gert Birkner schrieb:
> Hab ich hier einen Denkfehler?

ja, du fragst Pin 0 ab...

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Gert Birkner schrieb:
> Hab ich hier einen Denkfehler?
 Da ich annehme, dass du die Ports entsprechend definiert hast...

Gert Birkner schrieb:
1
void ultrasonic::isrTimer()
2
{
3
 switch(m_Status)  {
4
  case inAktive:
5
  m_Status = triggerActive;
6
  (*TriggerPort) |= (1 << TriggerPin);
7
  break;
8
9
//* Hast du in diesen 10us, die TriggerPin on war, etwas sinnvoles getan ?
10
 case triggerActive:
11
  m_Status = awaitingEcho;
12
  (*TriggerPort) &=  ~(1 << TriggerPin);    //* Vielleich sollte das erst weiter unten passieren ?
13
  break;
14
15
//* Angenommen, (*EchoPort) & EchoPin) funktioniert (tut es aber nicht)...
16
 case awaitingEcho:
17
  if((*EchoPort) & EchoPin)     // !!!!!!  wird nie true ??? !!!!!!!!
18
   m_Status = measureActive;
19
  m_distanceCount=1;
20
  break;
21
22
 case measureActive:
23
  if((*EchoPort) & EchoPin)
24
   m_distanceCount++;
25
26
//* Wenn m_Behavior == single wird der Timer gestoppt, muss erst wieder gestartet werden
27
  else {
28
   if (m_Behavior == single) {
29
    TCCR0B &= ~(1 << CS00);       // Timer stoppen
30
    TCNT0 = 0;
31
   }
32
33
//* TriggerPin ist schon aus, wenn du hier angelangt bist, wozu (Fehler) ?
34
   (*TriggerPort) &=  ~(1 << TriggerPin);
35
36
//* Nur wenn m_Behavior <> single oder Timer erneut gestartet wird, macht die untere Zeile einen Sinn.
37
   m_Status = inAktive;
38
   }
39
  break;
40
 } // switch
41
}

: Bearbeitet durch User
von Daniel A. (daniel-a)


Lesenswert?

EchoPort muss volatile sein. Ist er das?

ungetestet:
1
// variante 1
2
// header
3
#define EchoPort PINx
4
// variante 2
5
// header
6
extern volatile unsigned char* EchoPort;
7
// cpp
8
volatile unsigned char* EchoPort = &PINx;
9
// variante 3
10
// header
11
static constexpr volatile unsigned char& EchoPort = PINx;
12
// variante 4
13
// header
14
struct Port {
15
  volatile unsigned char& port;
16
  volatile unsigned char& pin;
17
  operator int(){
18
    return pin;
19
  }
20
  Port operator=(int x){
21
    port=x;
22
  }
23
  Port(volatile unsigned char& port,volatile unsigned char& pin) : port(port), pin(pin) {}
24
};
25
static constexpr Port EchoPort(PORTx,PINx);
26
// unendlich viele weitere möglichkeiten...

von Gert Birkner (Gast)


Lesenswert?

Vielen Dank,
da hast du natürlich recht. es sollte natürlich
if ((*EchoPort) & (1 << EchoPin))
heißen.
... dummer Fehler ...

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.