Forum: Mikrocontroller und Digitale Elektronik AS3935 SPI merkwürdig


von Hugo P. (portisch)


Angehängte Dateien:

Lesenswert?

Hallo!

Ich bin gerade dabei den IC AS3935 mit einem Atmega168 zu verbinden:
http://www1.futureelectronics.com/doc/AUSTRIAMICROSYSTEMS/AS3935.pdf

und zwar will ich z.B. das Register 0x00 auslesen.
Dazu muss man den Read Befehl mit dem Register verodern.
Nach senden des Commands muss man noch ein Dummy Byte nachschicken, 
damit der AS3935 seine Clock hat um die Antwort rein zu schreiben.

Am Oszi passt alles:
Send per SPI: 0x40 (Read Register 0x00)
Receive per SPI: 0x24 (Binär: 00100100 = Default Werte)

Laut debuggen mit dem JTAGICE mkII bekomme ich aber 0x12 als Antwort!?

Ich komme einfach nicht drauf warum mir das Oszi das richtige zeigt, der 
AVR mir aber die falsche Antwort gibt!?
1
#define AS3935_READ    0x40
2
#define AS_AFE_GB    0x003E
3
result = as3935_rd_register(AS_AFE_GB);
1
// ----------------------------------------------------------------------------
2
// read register from AS3935
3
4
uint8_t as3935_rd_register(uint16_t reg)
5
{
6
  uint8_t val;
7
  RESET(AS3935_CS);
8
  
9
  spi_putc(AS3935_READ | (reg >> 8));
10
  val = spi_putc(0x00);
11
  
12
  SET(AS3935_CS);
13
14
  return val;
15
}
1
uint8_t spi_putc(uint8_t data)
2
{
3
4
  uint8_t rc;
5
  
6
  // put byte in send-buffer
7
  SPDR = data;
8
  
9
  // wait until byte was send
10
  while( !( SPSR & (1<<SPIF) ) );
11
12
  return SPDR;
13
14
}
1
#ifdef  SPI_PRESCALER
2
  #if (SPI_PRESCALER == 2) || (SPI_PRESCALER == 8) || (SPI_PRESCALER == 32) || (SPI_PRESCALER == 64)
3
    #define  R_SPSR  (1<<SPI2X)
4
    #define SPI_PRESCALER_   (SPI_PRESCALER * 2)
5
  #else
6
    #define  R_SPSR  0
7
    #define  SPI_PRESCALER_  SPI_PRESCALER
8
  #endif
9
  
10
  #define  SPI_CLOCK_RATE_BIT0    (1<<SPR0)
11
  #define  SPI_CLOCK_RATE_BIT1    (1<<SPR1)
12
  
13
  #if (SPI_PRESCALER_ == 4)
14
    #define  R_SPCR  0
15
  #elif (SPI_PRESCALER_ == 16)
16
    #define  R_SPCR  SPI_CLOCK_RATE_BIT0
17
  #elif (SPI_PRESCALER_ == 64)
18
    #define  R_SPCR  SPI_CLOCK_RATE_BIT1
19
  #elif (SPI_PRESCALER_ == 128)
20
    #define  R_SPCR  SPI_CLOCK_RATE_BIT1 | SPI_CLOCK_RATE_BIT0
21
  #else
22
    #error   SPI_PRESCALER must be one of the values of 2^n with n = 1..7!
23
  #endif
24
#else
25
  #error  SPI_PRESCALER not defined!
26
#endif
27
28
void mcp2515_spi_init(void)
29
{    
30
    // Aktivieren des SPI Master Interfaces
31
    SPCR = (1<<SPE)|(1<<MSTR) | R_SPCR;
32
    SPSR = R_SPSR;
33
}

Irgendwie kommt es mir vor als wäre ein rotate right drinnen:

Wenn ich Register 0x00 abfrage bekomme ich:
0x12, sollte aber 0x24 sein: 0x24 >> 1 == 0x12

Wenn ich Register 0x01 abfrage bekomme ich:
0x11, sollte aber 0x22 sein: 0x22 >> 1 == 0x11

Wenn ich Register 0x02 abfrage bekomme ich:
0x61, sollte aber 0xC2 sein: 0xC2 >> 1 == 0x61

Warum??

von spess53 (Gast)


Lesenswert?

Hi

Sieht nach falscher SPI-Eistellung aus. Lt.Datenblatt verlangt des 
AS3935 in Bitmitte eine fallende Flanke. Auf deinem Bild ist aber dort 
eine steigende.

MfG Spess

von Hugo P. (portisch)


Lesenswert?

Danke für den Hinweis!

Ich muss noch das Bit CPHA setzen, dann passt das Ergebnis!

Ist halt blöd, da ich auch noch den MCP2515 per SPI dran habe.
Dieser braucht das CPHA auf 0...

von Hugo P. (portisch)


Lesenswert?

Jetzt hätte ich noch eine Frage was ich auch noch nicht verstehe:

Ich habe dann eine Funktion:
1
// ----------------------------------------------------------------------------
2
// write register from AS3935
3
4
void as3935_wr_register(const uint16_t reg, const uint8_t val)
5
{
6
  uint8_t reg_val;
7
8
  reg_val = as3935_rd_register(reg);
9
  
10
  // clear unsed bits
11
  reg_val &= ~(reg & 0xFF);
12
  reg_val |= (reg & 0xFF) & val;
13
  
14
  RESET(AS3935_CS);
15
  SPCR |= (1<<CPHA);
16
17
  // put byte in send-buffer
18
  SPDR = AS3935_WRITE | (reg >> 8);
19
  
20
  // wait until byte was send
21
  while( !( SPSR & (1<<SPIF) ) );
22
  
23
  // put byte in send-buffer
24
  SPDR = reg_val;
25
  
26
  // wait until byte was send
27
  while( !( SPSR & (1<<SPIF) ) );  
28
  
29
  SPCR &= ~(1<<CPHA);  
30
  SET(AS3935_CS);
31
}

Wenn ich das nun live debugge ändert sich der Wert von reg und val 
obwohl sie als const definiert werden.

Wenn ich vorher eine extra static uint16_t definiere und die Werte 
übergebe bleiben die static vars unverändert.

    AVR Memory Usage
    ----------------
    Device: atmega168
    Program:   10902 bytes (66.5% Full)
    (.text + .data + .bootloader)
    Data:        295 bytes (28.8% Full)
    (.data + .bss + .noinit)

von Blitzdetektor Jungs (Gast)


Lesenswert?

Hallo zusammen,
Wir versuchen mit einem Texas Instruments Mikrocontroller mit Hilfe des 
AS3935 Franklin Lightning Sensor Blitze zu detektieren mit einem 
I2C-BUS. Jedoch haben wir bei der Registerauslesung Probleme. Unabhängig 
vom angefragten Register, liefert uns der Sensor im Betrieb ständig den 
selben Wert (0x24 oder 0x1C).
ACK bzw. NAK werden unserer Meinung nach richtig gesetzt. Ist dieses 
Problem bekannt bzw. könnt Ihr uns irgendwelche Tipps geben?
besten Dank im voraus!

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.