Codekonvertierung von ATmega32u4 auf ATmega328p

OP #4568135
Lesenswert?

Hallo Leute,
mir gehen langsam die Ideen aus.
Folgendes Problem: Ich beschreibe meinen selbstgebauten Slave per I2C 
erfolgreich über einen ATmega32u4, 16MHz Quarz, 8 Bit Prozessor, mit 
Hilfe der Peter Fleury Lib.Alles gut soweit und alles funktioniert.

Nun möchte ich das ganze Projekt auf den kleinen Arduino Nano mit dem 
ATmega328p on Board auslagern. Laut Datenblatt ebenso 16Mhz, 8 Bit 
Prozessor ... Dazu möchte ich nicht das ganze Arduinozeugs nutzen, 
sondern den C-Code inclusive TWI Lib weiter nutzen. Allerdings erkennt 
der Atmega328p gar nicht erst meinen Slave.

Ich hätte primär gedacht, aufgrund der gleichen F_CPU beider Chips gar 
nichts anpassen zu müssen, da nichts ging habe ich die Source_Clock auf 
400kHz gesetzt wie in diversen Tutorien beschrieben-alles ohne Erfolg.

Bitte helft mir, anbei sind die beiden Libs, welche ich verwende.
Angehängte Dateien:
OP #4568229
Lesenswert?

> #define F_CPU 4000000UL
>

Genau also die 4000000UL sind der default Wert aus der Biliothek. Bei 
dem 32u4 habe ich den Wert auf 2000000UL eingestellt.

> Mit welcher Frequenz arbeitet dein Controller wirklich?
>

Die Fuses habe ich nicht verändert, laut Datenblatt "
8.6 Calibrated Internal RC Oscillator
By default, the Internal RC Oscillator provides an approximate 8.0 MHz 
clock" würde ich also das als tatsächliche Frequenz vermuten?!
OP #4568231
Lesenswert?

>
> Und wo ist DEIN Programm?

Hier ist mal der Code für die init,start_wait,read und stop Befehle 
welche ich dann später alle verwende. Ich denke hier mache ich irgendwo 
was falsch ^^

#define SCL_CLOCK  100000L
#define F_CPU 2000000UL // Does not work with 1600000UL
#include <util/delay.h>
#include <avr/io.h>
#include <inttypes.h>
#include <util/twi.h>
#include <stdint.h>
#include <stdlib.h>

//variables
uint8_t reg[6];
int i;

void i2c_start_wait(unsigned char address)
{
  uint8_t   twst;


  while ( 1 )
  {
    // send START condition
    TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);

    // wait until transmission completed
    while(!(TWCR & (1<<TWINT)));

    // check value of TWI Status Register. Mask prescaler bits.
    twst = TW_STATUS & 0xF8;
    if ( (twst != TW_START) && (twst != TW_REP_START)) continue;

    // send device address
    TWDR = address;
    TWCR = (1<<TWINT) | (1<<TWEN);

    // wail until transmission completed
    while(!(TWCR & (1<<TWINT)));

    // check value of TWI Status Register. Mask prescaler bits.
    twst = TW_STATUS & 0xF8;
    if ( (twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK) )
    {
      /* device busy, send stop condition to terminate write operation 
*/
      TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);

      // wait until stop condition is executed and bus released
      while(TWCR & (1<<TWSTO));

      continue;
    }
    //if( twst != TW_MT_SLA_ACK) return 1;
    break;
  }

}/* i2c_start_wait */
unsigned char i2c_write(unsigned char data)
{
  uint8_t   twst;

  // send data to the previously addressed device
  TWDR = data;
  TWCR = (1<<TWINT) | (1<<TWEN);

  // wait until transmission completed
  while(!(TWCR & (1<<TWINT)));

  // check value of TWI Status Register. Mask prescaler bits
  twst = TW_STATUS & 0xF8;
  if( twst != TW_MT_DATA_ACK) return 1;
  return 0;

}
void i2c_stop()
{
  /* send stop condition */
  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);

  // wait until stop condition is executed and bus released
  while(TWCR & (1<<TWSTO));

}
void i2c_init()
{
  /* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */

  TWSR = 0;                         /* no prescaler */
  TWBR = ((F_CPU/SCL_CLOCK)-16)/2;  /* must be > 10 for stable operation 
*/

}
OP #4568252
Lesenswert?

> Und wo ist DEIN Programm?

Hier ist mal der Code für die init,start_wait,read und stop Befehle
welche ich dann später alle verwende. Ich denke hier mache ich irgendwo
was falsch ^^

>
> "Formatierung (mehr Informationen...)"
1
#define SCL_CLOCK  100000L
2
#define F_CPU 2000000UL // Does not work with 1600000UL
3
#include <util/delay.h>
4
#include <avr/io.h>
5
#include <inttypes.h>
6
#include <util/twi.h>
7
#include <stdint.h>
8
#include <stdlib.h>
9

10
//variables
11
uint8_t reg[6];
12
int i;
13

14
void i2c_start_wait(unsigned char address)
15
{
16
  uint8_t   twst;
17

18

19
  while ( 1 )
20
  {
21
    // send START condition
22
    TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
23

24
    // wait until transmission completed
25
    while(!(TWCR & (1<<TWINT)));
26

27
    // check value of TWI Status Register. Mask prescaler bits.
28
    twst = TW_STATUS & 0xF8;
29
    if ( (twst != TW_START) && (twst != TW_REP_START)) continue;
30

31
    // send device address
32
    TWDR = address;
33
    TWCR = (1<<TWINT) | (1<<TWEN);
34

35
    // wail until transmission completed
36
    while(!(TWCR & (1<<TWINT)));
37

38
    // check value of TWI Status Register. Mask prescaler bits.
39
    twst = TW_STATUS & 0xF8;
40
    if ( (twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK) )
41
    {
42
      /* device busy, send stop condition to terminate write operation 
43
*/
44
      TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
45

46
      // wait until stop condition is executed and bus released
47
      while(TWCR & (1<<TWSTO));
48

49
      continue;
50
    }
51
    //if( twst != TW_MT_SLA_ACK) return 1;
52
    break;
53
  }
54

55
}/* i2c_start_wait */
56
unsigned char i2c_write(unsigned char data)
57
{
58
  uint8_t   twst;
59

60
  // send data to the previously addressed device
61
  TWDR = data;
62
  TWCR = (1<<TWINT) | (1<<TWEN);
63

64
  // wait until transmission completed
65
  while(!(TWCR & (1<<TWINT)));
66

67
  // check value of TWI Status Register. Mask prescaler bits
68
  twst = TW_STATUS & 0xF8;
69
  if( twst != TW_MT_DATA_ACK) return 1;
70
  return 0;
71

72
}
73
void i2c_stop()
74
{
75
  /* send stop condition */
76
  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
77

78
  // wait until stop condition is executed and bus released
79
  while(TWCR & (1<<TWSTO));
80

81
}
82
void i2c_init()
83
{
84
  /* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */
85

86
  TWSR = 0;                         /* no prescaler */
87
  TWBR = ((F_CPU/SCL_CLOCK)-16)/2;  /* must be > 10 for stable operation 
88
*/
89

90
}
Gast #4568273
Lesenswert?

Flop P. schrieb:
> #define F_CPU 2000000UL // Does not work with 1600000UL

Das deutet darauf hin, dass man vielleicht doch bei den Fuses mal aktiv 
werden und den 1:8 Vorteiler rausnehmen sollte.

Einfachste Möglichkeit zum Abschätzen der wahren CPU Taktfrequenz ist 
der 1Hz-Blink-Test mit einer LED.

Um die Diagnose auf dem I2C zu vereinfachen, wäre vielleicht eine 
Minimalmessausstattung nicht schlecht, z.B. ein kleiner Logikanalysator 
für 6€ oder gar ein DSO.

Nebenbei: Verwendest du geeignete Pull-Up Widerständen für den I2C-Bus?
OP #4568277
Lesenswert?

Georg G.
> Dass du es mit neuer CPU-Definition neu übersetzen musst ist dir aber
> schon klar?

Georg G., wie genau müsste denn die neue CPU-Definition aussehen? Bzw. 
meinst du "nur" den neuen Wert ? Wie berechnet sich der, wenn ich einen 
16MHz Quarz benutze und die Fuses Defaultwerte besitzen??
Gast #4568283
Lesenswert?

Flop P. schrieb:
> Wie berechnet sich der, wenn ich einen
> 16MHz Quarz benutze und die Fuses Defaultwerte besitzen??

Zeig doch mal die Werte der Fuses. Wenn das ein vorkonfigurierter 
Arduino ist, dann sollten die Fuses korrekt eingestellt sein. Hast Du 
den Bootloader überschrieben?
OP #4568515
Lesenswert?

> Zeig doch mal die Werte der Fuses. Wenn das ein vorkonfigurierter
> Arduino ist, dann sollten die Fuses korrekt eingestellt sein. Hast Du
> den Bootloader überschrieben?

Aus  der SCK Periode(T)=0.1us hätte ich jetzt F_CPU = 1/T = 10MHz 
abgeleitet. Funktioniert aber scheinbar nicht so ?!

>Hast Du
> den Bootloader überschrieben?

Ich denke nicht, denn ich LED-Debugge meinen I2C Bus - sobald der Slave 
gefunden wurde, geht die LED ( PB5) auch aus(so sollte es zumindest sein 
wenn er den Slave finden würde). Damit diese LED  erstmal angeht muss 
also quasi mein Code schonmal vom Booleader bearbeitet worden sein.

Den Code flashe ich btw per 'avrdude -p m328p -c avrisp -P com39 -b 
57600 -F -U flash:w:filename'
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