Forum: Mikrocontroller und Digitale Elektronik Funkmodul RFM12b & MSP430 SPI Einstellungen


von Frank M. (frankmichelson)


Lesenswert?

hallo,

ich versuche schon seit längerem vergebens mit meinem msp430 über die 
SPI-Schnittstelle mit dem Funkmodul RFM12b zu komunizieren. weder der 
nIRQ geht auf low noch antwortet das Funkmodul, wenn ich über SPI die 
Status Bits (0x0000) abfrage.


FSK ist mit 10K an Vcc angeschlossen.

//           RFM12 Transceiver              MSP430F2013
//             -----------------          -----------------
//            |                 |     /|\|              XIN|-
//            |                 |      | |                 |
//            |                 |      --|RST          XOUT|-
//       VCC->|VDD              |        |                 |
//  VCC-10K ->|FSK/DATA         |        |                 |
//      GND ->|GND (7&10)       |        |                 |
//            |                 |        |             P1.0|-> LED
//            |             SDI/|<-------|P1.6/SDO         |
//            |             SDO/|------->|P1.7/SDI         |
//            |            SCLK/|<-------|P1.5/SCLK        |
//             -----------------          -----------------

Meine SPI Einstellungen:

 USICTL0 |= USISWRST;

 USICTL0 |= USIPE7 + USIPE6 + USIPE5 + USIMST + USIOE;
/*
 Configure USI:
 Enable SPI-Ports P1.7 (MISO), P1.6 (MOSI), P1.5 (SCLK)
 Configure MSP430F2013 as SPI-Master
 DataOutputEnable (enable SDO)
*/

  USICTL1 = USIIE;
/*
 Counter interrupt enabled, flag remains set
*/

  USICKCTL = USIDIV_5 + USISSEL_2;
/*
 Configure USI Clock:
 Divider = 32_dec
 SCLK (SPI-Clock): Clock source = SMCLK (Subsystem Clock)
 Inactive clock polarity = high; that means the SCLK pin
 will be at high-level, when the clock is deactivated
*/
  USICTL0 &= ~USISWRST;
/*
 USI released for operation
*/

Für Ratschläge oder Tipps wäre ich sehr Dankbar

von Erik (Gast)


Lesenswert?

Hallo Frank ,

NIRQ / NSEL mit angeschlossen wie in der einen PDF beschrieben ?

mfg Erik

von Michael U. (amiga)


Lesenswert?

Hallo,

inaktive Clock = L (Mode 0) sollte für den RFM12 passen.

Den MSP430 habe ich noch nicht benutzt, das Zeitverhalten von 
SCK/SDO/SDI des RFM ist aber in dessen Datenblatt gut beschrieben.

Auf nSEL wurde ja schon hingewiesen.

Gruß aus Berlin
Michael

von Frank M. (frankmichelson)


Lesenswert?

hallo,

nSEL liegt auf masse und nIRQ ist am P1.4 angeschlossen.
ich habe mich am Timing-Diagram vom datenblatt RF12B orientiert. Den MSP 
kenne ich "recht gut", aber SPI ist für mich neu. die Einstellungen 
müssten jetzt eigentlich richtig sein, aber am oszilloskop sehe ich 
keine reaktion am SDO vom rfm12b

hier der ganze code:

//********************************************************************** 
********
//  MSP430F20x2/3 Demo - SPI full-Duplex 3-wire Master
//
//  Description: SPI Master communicates with SPI Slave RFM12 868MHz
//  using 3-wire mode.
//  Master will pulse slave reset for synch start.
//  ACLK = n/a, MCLK = SMCLK = Default DCO
//
//                Slave                      Master
//           RFM12 Transceiver              MSP430F2013
//             -----------------          -----------------
//            |                 |     /|\|              XIN|-
//            |                 |      | |                 |
//            |                 |      --|RST          XOUT|-
//       VCC->|VDD              |        |                 |
//  VCC-10K ->|FSK/DATA         |        |                 |
//      GND ->|GND (7&10)       |        |                 |
//            |                 |        |             P1.0|-> LED
//            |             SDI/|<-------|P1.6/SDO         |
//            |             SDO/|------->|P1.7/SDI         |
//            |            SCLK/|<-------|P1.5/SCLK        |
//            |            nIRQ/|<-------|P1.4/ Input      |
//             -----------------          -----------------
//********************************************************************** 
********

#include <msp430x20x3.h>

//Function prototypes
void spi_init(void);                        // Initialization of SPI for 
converters
int Send_data_via_spi_to_rfm012(int);      // Send data to RFM012 via 
spi



void main(void)
{

  WDTCTL = WDTPW + WDTHOLD;             // Stop watchdog timer

  spi_init();                           //init spi interface of 
MSP430F2013


 int i;

    for (;;)
  {
    /*
    for( i = 0; i < 65535; i++)
      Send_data_via_spi_to_rfm012(i);
    */

      Send_data_via_spi_to_rfm012(0x8239);
      Send_data_via_spi_to_rfm012(0xA640);
      Send_data_via_spi_to_rfm012(0xC647);    //
      Send_data_via_spi_to_rfm012(0x94A0);    //
      Send_data_via_spi_to_rfm012(0xC2AC);    //
      Send_data_via_spi_to_rfm012(0xCA81);    //
      Send_data_via_spi_to_rfm012(0xC483);    //
      Send_data_via_spi_to_rfm012(0x9850);    //
      Send_data_via_spi_to_rfm012(0xE000);    //
      Send_data_via_spi_to_rfm012(0xC800);    //
      Send_data_via_spi_to_rfm012(0xC040);    //
      Send_data_via_spi_to_rfm012(0x0000);    //
      Send_data_via_spi_to_rfm012(0x7fff);

  }


}

void spi_init(void)
{
  P1DIR = BIT0;                // Configure P1.0 (= BIT0), P1.1 (= BIT1) 
as output:
                                       //   P1.0: LED Ouput for 
debugging
                                       //   P1.1: CS for RFM012
                                      //    P1.2: Input for nIRQ of 
RFM012
  P1OUT |= BIT0;                // Set CS at high level (disable 
communication with SPI-devices)

  P1SEL |= BIT7;

    USICTL0 |= USISWRST;                                  // USI stopped
  USICTL0 |= USIPE7 + USIPE6 + USIPE5 + USIMST + USIOE; // Configure 
USI:
                                                        //   Enable 
SPI-Ports P1.7 (MISO), P1.6 (MOSI), P1.5 (SCLK)
                                                        //   Configure 
MSP430F2013 as SPI-Master
                                                        // 
DataOutputEnable (enable SDO)
  USICTL1 = USIIE;                                     // Counter 
interrupt enabled, flag remains set
  USICTL1 |= USICKPH;                                  // Data is 
changed on the first SCLK edge and captured on the following edge
  USICKCTL = USIDIV_5 + USISSEL_2 + USICKPL;            // Configure USI 
Clock:
                                                        //   Divider = 
32_dec
                                                        //   SCLK 
(SPI-Clock): Clock source = SMCLK (Subsystem Clock)
                                                        //   Inactive 
clock polarity = high; that means the SCLK pin
                                                        //     will be 
at high-level, when the clock is deactivated
  USICTL0 &= ~USISWRST;                                 // USI released 
for operation
}



int Send_data_via_spi_to_rfm012(int data)
{
  int i;

    P1OUT |= BIT1;
    USISR = data;                      // Control bits: 1111_bin = Fhex, 
Data: 800_hex 2048_dec = 1.25 V
    USICNT = USI16B;                   // Enable 16-bit-shift-register 
mode in order send 16 bit of data.
                                       //   So the shift registers 
USISRL and USISRH are used.
                                       //   They can be addressed 
together by USISR
                                       //   All other bits of this 
register are deleted. USIIFGCC is one of these bits.
    USICNT |= 16;                      // Load USI Bit Counter Register 
(Family user's guide chapter 10.2):
                                       //   USICNTx-Bits value: 16_dec; 
in order to send 16 bit of data (16-bit-a/d-converter);
                                       //   Because USIIFGCC was 
deleted, the flag USIIFG is set if USICNTx reaches zero.
                                       //   When Counter Register is 
loaded and something has been writen to USISR(L)
                                       //     the transmission starts 
automatically
    while (!(USIIFG & USICTL1));       // Counter clear? USI counter 
sets USIIFG when USICNTx = 0



    P1OUT &= ~BIT1;

    while ((P1IN & BIT4) == BIT4)  //warten auf nIRQ Pin
    return 0;
}

von Tom (Gast)


Lesenswert?

Hallo,

wurde Dir schon geholfen oder hast du es jetzt am Laufen??

Ich hab das mit dem 2013 und nem 149 auch per Hardware SPI versucht. 
Klappte nicht, deshalb auf Software Spi umgestellt und läuft bestens..


Grüße

von Frank m. (Gast)


Lesenswert?

hi tom,

noch habe ich es über HW-SPI nicht zum laufen bekommen. ich habe den 
beispielcode vom datenblatt für den PIC angefangen umzuschreiben und es 
so per SW_SPI umzusetzten.

mags du deinen code veröffentlichen?

so sieht mein anfang schon mal aus:

//********************************************************************** 
********

//
//                Slave                      Master
//           RFM12 Transceiver              MSP430F2013
//             -----------------          -----------------
//            |                 |     /|\|              XIN|-
//            |                 |      | |                 |
//            |                 |      --|RST          XOUT|-
//       VCC->|VDD              |        |                 |
//  VCC-10K ->|FSK/DATA         |        |                 |
//      GND ->|GND (7&10)       |        |                 |
//            |                 |        |             P1.0|-> LED
//            |             SDI/|<-------|P1.6/SDO         |
//            |             SDO/|------->|P1.7/SDI         |
//            |            SCLK/|<-------|P1.5/SCLK        |
//            |            nSEL/|------->|P1.1/CS          |
//            |            nIRQ/|<-------|P1.4/ Input      |
//
//
//

//********************************************************************** 
********

#include <msp430x20x3.h>

typedef unsigned char uchar;
typedef unsigned int uint;


#define SPI_PORT  P1OUT
#define SPI_DIR   P1DIR
#define SDI       BIT7
#define SDO       BIT6
#define SCK       BIT5
#define nSEL      BIT1
#define nIRQ      BIT2

#define SCK0      (SPI_PORT&= ~SCK)
#define SCK1      (SPI_PORT|= SCK)
#define SDO0      (SPI_PORT&= ~SDO)
#define SDO1      (SPI_PORT|= SDO)



void SET_SW_SPI(void);
void Write0(void);
void Write1(void);
void WriteCMD(uint CMD);


void main(void)
{

  SET_SW_SPI();
  WriteCMD(0xc0ac);
}


void SET_SW_SPI(void){
  SPI_DIR= SDI + SDO + SCK + nSEL;
  SPI_PORT= SDI + SDO + SCK + nSEL;
  }

void Write0( void ){
  SDO0;
  __delay_cycles(5);
  SCK1;
  __delay_cycles(15);
  SCK0;
  }

void Write1( void ){
  SDO1;
  __delay_cycles(5);
  SCK1;
  __delay_cycles(15);
  SCK0;
  }

void WriteCMD( uint CMD ){
  uchar n=16;
  while(n--)
  {
    if(CMD&0x8000)
    Write1();
    else
    Write0();
    CMD=CMD<<1;
  }
}

mit dem Befehl 0xc0ac kann man die clock des RFM12b auf 3.33Mhz stellen. 
das ist praktisch weil man so auf die schnelle mit einem oszilloskop 
kontrollieren ob es funktioniert.

mfg frank

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.