Forum: Mikrocontroller und Digitale Elektronik Atmega 328 / TWI-Problem / TWCR


von Matze (Gast)


Lesenswert?

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?

von Matze (Gast)


Lesenswert?

Versuche es nun mit der Lib von:
http://homepage.hispeed.ch/peterfleury/avr-software.html

Habe da aber ein noch seltsameres Problem,
undefined refference to i2c_init

Habe keine Ahnung warum der Compiler (Atmel-Studio 6) USART_transmit 
kennt,
i2c_init jedoch nicht.

Die C-Datei, sowie die Header-Datei sind im Projekt eingebunden, wenn 
i2c eingegeben wird kann auch schon selbstständig auf i2c_init erweitert 
werden. i2cmaster.h liegt im sleben verezichniss wie Send_VFD.h welches 
USART_transmit enthält.

Der Fehler muss ganz grundsätzlich sein, ich find ihn jedoch nicht, sehe 
keinen unterschied zwischen der einbindung von USART_transmit und 
i2c_init.

Hier der Code:
1
#define F_CPU 16000000UL
2
#include <util/delay.h>
3
#include <avr/io.h>
4
#include "Send_VFD.h"
5
#include "i2cmaster.h"
6
//#include "Clock.h"
7
8
int main(void)
9
{
10
  i2c_init();
11
12
  char oben[21] ="     geht!          ";
13
  char unten[21]="Hallo Welt          ";
14
  uint8_t dispcount=0;
15
  DDRB |=  (1<<PB5); //PB1 auf 1 -> als Ausgang
16
  uint8_t a=1;
17
  uint8_t b=0;
18
  USART_Init();
19
  USART_Transmit(0x0a);
20
  USART_Transmit(0x0d);
21
  USART_Transmit(0x04);
22
  Init(0,50,11,23,5,2015);
23
    while(1)
24
    {
25
    i2c_start_wait(0x90+I2C_WRITE);
26
    int test=0;
27
    b=test;
28
    oben[0]=b/100+0x30;
29
    b=b%100;
30
    oben[1]=b/10+0x30;
31
    b=b%10;
32
    oben[2]=b+0x30;
33
    dispcount=0;
34
    while (dispcount <= sizeof(oben)-2)
35
    {
36
      USART_Transmit(oben[dispcount]);
37
      dispcount++;
38
    }
39
    //_delay_ms(1);
40
    }
41
}

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
Noch kein Account? Hier anmelden.