Hallo, ich habe mit dem XPLAIN Board(XMEGA128A1) einen i²C CO2 Sensor angesprochen. Funktioniert alles soweit ganz gut, jedoch habe ich das Problem, dass nach ein paar korrekten Messwerten entweder eine 0 oder eine 10794 übertragen wird, mir schein es fast so, als würde ein Puffer überlaufen/leerlaufen...... Da ich recht neu in der uC Welt bin, ist mein Code auch entsprechend einfach geschrieben.....in der main.c habe ich die Funktionen mit einem Delay versehen, um dem Sensor zeit zum Verarbeiten zu eben, da liegt wahrsch das Problem...jetzt suche eine Funktion, mit der mein uC erkennt, dass der Controller bereit für das nächste "Gespräch" ist, normalerweise ist das ja nach dem Slave ACK der Fall.....vllt kann mir ja der eine oder andere helfen. Hier meine main.c: int main(void) { PORTC.PIN0CTRL = 0x18; //Pull Up SDA PORTC.PIN1CTRL = 0x18; //Pull Up CLK int i=0; int Status = 0; int temperature=0; unsigned int humi=0; char status = 0; char lowbyte = 0; char highbyte = 0; char check = 0; int co2_raw = 0; TWI_MasterInit(&TWIC); //UART initialisieren USARTC0.BAUDCTRLB = 0; USARTC0.BAUDCTRLA = 0x0C; USARTC0.CTRLA = USART_RXCINTLVL_HI_gc; USARTC0.CTRLB = USART_TXEN_bm | USART_RXEN_bm; USARTC0.CTRLC = USART_CHSIZE_8BIT_gc; PORTC.DIR = 0x08; while(1) { // SHT 75 Auslesen!!! sht_init(); sht_start(); _delay_ms(30); sht_write_byte(MEAS_TEMP); sht_wait_for_measurement(); temperature = sht_read_byte(1)<<8; temperature |= sht_read_byte(0); _delay_ms(5); sht_start(); _delay_ms(30); sht_write_byte(MEAS_HUMI); sht_wait_for_measurement(); humi = sht_read_byte(1)<<8; humi |= sht_read_byte(0); float temp = sht_calc_temp(temperature); float feuchte = sht_calc_humi(humi); K22_send_byte(&TWIC,K22); _delay_ms(20); K22_read_Adress(&TWIC,K22); _delay_us(500); status = K22_read_Data(&TWIC); TWIC.MASTER.CTRLC = TWI_MASTER_CMD_RECVTRANS_gc; _delay_us(500); lowbyte = K22_read_Data(&TWIC); TWIC.MASTER.CTRLC = TWI_MASTER_CMD_RECVTRANS_gc; _delay_us(500); highbyte = K22_read_Data(&TWIC); TWIC.MASTER.CTRLC = TWI_MASTER_CMD_RECVTRANS_gc; _delay_us(500); check = K22_read_Data(&TWIC); _delay_us(500); TWIC.MASTER.CTRLC = TWI_MASTER_CMD_RECVTRANS_gc; co2_raw = lowbyte<<8; co2_raw |= highbyte; char Buffer[20]; utoa( temp, Buffer, 10 ); char Buffer2[20]; utoa( feuchte, Buffer2, 10 ); char Buffer3[20]; utoa( co2_raw, Buffer3, 10 ); //Daten über UART an BT-Modul senden Send_UART("Temp: "); Send_UART(Buffer); Send_UART("Humi: "); Send_UART(Buffer2); Send_UART("CO2: "); Send_UART(Buffer3); if(co2_raw > 2000){ Send_UART("Achtung! CO2 Konzentration zu hoch!!!"); } _delay_ms(1330); } } hier die TWI.c: #include <avr/io.h> #include "util/delay.h" #include "TWI.h" //Funktionen void TWI_MasterInit(TWI_t *twi){ twi->MASTER.BAUD = TWI_BAUDRATE; twi->MASTER.CTRLA = TWI_MASTER_ENABLE_bm | TWI_MASTER_INTLVL_HI_gc | TWI_MASTER_RIEN_bm | TWI_MASTER_WIEN_bm; twi->MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc; } void Send_Address(TWI_t *twi, char Adresse, char RW) { twi->MASTER.ADDR = (Adresse << 1)+RW; //twi->MASTER.ADDR = Adresse; } void K22_send_byte(TWI_t *twi, char Adresse) { int i = 0; Send_Address(twi, Adresse, 0); _delay_us(500); twi->MASTER.DATA = 0x22; _delay_us(500); twi->MASTER.DATA = 0x00; _delay_us(500); twi->MASTER.DATA = 0x08; _delay_us(500); twi->MASTER.DATA = 0x2A; _delay_us(500); twi->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc; } char K22_read_Adress(TWI_t *twi, char *Adresse) { Send_Address(twi, Adresse, 1); _delay_us(500); //twi->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc; } char K22_read_Data(TWI_t *twi) { return twi->MASTER.DATA; _delay_us(500); } Gruß Johannes
Schau mal in AVR1308, da ist ein einfach in Betrieb zu nehmenden Beispiel für das TWI-Modul, das man leicht an eigene Slaves anpassen kann. So wie Du das gemacht hast, geht es nicht.
Das AVR1308 hab ich schon mehrfach durch....da steht zwar alles prima erklärt, das hilft mir jedoch nicht wirklich weiter, meinen C-Code zu verbessern...wie gesagt der sensor antwortet, nur nach 15-25 Messwerten kommt aufeinmal müll raus.....bitte nicht vom C-Code für den SHT75 Sensor verwirren lassen, das ist kein richtiger i2c da haben wir die Kommunikation per Hand durchgeführt laut datenblatt.....funktioniert aber auch 1A...
Dass Dein Code ein bisschen funktioniert, ist sicher nur Zufall, du aktivierst z.B. die TWI-Interrupts (CTRLA-Register), hast aber keine Handler dafür. Das Atmel-Beispiel zeigt Dir, wie das gemacht werden muss.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.