Moin.

Hab mal wieder ein kleines Problem.
Ich bin gerade dabei, einen SRF05 auszulesen.

Vom Prinzip her send ich einfach den 10µs-Trigger und mess dann die Zeit des Antwort-Pulses über den Timer1.
Wird die steigende Flanke empfangen, startet der Timer mit Prescaler 8, d.h. die Dauer des Pulses entspricht dem Timerwert / 2 (bei 16MHz FCPU)
Ist der Antwortpuls beendet (fallende Flanke), wird der Timer gestoppt und das Ergebnis berechnet.
In der main lass ich mir das Ergebnis über I2C an ein LCD ausgeben, zusammen mit einer laufenden Nummer als Kontrolle, ob sich was tut.
Die Nummer läuft hoch, das Ergebnis bleibt jedoch immer 0.

Ich geh davon aus, dass gemessen wird, da die LED am SRF05 blinkt und man auch ein leises Knacken vom Ultraschallsender hört.

Die betreffenden Codes sind angehängt.

Sieht hier jemand nen Fehler?

main.c:
Code:
int main (void)
{
  _delay_ms(100);
  I2C_Init(100000ul);
  SRF05_Init();
 
  sei();
  ui16_t measures = 0;

  while(1)
  {
    sprintf(I2C_SendText, "%5d = %06ld ", measures++, SRF05_GetResponseTime());
    I2C_PutS(0x20, (ui8_t*)I2C_SendText, 20);
    _delay_ms(100);
  }
}

srf05.c:
Code:
#include "srf05.h"

typedef enum
{
  SRF_IDLE = 0,
  SRF_WAITING_FOR_ECHO,
  SRF_ECHO_ACTIVE,
  SRF_RESULT_READY,
  SRF_TIMEOUT
} e_srfstate;

volatile ui16_t SRF_ValueBuffer[400];
volatile ui16_t SRF_ValueBufferIndex = 0;

volatile ui8_t  SRF_Overflows = 0;
volatile ui16_t SRF_TCNT = 0;
volatile ui32_t SRF_TotalTimeTicks = 0;

volatile e_srfstate  SRF_State = SRF_IDLE;

void SRF05_Init(void)
{
  // Setup result pin
  SRF_RESULT_PORT  &=~ (1 << SRF_RESULT_PIN);
  SRF_RESULT_DDR   &=~ (1 << SRF_RESULT_PIN);

  // setup trigger pin
  SRF_TRIGGER_PORT &=~ (1 << SRF_TRIGGER_PIN);
  SRF_TRIGGER_DDR  |=  (1 << SRF_TRIGGER_PIN);

  // Setup result pin interrupt:
  SRF_RESULT_INT_ISC_REG |= (1 << SRF_RESULT_INT_ISC_BIT);

}

ui32_t SRF05_GetResponseTime(void)
{
  // Response signal 100µs - 25ms
  // FCPU = 16MHz
  // Prescaler 8 => 2 MHz => 0.5 µs tick duration
  
  // Prepare Timer
  TCCR1A = 0; // Standard timer; just count here
  TCCR1B = 0; // Stop timer
  TCNT1 = 0;
  SRF_Overflows = 0;
  SRF_TCNT = 0;
  SRF_TotalTimeTicks = 0;

  // clear a possible pending interrupt request
  SRF_RESULT_INT_FLAG_REG |= (1 << SRF_RESULT_INT_FLAG_BIT);

  // enable interrupt
  SRF_RESULT_INT_MSK_REG |= (1 << SRF_RESULT_INT_MSK_BIT);
  
  // enable timer overflow interrupt
  TIMSK |= (1 << TOIE1);
  
  SRF_State = SRF_WAITING_FOR_ECHO;

  // Send trigger pulse (10µs)
  SRF_TRIGGER_HIGH();
  _delay_us(10);
  SRF_TRIGGER_LOW();
  
  // wait until measurement is complete
  while((SRF_State == SRF_ECHO_ACTIVE) || (SRF_State == SRF_WAITING_FOR_ECHO))
  {
    // nothing to do; just wait...
  }

  // Calculate result  
  SRF_TotalTimeTicks  = SRF_Overflows;
  SRF_TotalTimeTicks <<= 16;
  SRF_TotalTimeTicks += SRF_TCNT;

  return SRF_TotalTimeTicks;
}


ISR(SRF_RESULT_ISR)
{
  ui8_t pinlevel = SRF_RESULT_INPUT & (1 << SRF_RESULT_PIN);
  
  if (pinlevel)
  {
    // rising edge: result pulse started
    // start timer for counting
    TCCR1B = (1 << CS11);
    SRF_State = SRF_ECHO_ACTIVE;
  }
  else
  {
    // falling edge: result pulse end
    // stop timer
    SRF_TCNT = TCNT1;
    TCCR1B = 0;
    
    // disable trigger interrupt
    SRF_RESULT_INT_MSK_REG &=~ (1 << SRF_RESULT_INT_MSK_BIT);

    // disable timer overflow interrupt
    TIMSK &=~ (1 << TOIE1);
    SRF_State = SRF_RESULT_READY;
  }
}

ISR (SIG_OVERFLOW1) // Interrupt Timer 1
{
  SRF_Overflows++;
}
srf05.h
Code:
#ifndef _SRF05_H_
#define _SRF05_H_

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "glob_defs.h"
#include "glob_type.h"

#define SRF_TRIGGER_PORT     PORTD
#define SRF_TRIGGER_DDR      DDRD
#define SRF_TRIGGER_PIN      4

#define SRF_RESULT_PORT      PORTD
#define SRF_RESULT_DDR       DDRD
#define SRF_RESULT_INPUT     PIND
#define SRF_RESULT_PIN       3

#define SRF_RESULT_INT_ISC_REG  (MCUCR)
#define SRF_RESULT_INT_ISC_BIT  (ISC11)

#define SRF_RESULT_INT_MSK_REG  (GICR)
#define SRF_RESULT_INT_MSK_BIT  (INT1)

#define SRF_RESULT_INT_FLAG_REG (GIFR)
#define SRF_RESULT_INT_FLAG_BIT (INTF1)

#define SRF_RESULT_ISR           SIG_INTERRUPT1

#define SRF_TRIGGER_HIGH()   (SRF_TRIGGER_PORT |=  (1 << SRF_TRIGGER_PIN))
#define SRF_TRIGGER_LOW()    (SRF_TRIGGER_PORT &=~ (1 << SRF_TRIGGER_PIN))

void SRF05_Init(void);
ui32_t SRF05_GetResponseTime(void);

#endif