I2C meldet status 0x38

Gast #3270359
Lesenswert?

Hallo Leute,

ich habe einen Atmega 644PA,
und den BLMC von Ulrich Radig.

Der Atmega644 sendet 2Bytes und danach meldet der TWI 0x38, also 
Arbitration lost in SLA+W or data bytes. Hat jemand ne Ahnung wie das 
kommt?

Danke im Voraus.
Gast #3270395
Lesenswert?

>was meinst du mit Clockstretching.

Ein uC I2C Slave ist häufig zu langsam um sofort zu antworten.
Um sich ein bisschen Zeit zu verschaffen zieht er einfach
die Clockleitung runter. Wenn er bereit ist lässt er sie wieder los.
Das sollte der I2C Master abkönnen.

Was genau bei dir abgeht solltest du mal mit einem Logicanalyzer
oder Speicherosci ansehen. So ist das nur willenloses rumgerate.

Dein Programm in einer Minimalform zeigen wo der Fehler auftritt
könnte auch ungemein hilfreich sein.
Gast #3270402
Lesenswert?

Da wo "hier" steht bleibt er beim nächsten Senden stecken
und das printf liefert vorher halt 0x38. Zwischen jedem Senden wird 
1Sek.
gewartet.
1
uint8_t TWIM_Write (uint8_t byte)
2
  {
3
  uint8_t   twst;
4
/*
5
** Send data to the previously addressed device
6
*/
7
  TWDR = byte;
8
  TWCR = (1<<TWINT)|(1<<TWEN);
9
/*
10
** Wait until transmission completed
11
*/
12
  while (!(TWCR & (1<<TWINT)));/*hier*/
13
/*
14
** Check value of TWI Status Register. Mask prescaler bits
15
*/
16
  twst = TWSR & 0xF8;
17
  printf("0x%02x\n",twst);
18
  if (twst != TWI_MTX_DATA_ACK) return 1;
19

20
  return 0;
21
  }
Gast #3270425
Lesenswert?

Unten habe ich mal die main.c und die TWI_Master.c

main.c
1
/*******************************************************
2
 Author:          Manfred Langemann
3
 mailto:          Manfred.Langemann ät t-online.de
4
 Begin of project:      04.01.2008
5
 Latest version generated:  04.01.2008
6
 Filename:          Main.c
7
 Description:          Main routine for testing
8
               TWI_Master_main.c
9
 ********************************************************/
10
#include <stdio.h>
11
#include <avr/interrupt.h>
12

13
#include "General.h"
14
#include "RS232.h"
15
#include "Delay.h"
16
#include "TWI_Master.h"
17
/*
18
** This main programm demonstrates how to use the 
19
** implemented TWI master functions. These are:
20
**  TWIM_Init
21
**  TWIM_ReadAck
22
**  TWIM_ReadNack
23
**  TWIM_Write
24
**  TWIM_Stop
25
**
26
** For testing this program, use the program
27
** TWI_Slave_main.c in the slave uC and connect the
28
** two TWI lines properly (don't forget to also
29
** connect GND between Master and Slave!)
30
**
31
** Used uC for Master is ATMega32
32
*/
33
int main (void)
34
  {
35
  uint8_t    i;
36
  uint8_t    j=0;
37
  //uint8_t    Data[8];
38
  uint8_t    SlaveAddress = 0;
39
/*
40
** Clear any interrupt
41
*/
42
  cli ();
43
/*
44
** Wait 1 second for POR
45
*/
46
  Delay_ms (1000);
47
/*
48
** Initiate RS232
49
*/
50
  RS232_Init ();
51
  printf ("Hello world...\n");
52
/*
53
** Initiate TWI Master Interface with bitrate of 100000 Hz
54
*/
55
  if (!TWIM_Init (100000))
56
    {
57
    printf ("Error in initiating TWI interface\n");
58
    while (1);
59
    }
60
/*
61
** Endless loop
62
*/
63
  while (1)
64
    {
65
/*
66
** Write byte(s) to the slave.
67
** It is implicitely assumed, that the slave will
68
** accepts 8 bytes
69
*/
70
      if (!TWIM_Start (SlaveAddress, TWIM_WRITE))
71
      {
72
      TWIM_Stop ();
73
      printf ("Could not start TWI Bus for WRITE\n");
74
        }
75
    else
76
      {
77
            TWIM_Write (j++);
78
        printf ("Byte sent: %d\n", j);
79
      TWIM_Stop ();
80
      Delay_ms (1000);
81
      }
82
    }
83

84
  return 0;
85
  }
TWI-Master
1
#include <stdio.h>
2
#include <avr/interrupt.h>
3

4
#include "General.h"
5
#include "TWI_Master.h"
6

7
/****************************************************************************
8
  TWI State codes
9
****************************************************************************/
10
// General TWI Master staus codes                      
11
#define TWI_START          0x08  // START has been transmitted  
12
#define TWI_REP_START        0x10  // Repeated START has been transmitted
13
#define TWI_ARB_LOST        0x38  // Arbitration lost
14

15
// TWI Master Transmitter staus codes                      
16
#define TWI_MTX_ADR_ACK        0x18  // SLA+W has been tramsmitted and ACK received
17
#define TWI_MTX_ADR_NACK      0x20  // SLA+W has been tramsmitted and NACK received 
18
#define TWI_MTX_DATA_ACK      0x28  // Data byte has been tramsmitted and ACK received
19
#define TWI_MTX_DATA_NACK      0x30  // Data byte has been tramsmitted and NACK received 
20

21
// TWI Master Receiver staus codes  
22
#define TWI_MRX_ADR_ACK        0x40  // SLA+R has been tramsmitted and ACK received
23
#define TWI_MRX_ADR_NACK      0x48  // SLA+R has been tramsmitted and NACK received
24
#define TWI_MRX_DATA_ACK      0x50  // Data byte has been received and ACK tramsmitted
25
#define TWI_MRX_DATA_NACK      0x58  // Data byte has been received and NACK tramsmitted
26

27
// TWI Slave Transmitter staus codes
28
#define TWI_STX_ADR_ACK        0xA8  // Own SLA+R has been received; ACK has been returned
29
#define TWI_STX_ADR_ACK_M_ARB_LOST  0xB0  // Arbitration lost in SLA+R/W as Master; own SLA+R has been received; ACK has been returned
30
#define TWI_STX_DATA_ACK      0xB8  // Data byte in TWDR has been transmitted; ACK has been received
31
#define TWI_STX_DATA_NACK      0xC0  // Data byte in TWDR has been transmitted; NOT ACK has been received
32
#define TWI_STX_DATA_ACK_LAST_BYTE  0xC8  // Last data byte in TWDR has been transmitted (TWEA = “0”); ACK has been received
33

34
// TWI Slave Receiver staus codes
35
#define TWI_SRX_ADR_ACK        0x60  // Own SLA+W has been received ACK has been returned
36
#define TWI_SRX_ADR_ACK_M_ARB_LOST  0x68  // Arbitration lost in SLA+R/W as Master; own SLA+W has been received; ACK has been returned
37
#define TWI_SRX_GEN_ACK        0x70  // General call address has been received; ACK has been returned
38
#define TWI_SRX_GEN_ACK_M_ARB_LOST  0x78  // Arbitration lost in SLA+R/W as Master; General call address has been received; ACK has been returned
39
#define TWI_SRX_ADR_DATA_ACK    0x80  // Previously addressed with own SLA+W; data has been received; ACK has been returned
40
#define TWI_SRX_ADR_DATA_NACK    0x88  // Previously addressed with own SLA+W; data has been received; NOT ACK has been returned
41
#define TWI_SRX_GEN_DATA_ACK    0x90  // Previously addressed with general call; data has been received; ACK has been returned
42
#define TWI_SRX_GEN_DATA_NACK    0x98  // Previously addressed with general call; data has been received; NOT ACK has been returned
43
#define TWI_SRX_STOP_RESTART    0xA0  // A STOP condition or repeated START condition has been received while still addressed as Slave
44

45
// TWI Miscellaneous status codes
46
#define TWI_NO_STATE        0xF8  // No relevant state information available; TWINT = “0”
47
#define TWI_BUS_ERROR        0x00  // Bus error due to an illegal START or STOP condition
48

49
/*******************************************************
50
 Public Function: TWIM_Init
51

52
 Purpose: Initialise the TWI Master Interface
53

54
 Input Parameter:
55
   - uint16_t  TWI_Bitrate (Hz)
56

57
 Return Value: uint8_t
58
   - FALSE:  Bitrate too high
59
   - TRUE:    Bitrate OK
60

61
*******************************************************/
62
uint8_t TWIM_Init (uint32_t TWI_Bitrate)
63
  {
64
/*
65
** Set TWI bitrate
66
** If bitrate is too high, then error return
67
*/
68
  TWBR = ((F_CPU/TWI_Bitrate)-16)/2;
69
  if (TWBR < 11) return FALSE;
70

71
  return TRUE;
72
  }
73
/*******************************************************
74
 Public Function: TWIM_Start
75

76
 Purpose: Start the TWI Master Interface
77

78
 Input Parameter:
79
   - uint8_t  Device address
80
   - uint8_t  Type of required Operation:
81
        TWIM_READ: Read data from the slave
82
        TWIM_WRITE: Write data to the slave
83

84
 Return Value: uint8_t
85
    - TRUE:    OK, TWI Master accessible
86
   - FALSE:  Error in starting TWI Master
87

88
*******************************************************/
89
uint8_t TWIM_Start (uint8_t Address, uint8_t TWIM_Type)
90
  {
91
  uint8_t    twst;
92
/*
93
** Send START condition
94
*/
95
  TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
96
/*
97
** Wait until transmission completed
98
*/
99
  while (!(TWCR & (1<<TWINT)));
100
/*
101
** Check value of TWI Status Register. Mask prescaler bits.
102
*/
103
  twst = TWSR & 0xF8;
104
  printf("0x%02x\n",twst);
105
  if ((twst != TWI_START) && (twst != TWI_REP_START)) return FALSE;
106
/*
107
** Send device address
108
*/
109
  TWDR = (Address<<1) + TWIM_Type;
110
  TWCR = (1<<TWINT)|(1<<TWEN);
111
/*
112
** Wait until transmission completed and ACK/NACK has been received
113
*/
114
  while (!(TWCR & (1<<TWINT)));
115
/*
116
** Check value of TWI Status Register. Mask prescaler bits.
117
*/
118
  twst = TWSR & 0xF8;
119
  printf("0x%02x\n",twst);
120
  if ((twst != TWI_MTX_ADR_ACK) && (twst != TWI_MRX_ADR_ACK)) return FALSE;
121

122
  return TRUE;
123
  }
124
/*******************************************************
125
 Public Function: TWIM_Stop
126

127
 Purpose: Stop the TWI Master
128

129
 Input Parameter: None
130

131
 Return Value: None
132

133
*******************************************************/
134
void TWIM_Stop (void)
135
  {
136
/*
137
** Send stop condition
138
*/
139
  TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
140
/*
141
** Wait until stop condition is executed and bus released
142
*/
143
  while (TWCR & (1<<TWINT));
144
  }
145
/*******************************************************
146
 Public Function: TWIM_Write
147

148
 Purpose: Write a byte to the slave
149

150
 Input Parameter:
151
   - uint8_t  Byte to be sent
152

153
 Return Value: uint8_t
154
    - TRUE:    OK, Byte sent
155
   - FALSE:  Error in byte transmission
156

157
*******************************************************/
158
uint8_t TWIM_Write (uint8_t byte)
159
  {
160
  uint8_t   twst;
161
/*
162
** Send data to the previously addressed device
163
*/
164
  TWDR = byte;
165
  TWCR = (1<<TWINT)|(1<<TWEN);
166
/*
167
** Wait until transmission completed
168
*/
169
  while (!(TWCR & (1<<TWINT)));
170
/*
171
** Check value of TWI Status Register. Mask prescaler bits
172
*/
173
  twst = TWSR & 0xF8;
174
  printf("0x%02x\n",twst);
175
  if (twst != TWI_MTX_DATA_ACK) return 1;
176

177
  return 0;
178
  }
179
/*******************************************************
180
 Public Function: TWIM_ReadAck
181

182
 Purpose: Read a byte from the slave and request next byte
183

184
 Input Parameter: None
185

186
 Return Value: uint8_t
187
    - uint8_t  Read byte
188

189
*******************************************************/
190
uint8_t TWIM_ReadAck (void)
191
  {
192
  TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
193
  while (!(TWCR & (1<<TWINT)));    
194

195
  return TWDR;
196
  }
197
/*******************************************************
198
 Public Function: TWIM_ReadAck
199

200
 Purpose: Read the last byte from the slave
201

202
 Input Parameter: None
203

204
 Return Value: uint8_t
205
    - uint8_t  Read byte
206

207
*******************************************************/
208
uint8_t TWIM_ReadNack (void)
209
  {
210
  TWCR = (1<<TWINT)|(1<<TWEN);
211
  while(!(TWCR & (1<<TWINT)));
212
  
213
  return TWDR;
214
  }
Gast #3270462
Lesenswert?

Wenn ich versuche die adresse 0x0C zu nehmen bekomme ich "Could not 
start TWI Bus for WRITE". Also bleibe ich schon beim Starten hängen.

Hat der Atmega88 vom BLMC vllt. nen CKDIV8 oder etwas ähnliches was den 
Takt ändert?

Oder gibt es noch etwas was ich bei den Fuse-Bits ändern muss außer 
Externer Quarz also... Full swing crystal oscillator?
Gast #3270510
Lesenswert?

>In der BLMC Software ist 0x0C eingestellt und auf die adresse 0
>antwortet er ja 2mal mit einem ACK und danach nicht mehr.

Auf die antwortet er aber nicht. Auf die um 1 Bit nach rechts geschobene
Adresse auch nicht. Dein Programm schiebt die Adresse ja um eine Stelle
nach links.

Hast du das Programm mit der neuen Adresse überhaupt compiliert?

Was ist wenn du 0x70 oder 0x38 nimmst?
Gast #3270550
Lesenswert?

Also so sieht mein Testprogramm für 4 Motoren auf die Schnelle aus.
1
#include <avr/interrupt.h>
2
#include <avr/io.h>
3
#include <util/twi.h>
4

5
//Motoradresse
6
#define MOTOR_ADR 0x70
7

8

9
//############################################################################
10
//Hauptprogramm
11
int main (void) 
12
//############################################################################
13
{
14
  unsigned char pwm = 10;
15
  //Watchdog off
16
  asm("wdr");
17
  MCUSR &= ~(1<<WDRF);
18
  //Write logical one to WDCE and WDE
19
  WDTCSR |= (1<<WDCE) | (1<<WDE);
20
  //Turn off WDT
21
  WDTCSR = 0x00;
22
  
23
  TWSR = 0;
24
  TWBR = ((12000000/200000)-16)/2; 
25
  DDRC |= (1<<5); //SCL Output
26
  
27
  DDRB |= (1<<0);
28
  PORTB |= (1<<0);
29
  
30
  
31
  while(1)
32
  {
33
      //Start I2C
34
      TWCR = (1<<TWSTA) | (1<<TWEN) | (1<<TWINT);
35
      while (!(TWCR & (1<<TWINT)));
36
      //Write Motor Adresse
37
      TWSR = 0x00;
38
      TWDR = 0x40;
39
      TWCR = (1<<TWINT) | (1<<TWEN);
40
      while (!(TWCR & (1<<TWINT)));  
41
      //Write PWM
42
      TWSR = 0x00;
43
      TWDR = pwm;
44
      TWCR = (1<<TWINT) | (1<<TWEN);
45
      while (!(TWCR & (1<<TWINT)));
46
      //Stop I2C
47
      TWCR = (1<<TWEN) | (1<<TWSTO) | (1<<TWINT);
48
      for(unsigned long a = 0;a<10000;a++) asm("nop");
49
      
50
      //Start I2C
51
      TWCR = (1<<TWSTA) | (1<<TWEN) | (1<<TWINT);
52
      while (!(TWCR & (1<<TWINT)));
53
      //Write Motor Adresse
54
      TWSR = 0x00;
55
      TWDR = 0x50;
56
      TWCR = (1<<TWINT) | (1<<TWEN);
57
      while (!(TWCR & (1<<TWINT)));  
58
      //Write PWM
59
      TWSR = 0x00;
60
      TWDR = pwm;
61
      TWCR = (1<<TWINT) | (1<<TWEN);
62
      while (!(TWCR & (1<<TWINT)));
63
      //Stop I2C
64
      TWCR = (1<<TWEN) | (1<<TWSTO) | (1<<TWINT);
65
      for(unsigned long a = 0;a<10000;a++) asm("nop");
66
      
67
      //Start I2C
68
      TWCR = (1<<TWSTA) | (1<<TWEN) | (1<<TWINT);
69
      while (!(TWCR & (1<<TWINT)));
70
      //Write Motor Adresse
71
      TWSR = 0x00;
72
      TWDR = 0x60;
73
      TWCR = (1<<TWINT) | (1<<TWEN);
74
      while (!(TWCR & (1<<TWINT)));  
75
      //Write PWM
76
      TWSR = 0x00;
77
      TWDR = pwm;
78
      TWCR = (1<<TWINT) | (1<<TWEN);
79
      while (!(TWCR & (1<<TWINT)));
80
      //Stop I2C
81
      TWCR = (1<<TWEN) | (1<<TWSTO) | (1<<TWINT);
82
      for(unsigned long a = 0;a<10000;a++) asm("nop");
83
      
84
      //Start I2C
85
      TWCR = (1<<TWSTA) | (1<<TWEN) | (1<<TWINT);
86
      while (!(TWCR & (1<<TWINT)));
87
      //Write Motor Adresse
88
      TWSR = 0x00;
89
      TWDR = 0x70;
90
      TWCR = (1<<TWINT) | (1<<TWEN);
91
      while (!(TWCR & (1<<TWINT)));  
92
      //Write PWM
93
      TWSR = 0x00;
94
      TWDR = pwm;
95
      TWCR = (1<<TWINT) | (1<<TWEN);
96
      while (!(TWCR & (1<<TWINT)));
97
      //Stop I2C
98
      TWCR = (1<<TWEN) | (1<<TWSTO) | (1<<TWINT);
99
      for(unsigned long a = 0;a<10000;a++) asm("nop");
100
  }
101
}
Gast #3270571
Lesenswert?

holger schrieb:
> Poste deinen aktuellen Code vom BLMC.
1
/*----------------------------------------------------------------------------
2
 Copyright:      Ulrich Radig (mail@ulrichradig.de)
3
 Author:         Ulrich Radig
4
 Remarks:        
5
 known Problems: none
6
 Version:        23.06.2011
7
 Description:    Brushless Motor Controller for ATmega48/88/168
8
 
9
 Dieses Programm ist freie Software. Sie können es unter den Bedingungen der 
10
 GNU General Public License, wie von der Free Software Foundation veröffentlicht, 
11
 weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder 
12
 (nach Ihrer Option) jeder späteren Version. 
13

14
 Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, 
15
 daß es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, 
16
 sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT 
17
 FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License. 
18

19
 Sie sollten eine Kopie der GNU General Public License zusammen mit diesem 
20
 Programm erhalten haben. 
21
 Falls nicht, schreiben Sie an die Free Software Foundation, 
22
 Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
23
------------------------------------------------------------------------------*/
24

25
#include <avr/interrupt.h>
26
#include <avr/io.h>
27
#include <util/twi.h>
28

29
//Motoradresse
30
#define MOTOR_ADR 0x0C
31

32
//PHASE1 (U)
33
#define UH_DDR  DDRB |= (1<<3);
34
#define UH_ON  TCCR2A |= (1<<COM2A1);
35
#define UH_OFF  TCCR2A &= ~(1<<COM2A1);
36

37
//PHASE1 (U)
38
#define UL_DDR  DDRB |= (1<<1);
39
#define UL_ON  PORTB |= (1<<1);
40
#define UL_OFF  PORTB &= ~(1<<1);
41

42

43
//PHASE2 (V)
44
#define VH_DDR  DDRD |= (1<<5);
45
#define VH_ON  TCCR0A |= (1<<COM0B1);
46
#define VH_OFF  TCCR0A &= ~(1<<COM0B1);
47

48
//PHASE2 (V)
49
#define VL_DDR  DDRB |= (1<<2);
50
#define VL_ON  PORTB |= (1<<2);
51
#define VL_OFF  PORTB &= ~(1<<2);
52

53

54
//PHASE3 (W)
55
#define WH_DDR  DDRD |= (1<<3);
56
#define WH_ON  TCCR2A |= (1<<COM2B1);
57
#define WH_OFF  TCCR2A &= ~(1<<COM2B1);
58

59
//PHASE3 (W)
60
#define WL_DDR  DDRC |= (1<<3);
61
#define WL_ON  PORTC |= (1<<3);
62
#define WL_OFF  PORTC &= ~(1<<3);
63

64

65
#define PHASE_ALL_OFF  UH_OFF;UL_OFF;VH_OFF;VL_OFF;WH_OFF;WL_OFF;
66

67
#define SENSE_U    ADMUX = 0;
68
#define SENSE_V    ADMUX = 1;
69
#define SENSE_W    ADMUX = 2;
70

71
#define SENSE_H    (ACSR&(1<<ACO))
72

73
#define START_PWM   5
74

75
volatile unsigned long i2c_timeout = 0;
76
volatile unsigned char rx_pwm = 0;
77
volatile unsigned char rotor_state = 0;
78
volatile unsigned char rotor_run = 0;
79

80
//############################################################################
81
void next_commutate_state (unsigned char startup)
82
//############################################################################
83
{
84
  switch (rotor_state)
85
  {
86
    case (0):
87
      if(!SENSE_H || startup)
88
      {
89
        WH_OFF;
90
        UH_ON;
91
        SENSE_W;
92
        rotor_state = 1;
93
        TCNT1 = 1;
94
      }
95
      break;
96

97
    case (1):
98
      if(SENSE_H || startup)
99
      {
100
        VL_OFF;
101
        WL_ON;
102
        SENSE_V;
103
        rotor_state = 2;
104
        TCNT1 = 1;
105
      }
106
      break;
107

108
    case (2):
109
      if(!SENSE_H || startup)
110
      {
111
        UH_OFF;
112
        VH_ON;
113
        SENSE_U;
114
        rotor_state = 3;
115
        TCNT1 = 1;
116
      }
117
      break;
118
  
119
    case (3):
120
      if(SENSE_H || startup)
121
      {
122
        WL_OFF;
123
        UL_ON;
124
        SENSE_W;
125
        rotor_state = 4;
126
        TCNT1 = 1;
127
      }
128
      break;
129

130
    case (4):
131
      if(!SENSE_H || startup)
132
      {
133
        VH_OFF;
134
        WH_ON;
135
        SENSE_V;
136
        rotor_state = 5;
137
        TCNT1 = 1;
138
      }
139
      break;
140

141
    case (5):
142
      if(SENSE_H || startup)
143
      {
144
        UL_OFF;
145
        VL_ON;
146
        SENSE_U;
147
        rotor_state = 0;
148
        TCNT1 = 1;
149
      }
150
      break;
151
  }
152
}
153

154
//############################################################################
155
//back EMF zero crossing detection
156
ISR (ANALOG_COMP_vect) 
157
//############################################################################
158
{
159
  if(rotor_run == 200) next_commutate_state (0);
160
  
161
  rotor_run++;
162
  if(rotor_run > 200)
163
  {
164
    rotor_run = 200;
165
  }
166
}
167

168
//############################################################################
169
ISR (TIMER1_OVF_vect)
170
//############################################################################
171
{  
172
  next_commutate_state (1);
173
  rotor_run = 0;
174
  OCR2A = START_PWM;
175
  OCR2B = START_PWM;
176
  OCR0B = START_PWM;
177
}
178

179
//############################################################################
180
ISR (TWI_vect)
181
//############################################################################
182
{  
183
  switch (TWSR & 0xF8) //TW_STATUS 
184
  {  
185
    //Adresse empfangen
186
    case TW_SR_SLA_ACK:  
187
      TWCR |= (1<<TWINT);
188
      return;
189
      
190
    //Daten empfangen
191
    case TW_SR_DATA_ACK:
192
      rx_pwm = TWDR;
193
      TWCR |= (1<<TWINT);
194
      i2c_timeout = 0;
195
      return;
196

197
    //Bus-Fehler zurücksetzen 
198
    case TW_NO_INFO:
199
      TWCR |=(1<<TWSTO) | (1<<TWINT); 
200

201
    //Bus-Fehler zurücksetzen   
202
    case TW_BUS_ERROR:
203
      TWCR |=(1<<TWSTO) | (1<<TWINT); 
204
  }
205
  //Reset TW
206
  TWCR =(1<<TWEA) | (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
207
}
208

209
//############################################################################
210
//Hauptprogramm
211
int main (void) 
212
//############################################################################
213
{
214
  //Watchdog on
215
  WDTCSR = (1<<WDCE) | (1<<WDE);
216
  
217
  //Motordriver output
218
  UH_DDR;
219
  VH_DDR;
220
  WH_DDR;
221
  UL_DDR;
222
  VL_DDR;
223
  WL_DDR;
224
    
225
  //PWM for UH, VH and WH (>32KHz)
226
  TCCR0A |= (1<<COM0B1|1<<WGM01|1<<WGM00);
227
  TCCR0B |= (1<<CS00);
228
  
229
  TCCR2A |= (1<<COM2A1|1<<COM2B1|1<<WGM21|1<<WGM20);
230
  TCCR2B |= (1<<CS20);
231
  
232
  //TIMER1 for start commutation or Back EMF lost
233
  TCCR1B |= (1<<CS11);
234
  TIMSK1 |= (1<<TOIE1);
235

236
  PHASE_ALL_OFF;
237
  
238
  //Comperator init for back EMF
239
  ADCSRB  |= (1<<ACME);
240
  DIDR1  |= (1<<AIN0D);
241
  ACSR  |= (1<<ACIE);
242
    
243
  //I2C Init
244
  TWAR = MOTOR_ADR & 0xFE;
245
    TWCR = (1<<TWINT)|(1<<TWEA)|(1<<TWEN)|(1<<TWIE);
246
  
247
  //Interrupts enabel
248
  sei();
249
  
250

251
  while(1)
252
  {  
253
    asm("wdr");
254
    if(rx_pwm > START_PWM)
255
    {
256
      ACSR |= (1<<ACIE);
257
      TIMSK1 |= (1<<TOIE1);
258
      
259
      if(rotor_run == 200)
260
      {
261
        OCR2A = rx_pwm;
262
        OCR2B = rx_pwm;
263
        OCR0B = rx_pwm;
264
      }
265
      i2c_timeout++;
266
      
267
      if(i2c_timeout>100000)
268
      {
269
        rx_pwm = 0;
270
      }
271
    }
272
    else
273
    {
274
      PHASE_ALL_OFF;
275
      ACSR&=~(1<<ACIE);
276
      TIMSK1 &= ~(1<<TOIE1);
277
    }
278
  }
279
}
Gast #3270584
Lesenswert?

Und du bist sicher das du auch immer die aktuelle HEX Datei geflasht 
hast?

Ich mach dir mal einen Vorschlag:

Nimm das BLMC Programm. Lass die Adresse bei 0x0C.
Mach ein make clean, und neu übersetzen.
Nachsehen ob die HEX Datei das aktuelle Datum hat.
HEX Datei neu auswählen im Brenndialog. HEX Datei flashen.

Das gleiche machst du mit deinem Programm. Mit jedem einzelnen Schritt.
Einmal mit 0x0C und 0x06.

Wenn das nicht hilft, hilft dir nur noch Gott.
Gast #3270939
Lesenswert?

Hast Du mal mit der Ticktack gespielt?

1 MHz  Takt ist flott, kann aber nicht jeder.
400KHz sind auch nicht ohne, möglicherweise kann auch das nicht jeder.
100KHz gehen auch noch recht gut.

Vergiss' nicht, Du (ATMega644) hast das sagen. Du gibst den Takt an.

Kann es sein, dass Du zwar Pull-Up-Widerstände aber keine 
Abschlusswiderstände hast?
Der Unterschied liegt in der Position bzw. im Layout.
Gast #3270986
Lesenswert?

amateur schrieb:
> Vergiss' nicht, Du (ATMega644) hast das sagen. Du gibst den Takt an.

Ja ich weiß gebe 100kHz vor

amateur schrieb:
> Abschlusswiderstände hast?

noch nie bei I2C gesehen

Abdul K. schrieb:
> SDA mit SCL vertauscht? Poste deine Scope-Aufnahme!

Denn würde es ja nie gehen und nach durchgangs prüfungen ist alles 
richtig
Wenn ich ein scope hätte, mach es wenn es sein muss mit meiner 
Soundkarte
#3271140
Lesenswert?

Sven Müller schrieb:
> Abdul K. schrieb:
>> Elektronikentwicklung
>> ohne Scope ist einfach Blödsinn.
>
> Ich habe die nötigen Geräte sonst in der Schule, aber wir haben ferienn.
> Zudem bin ich nicht reich und kann mir solche Geräte nicht leisten! Kein
> Grund jemanden zu verurteilen.

Das sind ausreden!
Heute gibt es unglaublich günstige LAs. Es muss ja kein ausgewachsenes 
DSO sein.
Aber wenn man Embedded Entwicklung betreibt (auch privat) muss man einen 
Grundstock an Messgeräten haben. Das ist keine Frage des Geldes.
Ich kenne im Elektro-Modellflug Menschen mit 30 Jahren Erfahrung, ner 
10.000 Euro Maschine (3m Spannweite) aber haben zuhause kein Multimeter. 
Da kann man nur den Kopf schütteln. Auch fürs Hobby brauchts Ausrüstung!

Das ist heute alles saubillig und trotzdem fürs Hobby tauglich. Und wenn 
man mit seriellen Bussen spielt, sollte man irgendwie die Möglichkeit 
haben, diese zu sehen. Also einen LA. Ohne solche Technik macht man sich 
das Leben schwer und den anderen hier auch.

gruß cyblord
Gast #3271797
Lesenswert?

Na ja, ein Funken Wahrheit ist an dem was Cyblord und Abdul so schreiben 
schon dran.
Oszis gibts neu für 300 EUR, der EEV-Blogger hat sogar bei Ebay für sage 
und schreibe 19Aussie Dollar ein voll funktionsfähiges Hameg 
Speicheroszi aufgetrieben. Und wenn man clever ist kann man selbst mit 
einem alten Analog-Oszi + externer Triggerung und einem triggernden 
Port-Bit für ein Standbild sorgen um die Bits auf dem I2C-Bus 
abzuzählen.

Aber was solls. Schuld ist bei nicht funktionsfähigen Nachbauten ja 
sowieso eh immer derjenige der sich die Mühe machte sich etwas 
auszudenken und frei zu veröffentlichen.
Gast #3272122
Lesenswert?

Woran es jetzt gelegen hat wurde mir auch nicht verraten. Der geposteten 
Source Code funktionierte bei mir habe ich gestern Abend noch getestet. 
Das Ruckeln des Motors liegt am Delay (1000). Die Software ist für eine 
Drohne ausgelegt. Erhält der Motor nicht innerhalb einer gewissen Zeit 
ein neues Datenbyte bleibt dieser stehen.

Gruß
Uli
Persönliche Seite #3272858
Lesenswert?

Sven Müller schrieb:
> cyblord ---- schrieb:
>> Das sind ausreden!
>
> Ich bin nich hier um mir etwas unterstellen zu lassen.
>
> Ich erwarte ledigtlich ein bisschen hilfe und keine Unterstellungen.

Das darf natürlich deine Meinung sein und Verurteilung zu unterstellen, 
find ich auch etwas dreist! Für 10 Euro bekommt man einen LA. Einzige 
Einschränkung: Ohne Tricks keine analogen Werte.

Es läuft halt einfach so: Du bleibst auf deinem Standpunkt und ich helfe 
dir eben nicht mehr, denn meine Zeit ist auch kostbar.

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