mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik M16C SPI


Autor: Til (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

ich möchte an meinen M16C26 SPI nutzen, nur finde ich leider nichts im
Datenblatt zu SPI, nur Informationen zum clock synchronous Mode, was ja
eigentlich SPI ist.

Hat jemand schon mal SPI mit dem M16C programmiert und dabei die
seriellen Funktionen des M16C genutzt (kein Portgeklapper!)?

Anregungen oder Codebeispiele helfen mir weiter!!

Danke.

Autor: Sascha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

so läuft es bei mir:

//********************************************************************** 
********
//   SPI-Ansteuerung MAX186
//  Basiernd auf RENESAS M16C62 Using the M16C62 UART for SPI
Communication
//
//   /CS = P73
//   DIN = P70/TXD2  !Bei TXD2 unbedingt ext. PullUp!
//   DOUT = P71/RXD
//  SCLK = P72/CLK
//  SSTRB = P74
//********************************************************************** 
********

void init_spi(void)
{
  pur1=0xff;
    CS_MAX186_DDR = 1;  // Change CHIP_SELECT port to output
  CS_MAX186 = 1;    // Bring CHIP_SELECT high
  SSTRB_DDR = 0;
    /* configure UART2 for SPI */
    u2c0   = 0x91;
  u2c1   = 0x00;    /* no data reverse, rx & tx disabled */
  u2brg  = 5;      // 2MHz SPI-CLK
  ckpol_u2c0 = 0;    // Clock polarity, bit 6 of U2C0 register
    ckph_u2smr3 = 0;  // Clock phase, bit 1 of U2SMR3 register.
    u2mr   = 0x01;    /* synchronous mode, internal clock, no reverse*/
}

unsigned char SPI_send_receive(unsigned char cmd)
{
  unsigned char i;
  while( !ti_u2c1 );      // Ensure transmit buffer is empty
    while( !txept_u2c0 );    // Ensure transmit register is empty
  i = u2rbl;           // Read receive buffer to empty it
    re_u2c1 = 1;        // Enable rx
    te_u2c1 = 1;        // Enable tx
    u2tbl = cmd;    // Transmit data
    while( !ri_u2c1 );    // Wait for rx to be completed
    i = u2rbl;    // Copy received data to buffer
    re_u2c1 = 0;        // Disable rx
    te_u2c1 = 0;        // Disable tx
  return i;
}

unsigned int RD_MAX186(unsigned char cmd)
{
  unsigned char RB1,RB2,RB3=0;
  unsigned int AD_WERT=0;
  CS_MAX186 = 0;
  RB1=SPI_send_receive(cmd);    // Kanal Wahl
  CS_MAX186 = 1;
  while(!SSTRB);          // Warte bis Wandlung fertig
  CS_MAX186 = 0;
  RB2=SPI_send_receive(0x00);
  RB3=SPI_send_receive(0x00);
  CS_MAX186 = 1;
  AD_WERT=(RB2<<8)|RB3;
  AD_WERT>>=3;
  return AD_WERT;
}


Mfg Sascha

Autor: Torsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na dann hier auch mal mein code (für SIO3):

Init:
  // SIO 3 (SPI Interface)
  PRCR|= 0x01 | 0x02 | 0x04;  // disable write protection again
  S3C =  //1 |  //  f/8 as clock source
      2 |    //  f/32 as source
      //4 |   //  output is disabled
      8 |    //  Sout as Output , CLK function
      //16|   //  CLK polarity
      //32 |   //  transfer MSB first
      64 ;  //  use internal sync. clock

  // SPI Baudrate Divisor
  S3BRG= 0xFF;

  // S3 Interrupt Control Register
  S3IC = 0x00;  //INTERRUPTPRIO_SPI;

  //enable protection
  PRCR &= ~(0x01|0x02|0x04);

Und die Schreibfunktion

unsigned char SPI_WriteByte(unsigned char Byte)
{
  int timeout = MAX_SPI_WAIT_TOUT;
  S3IC &= ~0x08;
  S3TRR = Byte;
        do{__no_operation();}
  while((!(S3IC & 0x08)) && (timeout--));
  if(timeout<=0)
  return 0;
    else
  return S3TRR;

}

Autor: Til (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke erstmal!!

Ich hoffe das passt auch so für meinen M16C26, muss ich mal die SFRs
vergleichen.

Was ich beim M16C noch nicht ganz verstehe, normalerweise habe ich doch
bei SPI
MOSI
MISO
CS
CLK

macht der M16C das CS selbst oder muss ich da einen Portpin bedienen?

Autor: Til (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich muss dazu sagen, das ich auf den SPI Kram, der über die Uart2 Pins
läuft, festgelegt bin. D.h. für mein Verständnis:

Pin 70 MOSI
Pin 71 MISO
Pin 72 CS
Pin 73 CLK

im Manual finde ich nix zu SPI, ist dann der synchrone Serial Mode das
gleiche wie SPI?

Autor: Sascha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Til,

siehe doch mal oben in meinem Beispiel.

CS   = /CS = P73
MOSI = DIN = P70/TXD2  !Bei TXD2 unbedingt ext. PullUp!
MISO = DOUT = P71/RXD
SCLK =  SCLK = P72/CLK

P74 habe ich für den A/D MAX186 genutzt, ob festzustellen, ob Wandlung
fertig ist. SPI ist der synchrone Modus.

Mfg Sascha

Autor: Til (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, dann hab ich es doch richtig verstanden, bei mir funzt es halt noch
nicht, deshalb zweifel ich erstmal alles an und zu aller erst mein
Verständis ;-).

Autor: Sascha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Poste doch mal deinen Code.

Mfg Sascha

Autor: Til (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier mein Code:


/*********************************************************************** 
***********************************************************/
/*! @fn               void spi_init(void)
    @brief
    @param[in]
    @param[out]
    @param[in,out]
    @return
    @retval

    Diese Funktion

    @warning
    @sa
************************************************************************ 
***********************************************************/
void spi_init(void)
{
  M_DEBUG_PUTS("spi init\r\n");


  M_SET_MOSI_INPUT();
  M_SET_MISO_OUTPUT();
  M_SET_CS_INPUT();
  M_SET_CLK_INPUT();



  /* configure UART2 for SPI */
  U2C0   = 0x91;
  U2C1   = 0x00;      /* no data reverse, rx & tx disabled
*/
  U2BRG  = 5;         /* 2MHz SPI-CLK
*/
  U2C0  &= ~0x20;
  U2SMR3 &= ~0x01;
  U2MR   = 0x01;      /* synchronous mode, internal clock, no reverse
*/
}


/*********************************************************************** 
***********************************************************/
/*! @fn               void spi_init(void)
    @brief
    @param[in]
    @param[out]
    @param[in,out]
    @return
    @retval

    Diese Funktion

    @warning
    @sa
************************************************************************ 
***********************************************************/
u8_t _spiTxRx(u8_t ucCmd)
{
  u8_t i;

#if 0
  while( (U2C1 & 0x02) != 0x02 );         /* Ensure transmit buffer is
empty      */
    while( (U2C0 & 0x08) != 0x08 );       /* Ensure transmit register
is empty    */

  M_DEBUG_PUTS("buffer empty\r\n");

  i = U2RBL;                              /*   Read receive buffer to
empty it    */

  U2C1 |= 0x05;                           /* Enable Tx and Rx
          */

  M_DEBUG_PUTS("tx\r\n");

  U2TB = ucCmd;                           /* Transmit data
          */
#endif
  M_DEBUG_PUTS("wait for data\r\n");
  while( (U2C1 & 0x08) != 0x08 );         /* Wait for rx to be
completed          */
  M_DEBUG_PUTS("rx\r\n");

  i = U2RB;                               /* Copy received data to
buffer         */
  U2C1 &= ~0x05;                          /* Disable Tx and Rx
          */

  return (i);
}




Mein M16C soll als Slave arbeiten und Daten empfangen, die ein XScale
an Ihn sende. Mein XScale sendet die ganze Zeit Daten über SPI.

Autor: Til (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
U2MR   = 0x09;      /* synchronous mode, external clock, no reverse */

muss eher so sein, ich muss doch externe clock nehmen, also quasi das
CLK vom XScale, das dann über Pin23 reinkommt.

Autor: Sascha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was sind dies den für Funktionen?

" M_SET_MOSI_INPUT();
  M_SET_MISO_OUTPUT();
  M_SET_CS_INPUT();
  M_SET_CLK_INPUT(); "

Mfg Sascha

Autor: Til (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
/* Makros
************************************************************************ 
*************************************************/
#define M_SET_MOSI_INPUT()            P7D &= ~C_MOSI_PIN
#define M_SET_MOSI_OUTPUT()           P7D |= C_MOSI_PIN
#define M_SET_MISO_INPUT()            P7D &= ~C_MISO_PIN
#define M_SET_MISO_OUTPUT()           P7D |= C_MISO_PIN
#define M_SET_CS_INPUT()              P7D &= ~C_CS_PIN
#define M_SET_CS_OUTPUT()             P7D |= C_CS_PIN
#define M_SET_CLK_INPUT()             P7D &= ~C_CLK_PIN
#define M_SET_CLK_OUTPUT()            P7D |= C_CLK_PIN

#define M_SET_MOSI_HIGH()             P7 |= C_MOSI_PIN
#define M_SET_MOSI_LOW()              P7 &= ~C_MOSI_PIN
#define M_IS_MOSI_HIGH()              ((P7 & C_MOSI_PIN) ==
C_MOSI_PIN)
#define M_SET_MISO_HIGH()             P7 |= C_MISO_PIN
#define M_SET_MISO_LOW()              P7 &= ~C_MISO_PIN
#define M_IS_MISO_HIGH()              ((P7 & C_MISO_PIN) ==
C_MISO_PIN)
#define M_SET_CS_HIGH()               P7 |= C_CS_PIN
#define M_SET_CS_LOW()                P7 &= ~C_CS_PIN
#define M_SET_CLK_HIGH()              P7 |= C_CLK_PIN
#define M_SET_CLK_LOW()               P7 &= ~C_CLK_PIN

Autor: Til (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier noch mal mein aktueller Code:

void spi_init(void)
{
  M_DEBUG_PUTS("spi init\r\n");

  /* configure UART2 for SPI */
  U2C0    = 0x41;       /* rec data at falling edge, lsb first
  */
  U2C1    = 0x00;       /* no data reverse, rx & tx disabled
  */
  U2BRG   = 5;          /* 2MHz SPI-CLK
  */
  U2SMR3  &= ~0x02;
  U2MR    = 0x09;       /* synchronous mode, external clock, no reverse
  */
}

u8_t _spiTxRx(u8_t ucCmd)
{
  u8_t i;

  U2TB = 0x00;                            /* Write dummy Byte in TX
          */
  i = U2RBL;                              /* Read receive buffer to
empty it      */
  U2C1 |= 0x05;                           /* Enable Tx and Rx
          */

  M_DEBUG_PUTS("wait for data\r\n");
  while ( (U2C1 & 0x08) != 0x08 );        /* Wait for rx to be
completed          */

  i = U2RB;                               /* Copy received data to
buffer         */

  M_DEBUG_PUTS("rx=\r\n");
  M_DEBUG_PUTU32(i);
  M_DEBUG_PUTS("\r\n");

  U2C1 &= ~0x05;                          /* Disable Tx and Rx
          */

  return (i);
}

Autor: Sascha (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also als SPI-Master brauchst du solche Makro`s definitiv nicht. Ich
glaube auch nicht, das als Slave dies nötig ist.
Makro #define M_SET_CLK_INPUT()             P7D &= ~C_CLK_PIN
ist, sofern ich das Datenblatt verstehe, nötig. Was genau funktioniert
denn nicht? Wenn das empfangen geht, und das senden nicht, ext. PullUp
an P72 vergessen?

Mfg Sascha

Autor: Til (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ähmmm.... hab jetzt den Fehler gefunden... naja, wenn die Adressen im
SFR Header File nicht stimmen (bzw. für M16C26 nicht stimmen, die
Adressen im Header File waren für den 6N4), dann beschreibt man wohl
nicht so direkt die Register..... ;-)

Danke nochmal an alle!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.