Forum: Mikrocontroller und Digitale Elektronik ATTiny2313 I2C - Master (Peter Fleury) / Slave (jtronics)


von Anthony S. (anthony_02)


Lesenswert?

Hallo,

hab Versuch mit dem Tutorial von jtronics.de eine Verbundung zwischen 
Zwei ATTiny2313 (Master und Slave) zum laufen zu bekommen.

http://www.jtronics.de/avr-projekte/library-i2c-twi-slave-usi.html

Wollte nun mit dem Programm Ein Zeichen welches ich dem Master via UART 
mitteile an den Slave senden und dann wieder auslesen und wieder via 
UART ausgeben.
Das funktioniert leider nicht. Wenn ich ein Zeichen übermittel, kommt 
nichts zurück, und ein zweites Zeichen kann er garnicht mehr einlesen, 
weil er davor scheinbar irgendwo hängen bleibt.

Im folgenden sind meine beiden Main.c Programm vom Master und Slave. Hat 
vieleicht jemand eine Idee was ich da falsch gemacht habe?

Gruß
Philipp

Master Module: (Verwendung der Peter Fleury Libary)
-Main.c Sieht Wiefolgt aus:
1
#include <avr/io.h>
2
#include "i2cmaster.h"
3
#include <util/delay.h>
4
5
//############# I2C/TWI Adressen
6
#define Adr_AttinyI 0b00110100 
7
8
9
//############# Macro 2x 8Bit --> 16Bit
10
#define uniq(LOW,HEIGHT)   ((HEIGHT << 8)|LOW)
11
//############# Macro 16Bit --> 2x 8Bit
12
#define LOW_BYTE(LONG)     (LONG & 0xff)
13
#define HIGH_BYTE(LONG)    ((LONG >> 8) & 0xff)
14
15
//############# Functions
16
uint8_t read_Attiny0(void);
17
void read_Attiny1(void);
18
void write_slave(uint8_t);
19
uint8_t Byte0, Byte1, Byte2, Byte3 = 0;  // Bytes
20
uint8_t hig,low = 0; // hight und Low Variable
21
uint16_t word1,word2 =0;
22
23
//############# Variabels
24
void InitUART (uint8_t baudrate);
25
void TransmitByte (uint8_t data);
26
uint8_t ReceiveByte (void);
27
28
29
//############# Main
30
int main(void)
31
{
32
  InitUART (12);
33
  while (1)
34
  {
35
    write_slave(ReceiveByte());
36
    _delay_ms(1000);
37
    TransmitByte (read_Attiny0());
38
    _delay_ms(1000);
39
    read_Attiny1();
40
    _delay_ms(1000);
41
  }
42
  
43
}
44
45
//############# Abfrage einzelner Bytes.
46
uint8_t read_Attiny0(void)
47
{
48
  i2c_start_wait(Adr_AttinyI + I2C_WRITE); // Adr_AttinyI ansprechen
49
  i2c_write(0); // startadresse zum lesen
50
51
  i2c_rep_start (Adr_AttinyI + I2C_READ ); // Lesen beginnen 
52
  Byte0 = i2c_readAck(); // Byte empfangen 
53
  Byte1 = i2c_readAck(); // Byte empfangen 
54
  Byte2 = i2c_readAck(); // Byte empfangen 
55
  Byte3 = i2c_readNak(); // letes Byte empfangen 
56
57
  i2c_stop(); // stopt I2C Verbindung
58
  return Byte0;
59
}
60
61
62
//############# Abfrage einzelner Bytes (8 Bits) und anschließend zusammenfügen zu einem Word (16 Bit)
63
void read_Attiny1(void)
64
{
65
  i2c_start_wait(Adr_AttinyI + I2C_WRITE); // Adr_AttinyI ansprechen
66
  i2c_write(0); // startadresse zum lesen
67
68
  i2c_rep_start (Adr_AttinyI + I2C_READ ); // Lesen beginnen 
69
70
  low = i2c_readAck(); // Byte0 lesen
71
  hig = i2c_readAck(); // Byte1 lesen
72
  word1 = uniq(low,hig); // 2x 8Bit --> 16Bit
73
74
  low = i2c_readAck(); // Byte2 lesen
75
  hig = i2c_readAck(); // Byte3 lesen
76
  word2 = uniq(low,hig); // 2x 8Bit --> 16Bit
77
78
  i2c_stop(); // stopt I2C Verbindung
79
}  
80
81
82
//############# Senden einzelner Bytes (8 Bits) und anschließend senden von einem Word (16 Bit), durch zerlegen in 2 Bytes
83
void write_slave(uint8_t Data)
84
{
85
  i2c_start_wait(Adr_AttinyI + I2C_WRITE);
86
  i2c_write(0); // Startadresse / Register
87
88
  i2c_write(Data); // 8bit Information - adresse 0 
89
  i2c_write(0x42); // 8bit Information - adresse 1 
90
91
  i2c_write(0x43); // 8bit Information - adresse 2 
92
  i2c_write(0x44); // 8bit Information - adresse 3 
93
94
  //i2c_write(LOW_BYTE(5678)); // 16bit --> 8bit - adresse 2 
95
  //i2c_write(HIGH_BYTE(5678)); // 16bit --> 8bit - adresse 3 
96
97
  i2c_stop();                          // stopt I2C Verbindung
98
}
99
100
101
102
//############# Initialize UART
103
void InitUART (uint8_t baudrate)
104
{
105
  //Eigene Initialisierung WatchDog
106
  MCUSR =0;
107
108
  MCUCR = 0x80;    //JTAG abschalten
109
  MCUCR = 0x80;
110
111
  //Eigene Initialisierung (Outputs)
112
  DDRD |= (1<<PD5);
113
114
  //Set the baud rate
115
  UBRRL = baudrate;
116
117
  // Enable UART receiver and transmitter
118
  UCSRB = (1 << RXEN) | (1 << TXEN);
119
120
  // 8 data bits, 1 stop bit
121
  UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
122
123
   
124
}
125
126
//############# Read and write functions
127
uint8_t ReceiveByte (void)
128
{
129
  // Wait for incomming data
130
  while (!(UCSRA & (1 << RXC)));
131
132
133
  if(UDR == 0x41)
134
  {
135
    PORTD |= (1<<PD5); // Led on
136
    _delay_ms(1000);
137
    PORTD &= !(1<<PD5); // Led off
138
    _delay_ms(1000);
139
  }
140
  //Return the data
141
  return UDR;
142
}
143
void TransmitByte (uint8_t data)
144
{
145
  // Wait for empty transmit buffer
146
  while (!(UCSRA & (1 << UDRE)));
147
148
  //Start transmittion
149
  UDR = data;
150
151
    PORTD |= (1<<PD5); // Led on
152
    _delay_ms(1000);
153
    PORTD &= !(1<<PD5); // Led off
154
    _delay_ms(1000);
155
}

Slave Module: (Verwendung der usiTwiSlave.h von jtronics)
-Main.c Sieht Wiefolgt aus:
1
#include   <stdlib.h>
2
#include   <avr/io.h>
3
#include   <avr/interrupt.h>
4
#include   <avr/pgmspace.h>
5
6
//################################################################## USI-TWI-I2C
7
8
#include   "usiTwiSlave.h"         
9
10
// Note: The LSB is the I2C r/w flag and must not be used for addressing!
11
#define   SLAVE_ADDR_ATTINY       0b00110100
12
13
#ifndef   F_CPU
14
#define   F_CPU 8000000UL
15
#endif
16
17
//####################################################################### Macros
18
19
#define uniq(LOW,HEIGHT)  ((HEIGHT << 8)|LOW)        // Create 16 bit number from two bytes
20
#define LOW_BYTE(x)          (x & 0xff)              // Get low byte from 16 bit number  
21
#define HIGH_BYTE(x)         ((x >> 8) & 0xff)        // Get high byte from 16 bit number
22
23
#define sbi(ADDRESS,BIT)   ((ADDRESS) |= (1<<(BIT)))  // Set bit
24
#define cbi(ADDRESS,BIT)   ((ADDRESS) &= ~(1<<(BIT)))// Clear bit
25
#define  toggle(ADDRESS,BIT)  ((ADDRESS) ^= (1<<BIT))  // Toggle bit
26
27
#define  bis(ADDRESS,BIT)  (ADDRESS & (1<<BIT))      // Is bit set?
28
#define  bic(ADDRESS,BIT)  (!(ADDRESS & (1<<BIT)))    // Is bit clear?
29
30
//#################################################################### Variables
31
32
  uint16_t   word=0;        // Counter
33
  uint8_t    byte1, byte2;
34
  uint16_t  buffer;
35
  uint8_t    high,low = 0;  // Variables used with uniq (high and low byte)
36
37
38
//################################################################# Main routine
39
int main(void)
40
{   
41
  
42
  cli();  // Disable interrupts
43
  
44
  usiTwiSlaveInit(SLAVE_ADDR_ATTINY);  // TWI slave init
45
  
46
  sei();  // Re-enable interrupts
47
  
48
  for (int i = 0; i < 10; i++)  // Fill buffers with arbitrary data
49
    txbuffer[i] = i + 10;
50
    
51
  for (int i = 0; i < 4; i++)
52
    rxbuffer[i] = i + 20;
53
54
55
while(1)
56
    {
57
  //############################################ Read data from reception buffer
58
59
  // 8 bit variables
60
  byte1  = rxbuffer[0];
61
  byte2  = rxbuffer[1];
62
63
  // 2 8 bit variables converted into a 16 bit number
64
  low    = rxbuffer[2];
65
  high    = rxbuffer[3];
66
  word  = uniq(low,high);
67
68
  //########################################## Write data to transmission buffer
69
  
70
  // 8 bit variables
71
  txbuffer[0]= byte1;
72
  txbuffer[1]= byte2;
73
  
74
  // 16 bit variable broken up into its high and low byte
75
  buffer    = word;
76
  txbuffer[2]  = LOW_BYTE(buffer);
77
  txbuffer[3]  = HIGH_BYTE(buffer);
78
  
79
  //############################################################################
80
  
81
  } //end.while
82
} //end.main

von Daniel K. (epyx)


Lesenswert?

Würde als Erstes davon ausgehen, dass der TWIMaster von Fleury Hardware 
TWI macht und den gibt es nicht auf dem 2313.

Der Code für den Slave funktioniert bei mir eigentlich recht gut. 
Benutze den für die Ansteuerung zweier Motoren bei meinem 
RP5/RP6-Chassis.

von Anthony S. (anthony_02)


Lesenswert?

Ist I2C und TWI nicht eigendlich das gleiche?

Bei dem Tutorial auf jtronics.de ist das Beispiel für einen ATTiny2313. 
Allerdings steht da jetzt nicht expliziet, das auch das Mastermodul (Wo 
man die Fleury Libary verwenden soll) auch ein ATTiny2313 sein kann.

Gibt es denn kein Beispiel, oder Libary, mit dem man bei einem ATTiny 
ein Master über USI einrichten kann?

von Daniel K. (epyx)


Lesenswert?

Man kann den Attiny als Master betreiben, wenn man den ASM-Code der Lib 
nutzt. Der C-Code ist jedoch nur für Devices mit Hardware-TWI.

TWI und I2C ist das Gleiche. I2C ist nur von Phillips/NXP namens 
rechtlich geschützt.

Kannst gucken, ob Atmel für die AppNote [1] Beispielcode hat.

[1] AVR310: Using the USI module as a I2C master

von Anthony S. (anthony_02)


Lesenswert?

Hab mir jetzt die PDF zu "AVR310: Using the USI module as a I2C master" 
angeschaut.
Da steht dann ja weiter unten, (Seite 4) dass man den Treiber einfach 
einbinden kann und das man den code dann als beispiel verwenden kann 
oder ändern.

Wo bekomme ich diesen Treiber denn her???

Gruß
Philipp

von Martin J. (bluematrix) Benutzerseite


Angehängte Dateien:

Lesenswert?

Im anhang findest du ein beispiel für einen twi master.
die Fleury Lib ist eine Master Lib für ein normales TWI interface.
die jtronics Lib ist, wie es auch da steht eine Lib für ein USI 
Interface und implementiert damit einen I2C Slave.

Um Mit USI einen I2C master zu erzeugen benötigst du also anderen code 
oder schreibst diesen um.

im anhang findest du dazu ein Bsp von atmel.

grüße martin

von Martin J. (bluematrix) Benutzerseite


Angehängte Dateien:

Lesenswert?

oder diese Hilfe

von Anthony S. (anthony_02)


Lesenswert?

Hab jetzt versucht AVR310 meinem ATTiny anzupassen.

Aber gleich am Anfang habe ich schon das Problem, das er die includes 
ioavr.h and inavr.h nicht finden kann.

Habe die dann durch avr/io.h erstetzt.
Dann habe ich aber folgende Fehler meldung zur folgenden Zeile Bekommen:

1
__x unsigned char USI_TWI_Start_Transceiver_With_Data( unsigned char * , unsigned char );
1
../USI_TWI_Master.h:116:5: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'unsigned'


Hat da Jemand eine Idee wie ich die weg bekomme?

Gruß
Philipp

von holger (Gast)


Lesenswert?

__x unsigned char USI_TWI_Start_Transceiver_With_Data(

>Hat da Jemand eine Idee wie ich die weg bekomme?

Das __x wegmachen.

von Anthony S. (anthony_02)


Lesenswert?

Hat ich auch schon versucht. Leider bleibt die fehler meldung bestehen.

Weitere Ideen?

von Anthony S. (anthony_02)


Lesenswert?

Hab den Fehler jetzt weg bekommen, indem ich die .c und .h Datei neu 
erstellt habe und den Code dann reinkopiert.

Hatten dann noch paar andere Fehlermeldungen die ich wiefolgt 
ausgebessert habe:
Das linke habe ich durch die Ausdrücke rechts ausgetaut:

1
__no_operation(); /*-->>*/ _delay_ms(1);
1
__enable_interrupt(); /*-->>*/ sei();
 ausgetauscht.
1
__delay_cycles( T4_TWI ); /*-->>*/ if (T4_TWI%2){ _delay_loop_1(T4_TWI/3);}
2
                                   else {_delay_loop_2(T4_TWI/4);}

Hab jetzt keine Fehlermeldung mehr aber die Kommunikation funktioniert 
immer noch nicht.

Ich habe die vermutung das das Programm beim Warten auf den ACK-Bit 
hängen bleibt.

In dem Slave Programm musste ich die CPU_Frequenz meinem µC anpassen, 
muss ich das bei dem Master auch irgendwo angeben?

Muss ich da eventuell in der Zeile:
1
#define SYS_CLK   4000.0  // [kHz]

die 4000.0 durch 20000000 austauschen?

Würde mich über jegliche Lösungsvorschläge freuen.

Gruß
Philipp

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.