Hi,
ich möchte mit meinem I2C Slave einen SRF05 auslesen.
Nur wird die Variable "us_time" nicht hochgezählt. Die Kommunikation mit dem Master funktioniert und wenn ich bei "return" der Funktion "readUS" z.B.
eine "45" direkt zurückgebe, kommt sie auch bei meinem Master an.
Der Sensor an sich funktioniert auch, weil die rote LED bei jedem Aufruf der Funktion leuchtet und ich das Signal mit einem Oszilloskop geprüft habe.
Mit dem jetztigen Code bekomme ich allerdings nur eine "0" zurück.
Wo ist der Fehler?Code:#include <avr/io.h> #include <util/delay.h> #include <util/twi.h> #include <avr/interrupt.h> #define LO_BYTE(a) ((uint8_t) (a & 0xFF)) #define HI_BYTE(a) ((uint8_t) ((a>>8)&0xFF)) //US-Defines #define US1 US1_PIN #define US2 US2_PIN #define US_DDR DDRD #define US_PORT PORTD #define US1_PIN PD4 #define US2_PIN PD5 #define TIMER0_AN TIMSK |= (1<<OCIE0); //Timer interrupt aktivieren #define TIMER0_AUS TIMSK &= ~(1<<OCIE0); //Timer interrupt deaktivieren #define SLAVE_ADRESSE 0x50 //Die Slave-Adresse //ACK nach empfangenen Daten senden/ ACK nach gesendeten Daten erwarten #define TWCR_ACK TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA); //NACK nach empfangenen Daten senden/ NACK nach gesendeten Daten erwarten #define TWCR_NACK TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT); //switched to the non adressed slave mode... #define TWCR_RESET TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA); //Datenstatuscodes #define DEFAULT 0 //Normaler status (keine aktion) #define READ_ENC_A 1 //Schritte vom linken Motor auslesen #define READ_ENC_B 2 //Schritte vom rechten Motor auslesen #define RESET_ENC_A 3 //Schritte vom linken Motor löschen #define RESET_ENC_B 4 //Schritte vom rechten Motor löschen #define READ_DIST_A 5 //Gefahrene Strecke auslesen (A) #define READ_DIST_B 6 //Gefahrene Strecke auslesen (B) #define RESET_DIST_A 7 //Gefahrene Strecke löschen (A) #define RESET_DIST_B 8 //Gefahrene Strecke löschen (B) #define READ_US1 9 //Ultraschall 1 Auslesen #define READ_US2 10 //Ultraschall 2 Auslesen void init_twi_slave (uint8_t adr); void initTimer0(void); uint16_t readUS(uint8_t us); volatile uint8_t status = DEFAULT; //status was der master will (z.B. US auslesen) volatile uint16_t us_time=0; int main (void){ //TWI als Slave mit Adresse slaveadr starten init_twi_slave(SLAVE_ADRESSE); initTimer0(); sei(); while(1){ } } void init_twi_slave (uint8_t adr){ cli(); TWAR = adr; // Set own TWI slave address. TWDR = 0xFF; // Default content = SDA released. TWCR = (1<<TWEN); sei(); // Start the TWI transceiver to enable reception of the first command from the TWI Master. TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA); } SIGNAL(SIG_2WIRE_SERIAL){ static uint8_t teil=0; //Welcher teil der Variable übertragen wurde static uint16_t daten=0; //entählt die daten die zum Master gesendet werden switch (TW_STATUS){ //TWI-Statusregister prüfen und nötige Aktion bestimmen case TW_ST_SLA_ACK: //SLA+R, adressiert //kein ACk/Nack/break -> sonst geht nix case TW_ST_DATA_ACK: // SLA+R received, ACK returned (Master fordert Daten an) if(status==READ_US2){ //Ultraschall 2 if(teil==0){ daten = readUS(US2); TWDR = LO_BYTE(daten); //Ersten 8 Bit übertragen TWCR_ACK; teil=1; } else{ TWDR = HI_BYTE(daten); //Zweiten 8 Bit übertragen TWCR_ACK; teil=0; status = DEFAULT; } } if(status==READ_US1){ //Ultraschall 1 if(teil==0){ daten = readUS(US1); TWDR = LO_BYTE(daten); //Ersten 8 Bit übertragen TWCR_ACK; teil=1; } else{ TWDR = HI_BYTE(daten); //Zweiten 8 Bit übertragen TWCR_ACK; teil=0; status = DEFAULT; } } break; case TW_SR_SLA_ACK: //SLA+W, adressiert TWCR_ACK; case TW_SR_DATA_ACK: //SLA+W received, ACK returned (Master sendet Daten) status = TWDR; //Geforderte aktion vom master speichern TWCR_ACK; break; default: //TWCR=0x00; TWCR_RESET; break; } } /* Ließt den Ultraschall sensor aus US1 = Ultreaschall 1 (front) US2 = Ultraschall 2 (side) */ uint16_t readUS(uint8_t us){ US_DDR |= (1<<us); //Pin auf Ausgang US_PORT |=(1<<us); //Pin high _delay_us(10); //15µs warten US_PORT &= ~(1<<us); //Pin low US_DDR &= ~(1<<us); //Pin auf Eingang while(!(PIND & (1<<us))){} //Solange der Pin low us_time = 0; TIMER0_AN; while(PIND & (1<<us)){} //Solange der Pin high TIMER0_AUS; return us_time/58; } /* Timer0 für den US Sensor konfigurieren Alle 1us einen Interrupt = Freq 1000000 (1000khz) OCR0 = 16000000/1/1000000=16 16Mhz Quarz, Prescaler 1, Frequenz */ void initTimer0(void){ TCCR0 |= (1<<WGM01) | (1<<CS00); //CTC, Prescaler 1 OCR0 = 16; } /*Interrupt für den US*/ SIGNAL(SIG_OUTPUT_COMPARE0){ us_time++; }
MfG Jörn







Zitieren

Lesezeichen