Forum: Mikrocontroller und Digitale Elektronik I2C und ACK Byte


von Christoph H. (christoph_b)


Angehängte Dateien:

Lesenswert?

So nachdem ich endlich den Atmega 8 flashen kann ergibt sich schon das 
nächste kleine Problem.

Ich wollte einen I2C Verbindung zwischen einem Atmega8 und einem Atmega 
2560 aufbauen.

Ich habe mich an den Quellcode von engineersgarage.com gehalten.

Master
1
// Program for Master Mode
2
// Check Code2 for Slave Mode Program
3
#include<avr/io.h>
4
#include<util/delay.h>
5
#include<inttypes.h>
6
 
7
void TWI_start(void);
8
void TWI_repeated_start(void);
9
void TWI_init_master(void);
10
void TWI_write_address(unsigned char);
11
void TWI_read_address(unsigned char);
12
void TWI_write_data(unsigned char);
13
void TWI_read_data(void);
14
void TWI_stop(void);
15
 
16
unsigned char address=0x20, read=1, write=1;
17
unsigned char write_data=0x01, recv_data;
18
 
19
int main(void)
20
{
21
_delay_ms(2000);
22
DDRB=0xff;
23
TWI_init_master(); // Function to initialize TWI
24
while(1)
25
{
26
if(write_data==0x00)
27
write_data=1;
28
TWI_start(); // Function to send start condition
29
TWI_write_address(address+write); // Function to write address and data direction bit(write) on SDA
30
TWI_write_data(write_data);     // Function to write data in slave
31
TWI_stop(); // Function to send stop condition
32
 
33
 
34
_delay_ms(10); // Delay of 10 mili second
35
 
36
TWI_start();
37
TWI_read_address(address+read); // Function to write address and data direction bit(read) on SDA
38
TWI_read_data(); // Function to read data from slave
39
TWI_stop();
40
_delay_ms(1000);
41
write_data = write_data * 2;
42
}
43
 
44
 
45
}
46
 
47
void TWI_init_master(void) // Function to initialize master
48
{
49
TWBR=0x01; // Bit rate
50
TWSR=(0<<TWPS1)|(0<<TWPS0); // Setting prescalar bits
51
// SCL freq= F_CPU/(16+2(TWBR).4^TWPS)
52
}
53
 
54
void TWI_start(void)
55
{
56
// Clear TWI interrupt flag, Put start condition on SDA, Enable TWI
57
TWCR= (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
58
while(!(TWCR & (1<<TWINT))); // Wait till start condition is transmitted
59
while((TWSR & 0xF8)!= 0x08); // Check for the acknowledgement
60
}
61
 
62
void TWI_repeated_start(void)
63
{
64
// Clear TWI interrupt flag, Put start condition on SDA, Enable TWI
65
TWCR= (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
66
while(!(TWCR & (1<<TWINT))); // wait till restart condition is transmitted
67
while((TWSR & 0xF8)!= 0x10); // Check for the acknoledgement
68
}
69
 
70
void TWI_write_address(unsigned char data)
71
{
72
TWDR=data; // Address and write instruction
73
TWCR=(1<<TWINT)|(1<<TWEN);    // Clear TWI interrupt flag,Enable TWI
74
while (!(TWCR & (1<<TWINT))); // Wait till complete TWDR byte transmitted
75
while((TWSR & 0xF8)!= 0x18);  // Check for the acknoledgement
76
}
77
 
78
void TWI_read_address(unsigned char data)
79
{
80
TWDR=data; // Address and read instruction
81
TWCR=(1<<TWINT)|(1<<TWEN);    // Clear TWI interrupt flag,Enable TWI
82
while (!(TWCR & (1<<TWINT))); // Wait till complete TWDR byte received
83
while((TWSR & 0xF8)!= 0x40);  // Check for the acknoledgement
84
}
85
 
86
void TWI_write_data(unsigned char data)
87
{
88
TWDR=data; // put data in TWDR
89
TWCR=(1<<TWINT)|(1<<TWEN);    // Clear TWI interrupt flag,Enable TWI
90
while (!(TWCR & (1<<TWINT))); // Wait till complete TWDR byte transmitted
91
while((TWSR & 0xF8) != 0x28); // Check for the acknoledgement
92
}
93
 
94
void TWI_read_data(void)
95
{
96
TWCR=(1<<TWINT)|(1<<TWEN);    // Clear TWI interrupt flag,Enable TWI
97
while (!(TWCR & (1<<TWINT))); // Wait till complete TWDR byte transmitted
98
while((TWSR & 0xF8) != 0x58); // Check for the acknoledgement
99
recv_data=TWDR;
100
PORTB=recv_data;
101
}
102
  
103
void TWI_stop(void)
104
{
105
// Clear TWI interrupt flag, Put stop condition on SDA, Enable TWI
106
TWCR= (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
107
while(!(TWCR & (1<<TWSTO)));  // Wait till stop condition is transmitted
108
}

Leider bekomme ich nur folgendes auf dem Logic Analyser zu sehen. Einmal 
wenn beide Controller am Bus hängen A-ACK. Wenn nur der Master am Bus 
hängt A-NACK.


Der Atmega läuft mit dem Internen Quarz auf 8Mhz. Der 2560 läuft mit 
16Mhz.

Besten Dank
von Klaus2m5 (Gast)


Lesenswert?

unsigned char address=0x20, read=1, write=1;
                                          !
write muss 0 sein, denn Du sendest hier sonst eine read-Adresse
                            !
TWI_write_address(address+write); // Function to write address and data 
direction bit(write) on SDA
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.