Hallo,
Ich möchte den TWI-Bus eines Atmega328 als I2C-Master verwenden um die
Temperatur eines DS1621 Temp-Sensors auszulesen.
Dazu habe ich den Code aus dem Datenblatt genommen, Baudrate auf 100KHZ
gestellt.
1 | void I2C_Init()
|
2 | {
|
3 | //SCL=16*10^6/(16+2*twbr*prescaler)
|
4 | //Prescaler=1;
|
5 | //twbr=(16*10^6-SCL*16)/(SCL*2)
|
6 | TWBR=72; //--> 100KHZ
|
7 | TWSR=(0<<TWPS0)|(0<<TWPS1); //--> Prescaler = 1
|
8 | }
|
Sie scheint zu stimmen, jedoch möchte ich auch Daten Senden.
Dazu soll diese Funktion es ermöglichen ein Byte an eine Adresse zu
senden.
1 | uint8_t I2C_Send(uint8_t address, uint8_t data)
|
2 | {
|
3 | /* I2C */
|
4 | /*Send start condition*/
|
5 | TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
|
6 | /* warten bis Start gesendet */
|
7 | while (!(TWCR &(1<<TWINT)));
|
8 | /* Goto error if Status different from Start*/
|
9 | if ((TWSR & 0xF8) != 0x08)
|
10 | return (TWSR & 0xF8); //Fehler?
|
11 | /* Start transmission of address */
|
12 | TWDR = address;
|
13 | TWCR = (1<<TWINT) |(1<<TWEN);
|
14 | /* wait for Address has been transmitted */
|
15 | while (!(TWCR &(1<<TWINT)))
|
16 | ;
|
17 | /* Check value of Status-Register */
|
18 | if (((TWSR & 0xF8) != 0x18) || ((TWSR & 0xF8) != 0x20) || ((TWSR & 0xF8) != 0x38))
|
19 | return 2;
|
20 | /* Start transmission of data */
|
21 | TWDR = data;
|
22 | TWCR = (1<<TWINT) | (1<<TWEN);
|
23 | /* Wait for Data has been transmitted */
|
24 | while (!(TWCR &(1<<TWINT)))
|
25 | ;
|
26 | /* goto error if no ACK comes */
|
27 | if ((TWSR & 0xF8) != 0x28)
|
28 | return 3;
|
29 | /* transmitt Stop-Condition */
|
30 | TWCR =(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
|
31 | return 0x00;
|
32 | /*
|
33 | 0x01 = Status different from Start
|
34 | 0x02 = No Slave Ack
|
35 | 0x03 = No Master Ack
|
36 | */
|
37 | }
|
Es sollen verschiedene Fahlerfälle abgeprüft werden, beim 1. Fall
(Fehler?)steigt die Funktion allerdings schon mit 0x10 / 0x20 Hex aus,
immer im welchsel.
(0x08 müsste nach einer Start-Condition darin stehen.)
0x10 stände für eine Repeated Start Condition,
0x20 für "SLA+W has been transmitted; NOT ACK has been received"
Dabei werden auch Daten gesendet, was nicht sein sollte, da
1 | TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
|
eigentlich eine Start-Condition senden sollte, und die Funktion hinter
dem //Fehler? nicht mehr ausgeführt wird.
Was stimmt hier nicht?