Forum: Mikrocontroller und Digitale Elektronik Atmega8 + Atmega644p über TWI Problem


von Philipp M. (lord-maricek)


Angehängte Dateien:

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?

von Philipp M. (lord-maricek)


Lesenswert?

Hat niemand eine Idee woran es liegen könnte? Mit dem Kompass am I2C Bus 
kann ich noch kommunizieren, aber warum sendent der Mega8 nach dem 
ersten mal nichts mehr?

MfG
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.