Hallo!
Also, ich habe da ein Problem.
Ich habe ein Beschlunigungssensor Modul von ELV mit einem BMA020 an einen atmega 32 angeschlossen.
Über den I²C bus.
Das Teil hat schon 10K pullup widerstände drauf.
Sonst habe ich keine pull ups.
Das Teil sendet aber kein Acknowledgment, also SDA wird am Ende nicht low.
Könnt ihr euch das mal ansehen?
Mein gut komemntierter code
Code:
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 1000000UL
#define BAUD 1200UL // Baudrate
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // clever runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
#error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
#endif
#include <util/delay.h>
int zahl = 0;
void uart_init(void)
{
UBRRH = UBRR_VAL >> 8;
UBRRL = UBRR_VAL & 0xFF;
UCSRB |= (1<<TXEN) | (1<<RXEN); // UART TX und RX einschalten
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // Asynchron 8N1
}
void uart_write (char eingabe[40]) //funktion um strings auszugeben
{
while (eingabe [zahl] != 0)
{
while (!(UCSRA & (1<<UDRE))) /* warten bis Senden moeglich */
{
}
UDR = eingabe[zahl];
zahl ++;
}
zahl = 0;
}
uint8_t uart_getc(void)
{
while (!(UCSRA & (1<<RXC))) // warten bis Zeichen verfuegbar
;
return UDR; // Zeichen aus UDR an Aufrufer zurueckgeben
}
int main (void)
{
uart_init ();
DDRC &= ~(1<<PC1);
if (PINC & (1<<PINC1))
{uart_write("High");}
DDRC = 0xFF;
PORTC &= ~(1 <<PC0) | (1<<PC1); //SCL und SDA auf LOW
DDRC &= ~(1<<PC0) | (1<<PC1); //SCL und SCA als Eingang also high
DDRC = (1 <<PC1); //SDA low (starbedingung2) [ecvnetuell pause davor]
//01110000
DDRC = (1 <<PC0); //SCL low
DDRC &= ~(1<<PC0); //SCl high 1.bit
DDRC &= ~(1 <<PC1); //SDA high
DDRC = (1 <<PC0); //SCL low
DDRC &= ~(1<<PC0); //SCl high 2.bit
DDRC = (1 <<PC0); //SCL low
DDRC &= ~(1<<PC0);//SCl high 3.bit
DDRC = (1 <<PC0); //SCL low
DDRC &= ~(1<<PC0);//SCl high 4.bit
DDRC =(1 <<PC1); //SDA low
DDRC = (1 <<PC0); //SCL low
DDRC &= ~(1<<PC0); //SCl high 5.bit
DDRC = (1 <<PC0); //SCL low
DDRC &= ~(1<<PC0); //SCl high 6.bit
DDRC = (1 <<PC0); //SCL low
DDRC &= ~(1<<PC0); //SCl hogh 7.bit
DDRC = (1 <<PC0); //SCL low
DDRC &= ~(1<<PC0); //SCl high 8.bit
DDRC &= ~(1<<PC1);
if (!(PINC & (1<<PINC1)))
{ uart_write ("low");}
else
{ uart_write ("high2");}
while(1)
{
}
}
Ich ahbe den gnazen Code gepostet, weil der fehler ja überalls ein könnte.
Aber der wichtige Teil sit unten.
Zuerst kommt die Startbedingung, dann wird die Adresse übertragen und dann wird das ACK geprüft.
Aber das ist bei mir immer High.
Wenn ich die pullups wegmache, dann ist es low, nur so als Test.
Für Antworten wäre ich sehr Dankbar.
Gruß
Olaf
Lesezeichen