Hallo,
ich habe meine I²C Routinen von einem ATMega168 auf einen
ATMega324P portiert.
Auf dem ATMega168 laufen diese prächtig.
Das einzige, was ich ändern mußte, war
SIGNAL (SIG_2WIRE_SERIAL) zu ISR (TWI_vect), sowie ein paar zusätzliche
define für neue Register von RS232 u.ä.
Nur ich bekomme jetzt keinen Interrupt mehr ausgelöst.
Codeauszug:
1 | void i2c_init ( unsigned int bitrate)
|
2 | {
|
3 | // Bitrate berechnen
|
4 | unsigned int faktor = 1;
|
5 | unsigned int temp = 0;
|
6 |
|
7 | do
|
8 | {
|
9 | temp = ((F_CPU / bitrate) - 16) / (2 * faktor);
|
10 | faktor = faktor * 4;
|
11 | }
|
12 | while ( temp > 255);
|
13 |
|
14 | TWBR = temp;
|
15 | // je nach Faktor Vorteiler konfigurieren
|
16 | faktor = faktor / 4;
|
17 | if (faktor == 1) TWSR |= (0 << TWPS0) | (0 << TWPS1);
|
18 | if (faktor == 4) TWSR |= (1 << TWPS0) | (0 << TWPS1);
|
19 | if (faktor == 16) TWSR |= (0 << TWPS0) | (1 << TWPS1);
|
20 | if (faktor == 64) TWSR |= (1 << TWPS0) | (1 << TWPS1);
|
21 | rs232_transmit (0xFF,0); *
|
22 | rs232_transmit (TWSR,0); *
|
23 | rs232_transmit (TWBR,0); *
|
24 | }
|
25 |
|
26 | void i2c_start (void)
|
27 |
|
28 | {
|
29 | // Interruptroutine freigeben
|
30 | // erster auszuführender Schritt = 1
|
31 | sei (); *
|
32 | i2c_stepnumber = 1;
|
33 | i2c_actuell = 0;
|
34 | TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN) | (1 << TWIE);
|
35 | _delay_ms (200); *
|
36 | rs232_transmit (0xEE,0); *
|
37 | rs232_transmit (TWCR,0); *
|
38 | rs232_transmit (TWSR,0); *
|
39 | }
|
40 |
|
41 |
|
42 |
|
43 | // Interruptroutine der I²C Schnittstelle
|
44 | // wird von einer externen Funktion gestartet
|
45 | ISR (TWI_vect)
|
46 |
|
47 | {
|
48 | merker = 1; *
|
49 | rs232_transmit ('O',0); *
|
50 |
|
51 | // Schrittkette abarbeiten
|
52 | switch (i2c_stepnumber)
|
53 | {
|
54 | case 1: // Slaveadressen senden
|
55 | ...
|
56 | ...
|
ich habe dort einige Debugbteile drin (*), bitte nicht wundern.
Über die RS232 bekomme ich : ff f8 c0 ee a5 08
Also:
in i2c_init ();
TWSR = F8 (kein Vorteiler)
TWBR = c0
nach diesen beiden Registern ist der Clk ca. 51 kHz -> also OK.
in i2c_start ();
TWCR = a5; TWINT,TWSTA,TWEN,TWIE sind auf 1
TWBR = 08; Master Mode -> Start wurde gesendet
Da der Start gesendet wurde, müßte jetzt ein Interrupt kommen;aber nix
Wenn der merker = 1 ist, sende ich in main eine zeichenkette über die
RS232, aber direkt in der ISR solle auch was gesendet werden, aber ich
bekomme nichts.
Auszug aus main.lst:
64: 67 c0 rjmp .+206 ; 0x134 <__bad_interrupt>
66: 00 00 nop
68: e9 c5 rjmp .+3026 ; 0xc3c <__vector_26>
6a: 00 00 nop
6c: 63 c0 rjmp .+198 ; 0x134 <__bad_interrupt>
...
...
00000c3c <__vector_26>:
// Interruptroutine der I²C Schnittstelle
// wird von einer externen Funktion gestartet
ISR (TWI_vect)
{
c3c: 1f 92 push r1
c3e: 0f 92 push r0
c40: 0f b6 in r0, 0x3f ; 63
c42: 0f 92 push r0
c44: 11 24 eor r1, r1
c46: 2f 93 push r18
c48: 3f 93 push r19
c4a: 4f 93 push r20
c4c: 5f 93 push r21
c4e: 6f 93 push r22
c50: 7f 93 push r23
c52: 8f 93 push r24
c54: 9f 93 push r25
c56: af 93 push r26
c58: bf 93 push r27
c5a: ef 93 push r30
c5c: ff 93 push r31
merker = 1;
c5e: 81 e0 ldi r24, 0x01 ; 1
c60: 80 93 26 01 sts 0x0126, r24
rs232_transmit ('O',0);
c64: 60 e0 ldi r22, 0x00 ; 0
c66: 8f e4 ldi r24, 0x4F ; 79
c68: 63 dd rcall .-1338 ; 0x730 <rs232_transmit>
c6a: 80 91 2c 02 lds r24, 0x022C
....
Der Aufruf erfolgt vor ! der main Schleife.
makefile : MCU = atmega324p
Ich sehe irgenwie den Fehler nicht.
Habt Ihr mal eine Idee ??
Jogibär