Forum: Mikrocontroller und Digitale Elektronik Ultraschallmodul SRF05 und Atmega32


von Sadik I. (sadiq)


Lesenswert?

Hallo Leute

Ich habe in diesem Forum zum Thema schon hilfreiches finden können, aber 
jetzt weiß ich nicht mehr weiter.

Ich versuche den SRF05 im "ein-pin-mode" auf einem atmega32 zum laufen 
zu kriegen. Das ging auch ganz gut, als ich noch keine interrupts 
verwendet habe. Jetzt versuche ich es mit Interrupts und es klappt nicht 
mehr.

Der Code ist historisch gewachsen, nicht alles davon soll letzendlich so 
bleiben. Man sieht wohl auch, dass ich sowas zum ersten mal mache.

1
// ultrasound.c
2
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
#include "ultrasound.h"
6
7
static volatile Ultrasound* activeUltrasound;
8
static volatile uint32_t begin;
9
volatile unsigned int microseconds = 0;
10
volatile uint8_t INT0_interrupt = 0;
11
volatile uint8_t measurement_complete = 0;
12
13
struct _ultrasound {
14
  /* for example PA4 */
15
  uint8_t PAX;
16
  /* for example PORTA */
17
  volatile uint8_t * PORTX;
18
  /* for example DDRA */
19
  volatile uint8_t * DDRX;
20
  /* for example PINA */
21
  volatile uint8_t * PINX;
22
  volatile uint16_t ustime;
23
};
24
25
26
uint8_t Ultrasound_get_distance(Ultrasound* u) {
27
  uint16_t dist = 0;
28
  dist = 0;
29
  microseconds = 0;
30
  TCNT0 = 0;
31
  
32
    *u->PORTX &= ~_BV(u->PAX); //low
33
  *u->DDRX |= _BV(u->PAX);//pin as output
34
35
  //Ausgang auf HIGH
36
  *u->PORTX |= _BV(u->PAX);
37
  _delay_us(12);
38
  //Set the ultrasound as active
39
  activeUltrasound = u;
40
41
  *u->PORTX &= ~_BV(u->PAX); //low again
42
  *(u->DDRX) &= ~(1 << u->PAX); //pin as input
43
  
44
  
45
  
46
  
47
  MCUCR = (1<<ISC01) | (1<<ISC00); //trigger on rising edge
48
49
  sei();
50
  while(measurement_complete != 1){
51
  }
52
  cli();
53
  
54
  measurement_complete = 0; // reset 
55
  
56
  dist = microseconds / 58;
57
  
58
  return dist;
59
}
60
61
/**
62
 * Erstellt den struct Ultrasound u
63
 */
64
Ultrasound * Ultrasound_create(uint8_t pax, volatile uint8_t* portx,
65
    volatile uint8_t* ddrx, volatile uint8_t *pinx) {
66
  
67
  *ddrx |= (1<<pax);
68
  Ultrasound *u;
69
  u = malloc(sizeof(Ultrasound));
70
  u->PORTX = portx;
71
  u->DDRX = ddrx;
72
  u->PAX = pax;
73
  u->PINX = pinx;
74
  u->ustime = 0;
75
  //Set the pin INTx to be an interrupt
76
  //MCUCR |= _BV(ISC00);
77
  //GIMSK |= _BV(INT0);
78
  //sei();
79
  TCCR0 = (1<<WGM01);
80
  // ((16000000 / 8 ) / 100000) -1 = 19
81
  OCR0 = 19;
82
  TIMSK |= (1<<OCIE0);
83
  GICR |= (1<<INT0);
84
  return u;
85
}
86
87
ISR(INT0_vect) {
88
  
89
  if(INT0_interrupt == 0){ //first rising edge
90
    TCCR0 |= (1<<CS01);
91
    PORTA |= (1<<PA4);
92
    MCUCR = (1<<ISC01); //set int0 to trigger in falling edge 
93
    INT0_interrupt = 1;
94
  }else{
95
    TCCR0 &= ~(1<<CS01);
96
    INT0_interrupt = 0;
97
    measurement_complete = 1;
98
    PORTA &= ~(1<<PA4);
99
  }
100
}
101
102
ISR(TIMER0_COMP_vect){
103
  microseconds += 10;
104
}

Der bleibt in der measurement_complete-Schleife recht lange hängen. 
Interessanterweise bleibt er da unterschiedlich lange hängen. 
Entschprechend kriege ich ständig unterschiedliche Distanzwerte.

In der main steht dann sowas drinne:
1
...
2
u1 = Ultrasound_create(PD2, &PORTD, &DDRD, &PIND);
3
dist1 = Ultrasound_get_distance(u1);
4
...


Ich kriege, wenn ich lange genug warte, Abstände von 3 bis 250 zurück, 
obwohl sich vor dem SRF05 nichts bewegt.

Weiß einer, was falsch ist (vllt nicht gleich alles)?

Gruß
Sadik

von Sadik I. (sadiq)


Lesenswert?

Ok, jetzt funktioniert es.
Ich habe nur eine Zeile am Code geändert

aus
1
*(u->DDRX) &= ~(1 << u->PAX); //pin as input
wurde
1
*u->DDRX &= ~_BV(u->PAX);

wichtiger ist: ich hatte den pin gar nicht korrekt mit dem INT pin vom 
atmega32 verbunden. naja, vielleicht hilft der Code irgendjemandem.

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.