Mikrocontroller und Digitale Elektronik
›
Thread
M16C SPI
T
Til
Gast
25.10.2005 10:20
#254718
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.
S
Sascha
Gast
25.10.2005 11:39
#254719
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
T
Torsten
Gast
25.10.2005 12:42
#254720
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;
}
T
Til
Gast
25.10.2005 13:14
#254721
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?
T
Til
Gast
25.10.2005 13:18
#254722
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?
S
Sascha
Gast
25.10.2005 13:51
#254723
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
T
Til
Gast
25.10.2005 14:04
#254724
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 ;-).
S
Sascha
Gast
25.10.2005 14:12
#254725
Poste doch mal deinen Code.
Mfg Sascha
T
Til
Gast
25.10.2005 14:48
#254726
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.
T
Til
Gast
25.10.2005 14:51
#254727
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.
S
Sascha
Gast
25.10.2005 16:53
#254728
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
T
Til
Gast
25.10.2005 17:02
#254729
/* 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
T
Til
Gast
25.10.2005 17:06
#254730
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);
}
S
Sascha
Gast
25.10.2005 17:16
#254731
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
T
Til
Gast
26.10.2005 09:44
#254732
Ä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!
↑ Nach oben
← Zurück zu Mikrocontroller und Digitale Elektronik
Antwort schreiben