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