Atmega8 + Atmega644p über TWI Problem

OP #2561645
Lesenswert?

Moin,

ich möchte einen Mega8 und einen Mega644p über I2C kommunizieren lassen, 
bzw. den Mega644p (als Master) nur vom Mega8 lesen lassen. SCL + SDA ist 
richtig verbunden, und da beide über eine Spannungsversorgung laufen, 
ist Masse auch verbunden.

Auf dem Mega644p läuft die Master Lib von Peter Fleury.
Auf dem Mega8 läuft die Slave Lib von hier:
Beitrag "AVR TWI Master und Slave Funtionen in C"

Als Test requestet der Mega644p 3 Bytes vom Mega8. Wenn ich beide 
gleichzeitig neu starte, gibt der 644p die 3 Bytes auch über USART aus. 
Nach einem Delay von 500ms, startet der 644p die Verbindung wieder aber 
kann nichts mehr empfangen und der Watchdog startet nach 2sek den 
Mega644p neu.
Das ist das erste Problem, dass er nur einmal empfangen kann, und danach 
nicht mehr.

Ein anderes Problem ist, dass nach dem WDT Reset, der WDT irgentwo 
hängenbleibt, denn den TWI Bus öffnet er nicht mehr, startet aber nach 2 
Sek trotzdem neu, obwohl in der while Schleife nur das delay von 500ms 
ist.

Hier sind die codes:
Atmega8 (16Mhz):
1
#define F_CPU 16000000UL
2
#define OWN_ADRESS 0x8A
3

4
#include <avr/io.h>
5
#include <util/delay.h>
6
#include <avr/interrupt.h>
7
#include "PPM.h"
8
#include "TWI_Slave.h"
9

10
void delay_ms(unsigned long t)
11
{
12
  for(unsigned long i=0;i<t;i++)
13
  {
14
    _delay_ms(1);
15
  }
16
}
17

18
int main(void)
19
{
20
  delay_ms(50);
21
  DDRD |= (1<<DDD2);
22
  delay = 1000;
23
  
24
  ppm_Init();
25
  TWIS_Init(OWN_ADRESS,400000);  //Hier wird auch das TWIE Bit gesetzt für                 //das Interrupt
26
  
27
  sei();
28
  
29
  
30
  while (1)
31
    {
32

33
    
34

35
    }
36
  return 0;   
37
}
38

39
ISR(TWI_vect)
40
{
41
  uint8_t TWIS_ResonseType;
42
  if (TWIS_ResonseRequired (&TWIS_ResonseType))
43
  {
44
    switch (TWIS_ResonseType)
45
    {
46
      case TWIS_ReadBytes:
47
        TWIS_Stop ();
48
        break;
49
      case TWIS_WriteBytes:
50
        TWIS_Write('H');
51
        TWIS_Write('A');
52
        TWIS_Write('L');
53
        TWIS_Stop ();
54
        break;
55
    }
56
  }  
57
}

Atmega644p(18.432Mhz)
1
#include "define.h"
2
#include "types.h"
3
#include "global.h"
4

5
#include "M_AVR_PROC/M_AVR_PROC.h"
6
#include "M_STEER_MANAGEMENT/M_STEER_MANAGEMENT.h"
7
#include "M_ROUTE_MANAGEMENT/M_ROUTE_MANAGEMENT.h"
8
#include "M_LSM303DLH/M_LSM_303DLH.h"
9
#include "M_GPS/M_GPS.h"
10
#include "M_PROTOCOL/M_PROTOCOL.h"
11
#include "M_PROTOCOL/fifo.h"
12

13
#include <avr/io.h>
14
#include <stdlib.h>
15
#include <stdio.h>
16
#include <avr/wdt.h>
17

18

19
//WDT
20
uint8_t mcusr_mirror __attribute__ ((section (".noinit")));
21

22
void get_mcusr(void) __attribute__((naked)) __attribute__((section(".init1")));
23
void get_mcusr(void)
24
{
25
    mcusr_mirror = MCUSR;
26

27
    // disable the dog
28
    MCUSR = 0;
29
    wdt_disable();
30
}
31

32

33
//FIFO
34
fifo_t fifo_pc_in;
35
fifo_t fifo_pc_out;
36
fifo_t fifo_gps;
37
uint8_t fifo_buffer_in[60];
38
uint8_t fifo_buffer_out[60];
39
uint8_t fifo_buffer_gps[60];
40

41
//Timeouts
42
#define TIMEOUT_GPS 1000
43
#define TIMEOUT_WI232 1000
44
#define TIMEOUT_COMPASS 500
45
#define TIMEOUT_HEARTBEAT 500
46
#define TIMEOUT_PPM 100
47
#define TIMEOUT_GPS_MSG 2500
48
#define TIMEOUT_ALTERNATE_HOMING 10000
49

50
//Timer Hardware
51
unsigned long timer_gps_lc;
52
unsigned long timer_wi232_lc;
53
unsigned long timer_compass_lc;
54

55
//Timer Software
56
unsigned long timer_heartbeat_lc;
57
unsigned long timer_ppm_lc;
58
unsigned long timer_gps_msg;
59
unsigned long timer_alternate_homing;
60

61
//Checks Send
62
uint8_t timer_wi232_lc_send_check;
63

64
int main(void)
65
{
66
    fifo_init(&fifo_pc_in,fifo_buffer_in,60);
67
    fifo_init(&fifo_pc_out,fifo_buffer_out,60);
68
    fifo_init(&fifo_gps,fifo_buffer_gps,60);
69

70
    //Timer
71
    timer_gps_lc = 0;
72
    timer_wi232_lc = 0;
73
    timer_compass_lc = 0;
74
    timer_heartbeat_lc = 0;
75
    timer_ppm_lc = 250;
76
    timer_wi232_lc_send_check = 0x00;
77

78
    M_AVR_PROC_INIT();
79
    PORTB |= LED_RED|LED_GREEN;
80
delay_ms(20);
81

82
    PORTB &= ~ LED_GREEN;
83
PORTB &= ~ LED_RED;
84
    PORTB &= ~ LED_GREEN;
85

86
    sei();
87

88
    if( mcusr_mirror &(1<<WDRF))
89
    {
90
        char a[10];
91
        uint8_t e = protocol_msg_code(PROTOCOL_RESET,PROTOCOL_WATCHDOG_RESET,a);
92
        for(uint8_t i=0; i<e; i++)
93
        {
94
            fifo_put(&fifo_pc_out,a[i]);
95
        }
96
        UCSR0B |= (1<<UDRIE0);
97
        //PORTB |= LED_RED;
98
    }
99
    else
100
    {
101
        char a[10];
102
        uint8_t e = protocol_msg_code(PROTOCOL_RESET,PROTOCOL_NORMAL_RESET,a);
103
        for(uint8_t i=0; i<e; i++)
104
        {
105
            fifo_put(&fifo_pc_out,a[i]);
106
        }
107
        UCSR0B |= (1<<UDRIE0);
108
        //PORTB |= LED_GREEN;
109
    }
110

111
    PORTB &= ~ LED_RED;
112
    PORTB &= ~ LED_GREEN;
113

114
    wdt_enable(WDTO_2S);
115
while(1)
116
  {
117
    wdt_reset();
118
    delay_ms(500);
119
    wdt_reset();
120
    if(i2c_start(PPM_DECODER+1)==0)
121
    {
122
      fifo_put(&fifo_pc_out,'Z');
123
      UCSR0B |= (1<<UDRIE0);
124
      uint8_t a = i2c_readAck();
125
      uint8_t b = i2c_readAck();
126
      uint8_t c = i2c_readNak();
127
      fifo_put(&fifo_pc_out,a);
128
      fifo_put(&fifo_pc_out,b);
129
      fifo_put(&fifo_pc_out,c);
130
      fifo_put(&fifo_pc_out,'\n');
131
      UCSR0B |= (1<<UDRIE0);
132
    }
133
    i2c_stop();
134
    
135
  }
136

137
ISR(USART0_UDRE_vect)
138
{
139
    int a = fifo_get_nowait(&fifo_pc_out);
140
    if(a==-1)
141
    {
142
        UCSR0B &= ~(1<<UDRIE0);
143
        return;
144
    }
145
    else
146
    {
147
        UDR0 = a;
148
    }
149
}
150

151
ISR(USART0_RX_vect)
152
{
153
    uint8_t a = UDR0;
154
    fifo_put(&fifo_pc_in,a);
155
}
156

157
ISR(USART1_RX_vect)
158
{
159
    uint8_t a = UDR1;
160
    fifo_put(&fifo_gps,a);
161
}
162

163
ISR(WDT_vect)
164
{
165

166
}
Ich hab in dem letzteren code eine riesige "Initialisierung-Orgie" 
rausgelassen, weil da nur Software Funktionen mit tonnenweise Zeigern 
Initialisiert werden, die aber mit dem momentanen Tets nichts zu tun 
haben.

Wer was zum Compilieren will, ich hab beide codes angehängt.

Ich hoffe jemand kann mir helfen.

MfG
Philipp

P.S.: Wie is das eig mit der Reihenfolge, wenn der Master Neustartet, 
müssen die Slaves auch neustarten? Muss der Master zuerst Initialisiert 
werden oder können auch die Slaves voher Initialisiert werden?
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren