Hello,
I program SPI protocol for an MCU C8051F020 with Silicon Laboratories IDE. My problem is : the spi clock isn't generate and i don't see the signal clock on the scope. Here is my code :
//----------------------------------------------------------------------------- // Includes //----------------------------------------------------------------------------- #include "c8051f020.h" // SFR declarations #include "spi_defs.h" //----------------------------------------------------------------------------- // 16-bit SFR Definitions for 'F02x //----------------------------------------------------------------------------- sfr16 DP = 0x82; // data pointer sfr16 TMR3RL = 0x92; // Timer3 reload value sfr16 TMR3 = 0x94; // Timer3 counter sfr16 ADC0 = 0xbe; // ADC0 data sfr16 ADC0GT = 0xc4; // ADC0 greater than window sfr16 ADC0LT = 0xc6; // ADC0 less than window sfr16 RCAP2 = 0xca; // Timer2 capture/reload sfr16 T2 = 0xcc; // Timer2 sfr16 RCAP4 = 0xe4; // Timer4 capture/reload sfr16 T4 = 0xf4; // Timer4 sfr16 DAC0 = 0xd2; // DAC0 data sfr16 DAC1 = 0xd5; // DAC1 data //----------------------------------------------------------------------------- // Global CONSTANTS //----------------------------------------------------------------------------- #define SYSCLK 22118400 // SYSCLK frequency in Hz sbit LED = P1^6; // LED='1' means ON sbit SW1 = P3^7; // SW1='0' means switch pressed //----------------------------------------------------------------------------- // Function PROTOTYPES //----------------------------------------------------------------------------- void SYSCLK_Init (void); void PORT_Init (void); void SPI0_Init (void); void Timer0_ms (unsigned ms); void Timer0_us (unsigned us); //----------------------------------------------------------------------------- // Global VARIABLES //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // MAIN Routine //----------------------------------------------------------------------------- void main (void) { WDTCN = 0xde; // disable watchdog timer WDTCN = 0xad; SYSCLK_Init (); // initialize oscillator SPI0_Init; PORT_Init (); while (1){ Timer0_ms(500); LED=~LED; } } //----------------------------------------------------------------------------- // Initialization Subroutines //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // SYSCLK_Init //----------------------------------------------------------------------------- // // This routine initializes the system clock to use an 22.1184MHz crystal // as its clock source. // void SYSCLK_Init (void) { int i; // delay counter OSCXCN = 0x67; // start external oscillator with // 22.1184MHz crystal for (i=0; i < 256; i++) ; // XTLVLD blanking interval (>1ms) while (!(OSCXCN & 0x80)) ; // Wait for crystal osc. to settle OSCICN = 0x88; // select external oscillator as SYSCLK // source and enable missing clock // detector } //------------------------------------------------------------------------------------ // PORT_Init //------------------------------------------------------------------------------------ // // Configure the Crossbar and GPIO ports // //P0.4 - MOSI (push-pull) //P0.3 - MISO //P0.2 - SCK (push-pull) //P0.0 - UART TX (push-pull) //P0.1 - UART RX void PORT_Init (void) { XBR0 |= 0x06; //Enable UART pins and SPI0 pins XBR1 = 0x00; // System clock routed to port pin XBR2 = 0x40; // Enable crossbar and weak pull-ups P1MDOUT |= 0x40; // enable P1.6 (LED) as push-pull output P0MDOUT |= 0x15; // enable P0.2 (CLK) and P0.4 (CONV) as push-pull output // P0.3 (Data) as push-pull input and UART TX (push-pull) output } //----------------------------------------------------------------------------- // SPI0_Init //----------------------------------------------------------------------------- // // This routine initializes the system clock to use an 22.1184MHz crystal // as its clock source. // void SPI0_Init (void) { SPI0CFG = 0x07; //data sampled on 1st SCK rising edge //8-bit data words SPI0CN = 0x03; //Master mode ; SPI enabled; flags cleared SPI0CKR = 0x04; //SPI clock rate } //----------------------------------------------------------------------------- // Timer0_ms //----------------------------------------------------------------------------- // // Configure Timer0 to delay <ms> milliseconds before returning // void Timer0_ms (unsigned ms) { unsigned i; //millisecond counter TCON &= ~0x30; //STOP Timer0 and clear overflow flag TMOD &= ~0x0f; //configure Timer0 to 16-bit mode TMOD |= 0x01; CKCON |= 0x08; //Timer0 counts SYSCLKs for (i=0;i<ms; i++) { TR0 = 0; // STOP Timer0 TR0 =(-SYSCLK/1000)>>8; //set Timer0 to overflow in 1ms TL0 = -SYSCLK/1000; TR0 = 1; //START Timer0 while (TF0 == 0); //wait for overflow indicator TF0 = 0 ; //clear overflow indicator } } //----------------------------------------------------------------------------- // Timer0_us //----------------------------------------------------------------------------- // // Configure Timer0 to delay <us> milliseconds before returning // void Timer0_us (unsigned us) { unsigned i; //millisecond counter TCON &= ~0x30; //STOP Timer0 and clear overflow flag TMOD &= ~0x0f; //configure Timer0 to 16-bit mode TMOD |= 0x01; CKCON |= 0x08; //Timer0 counts SYSCLKs for (i=0;i<us; i++) { TR0 = 0; // STOP Timer0 TR0 =(-SYSCLK/1000000)>>8; //set Timer0 to overflow in 1ms TL0 = -SYSCLK/1000000; TR0 = 1; //START Timer0 while (TF0 == 0); //wait for overflow indicator TF0 = 0 ; //clear overflow indicator } }
Can you help me ?
Thanks
Regards
I don't know your chip and don't have the time to retrieve the datasheet for it.
But how do you know that XBR0 |= 0x06; really do enable UART pins and SPI0 pins?
All you do is to set two bits - all other bits are left at their original values. Are these two bits the only changes needed relative the reset defaults of your processor?
Yes i need to configure UART0.
rgds
i make somme modifications in my code but i don't work.
//----------------------------------------------------------------------------- // Includes //----------------------------------------------------------------------------- #include "c8051f020.h" // SFR declarations #include "spi_defs.h" //----------------------------------------------------------------------------- // 16-bit SFR Definitions for 'F02x //----------------------------------------------------------------------------- sfr16 DP = 0x82; // data pointer sfr16 TMR3RL = 0x92; // Timer3 reload value sfr16 TMR3 = 0x94; // Timer3 counter sfr16 ADC0 = 0xbe; // ADC0 data sfr16 ADC0GT = 0xc4; // ADC0 greater than window sfr16 ADC0LT = 0xc6; // ADC0 less than window sfr16 RCAP2 = 0xca; // Timer2 capture/reload sfr16 T2 = 0xcc; // Timer2 sfr16 RCAP4 = 0xe4; // Timer4 capture/reload sfr16 T4 = 0xf4; // Timer4 sfr16 DAC0 = 0xd2; // DAC0 data sfr16 DAC1 = 0xd5; // DAC1 data //----------------------------------------------------------------------------- // Global CONSTANTS //----------------------------------------------------------------------------- #define SYSCLK 22118400 // SYSCLK frequency in Hz sbit LED = P1^6; // LED='1' means ON sbit SW1 = P3^7; // SW1='0' means switch pressed //----------------------------------------------------------------------------- // Function PROTOTYPES //----------------------------------------------------------------------------- void SYSCLK_Init (void); void PORT_Init (void); void SPI0_Init (void); void Timer0_ms (unsigned ms); void Timer0_us (unsigned us); //----------------------------------------------------------------------------- // Global VARIABLES //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // MAIN Routine //----------------------------------------------------------------------------- void main (void) { WDTCN = 0xde; // disable watchdog timer WDTCN = 0xad; SYSCLK_Init (); // initialize oscillator SPI0_Init; PORT_Init (); while (1){ Timer0_ms(500); LED=~LED; } } //----------------------------------------------------------------------------- // Initialization Subroutines //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // SYSCLK_Init //----------------------------------------------------------------------------- // // This routine initializes the system clock to use an 22.1184MHz crystal // as its clock source. // void SYSCLK_Init (void) { int i; // delay counter OSCXCN = 0x67; // start external oscillator with // 22.1184MHz crystal for (i=0; i < 256; i++) ; // XTLVLD blanking interval (>1ms) while (!(OSCXCN & 0x80)) ; // Wait for crystal osc. to settle OSCICN = 0x88; // select external oscillator as SYSCLK // source and enable missing clock // detector } //------------------------------------------------------------------------------------ // PORT_Init //------------------------------------------------------------------------------------ // // Configure the Crossbar and GPIO ports // //P0.4 - MOSI (push-pull) //P0.3 - MISO //P0.2 - SCK (push-pull) //P0.0 - UART TX (push-pull) //P0.1 - UART RX void PORT_Init (void) { XBR0 = 0x06; //Enable UART pins and SPI0 pins XBR1 = 0x00; // System clock routed to port pin XBR2 = 0x40; // Enable crossbar and weak pull-ups P1MDOUT = 0x40; // enable P1.6 (LED) as push-pull output P0MDOUT = 0x15; // enable P0.2 (CLK) and P0.4 (CONV) as push-pull output // P0.3 (Data) as push-pull input and UART TX (push-pull) output } //----------------------------------------------------------------------------- // SPI0_Init //----------------------------------------------------------------------------- // // This routine initializes the system clock to use an 22.1184MHz crystal // as its clock source. // void SPI0_Init (void) { SPI0CFG = 0x07; //data sampled on 1st SCK rising edge //8-bit data words SPI0CN = 0x03; //Master mode ; SPI enabled; flags cleared SPI0CKR = 0x04; //SPI clock rate } //----------------------------------------------------------------------------- // Timer0_ms //----------------------------------------------------------------------------- // // Configure Timer0 to delay <ms> milliseconds before returning // void Timer0_ms (unsigned ms) { unsigned i; //millisecond counter TCON &= ~0x30; //STOP Timer0 and clear overflow flag TMOD &= ~0x0f; //configure Timer0 to 16-bit mode TMOD |= 0x01; CKCON |= 0x08; //Timer0 counts SYSCLKs for (i=0;i<ms; i++) { TR0 = 0; // STOP Timer0 TR0 =(-SYSCLK/1000)>>8; //set Timer0 to overflow in 1ms TL0 = -SYSCLK/1000; TR0 = 1; //START Timer0 while (TF0 == 0); //wait for overflow indicator TF0 = 0 ; //clear overflow indicator } } //----------------------------------------------------------------------------- // Timer0_us //----------------------------------------------------------------------------- // // Configure Timer0 to delay <us> milliseconds before returning // void Timer0_us (unsigned us) { unsigned i; //millisecond counter TCON &= ~0x30; //STOP Timer0 and clear overflow flag TMOD &= ~0x0f; //configure Timer0 to 16-bit mode TMOD |= 0x01; CKCON |= 0x08; //Timer0 counts SYSCLKs for (i=0;i<us; i++) { TR0 = 0; // STOP Timer0 TR0 =(-SYSCLK/1000000)>>8; //set Timer0 to overflow in 1ms TL0 = -SYSCLK/1000000; TR0 = 1; //START Timer0 while (TF0 == 0); //wait for overflow indicator TF0 = 0 ; //clear overflow indicator } }
"My problem is : the spi clock isn't generate and i don't see the signal clock on the scope."
Of course, you don't see it. You fail even to initialize SPI.
void main (void) { ... SYSCLK_Init (); // initialize oscillator SPI0_Init; // <---- what's this? function pointer? ... }
Even if you would initialize SPI successfully, you don't see any output until you put data to SPI0DAT.
Tsuneo
yes. it's work.
i see the error in SPI0_Init; ==> SPI0_Init(); And i finally understood : "you don't see any output until you put data to SPI0DAT." I solved my problem before to read the message of Tsuneo Chinzei.