Jaecko
28.03.2010, 17:50
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:
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:
#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
#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
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:
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:
#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
#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