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.