On Mar 2, 2011, at 9:39 AM, Cat C wrote:
>
> Hi,
>
> I have to systems that I need to talk to each other:
> 1. An ATMega644 that is the SPI Master, clocked at 20MHz, SPI clk =
> CLK/16 (under 2MHz).
> 2. An ATMega168 that is the SPI slave, clocked at 8MHz (internal RC).
>
> The setup of 2:
>
> void SPI_Init()
> {
> //Here we setup PortB to be our SLAVE SPI
> DDRB = 0
> // | _BV(PB0) //NC
> | _BV(PB1) //OC1A PWM Output
> // | _BV(PB2) //SS SPI Chip Select INPUT for Slave
> // | _BV(PB3) //MOSI - Slave Input
> | _BV(PB4) //MISO - Slave Output
> // | _BV(PB5) //SCK - Slave Clock Input
> // | _BV(PB6) //XTAL1
> // | _BV(PB7) //XTAL2
> ;
>
> //We may need to use interrupts so we may want to also set SPIE
> SPCR = 0b1100000;//(1<<SPE); //Enable SPI, Slave
> // |||||||\ - SPR0: SPI Clock Rate Select 1 and 0. No effect for SPI
> Slave
> // ||||||\- - SPR1: SPI Clock Rate Select 1 and 0. No effect for SPI
> Slave
> // |||||\-- - CPHA: Clock Phase: CPHA Leading Edge Trailing Edge
> // ||||\--- - CPOL: Clock Polarity: When CPOL == 0, SCK is LOW when
> idle
> // |||\---- - MSTR: Master/Slave Select: When MSTR == 0, chip is SLAVE
> // ||\----- - DORD: Data Order: When DORD == 0, MSB transmitted first.
> // |\------ - SPE: SPI Enable
> // \------- - SPIE: SPI Interrupt Enable
> }
>
> The ISR looks like this, to start with:
>
>
> volatile char vcSPI_Char;
> ISR(SPI_STC_vect) //SPI_STC_vect SIG_SPI
> {
> vcSPI_Char = SPDR;
> UDR0 = vcSPI_Char; //Send to serial port for debugging
> }
>
> I know interrupts are enabled because I have a timer interrupt that
> works fine.
> My "ISR(SPI_STC_vect)" never gets called, BUT checking "if (SPSR &
> _BV(SPIF))" in the main loop works (it's true when expected), so I
> have good reason to believe that the hardware is connected properly.
>
> I still have some ideas to try on this next part:
> Something else I must be doing wrong in the main loop: it appears
> that I'm not reading the data correctly from the SPI buffer because
> my if-else never match what I know I'm sending AND I can see on the
> scope that whatever was first sent by the master is sent back by the
> slave next time... what's wrong below, please?
> It's also possible the master-slave have different MSB-LSB settings
> (master settings are not easy to find) but I thought I tried all
> variations in slave to no avail...
>
>
>
> if (SPSR & _BV(SPIF)) //If we received an SPI byte
> {
> ui8TempSPDR = SPDR;
> UART_PutChar(ui8TempSPDR); //This displays sometimes * (00101010)
> that I might be due to MSB<->LSB
> if (ui8TempSPDR == 'T') //01010100
> SPDR = 4;//Sending back, to look nice on the scope
> else if (ui8TempSPDR == 'U')//01010101
> SPDR = 8;//Sending back, to look nice on the scope
> else
> SomethingElse = ui8TempSPDR;
> }
>
> Just in case one wonders, for testing purposes, this is what the
> master sends:
>
>
> SPI_SendTempControlData('T'); //For Requesting MSB of Value which
> will come next time
> _delay_ms(1000);
> SPI_SendTempControlData('U'); //For Requesting LSB of Value which
> will come next time
> ui16_8Value.ui8Temp[1] = SPDR;
> Utils_SendNumberStrToSerial
> (ui16_8Value.ui8Temp[1]);UART_PUTSTR_P("\t");
> _delay_ms(1000);
> SPI_SendTempControlData(25); //For Debugging
> ui16_8Value.ui8Temp[0] = SPDR;
> Utils_SendNumberStrToSerial(ui16_8Value.ui8Temp[0]);UART_PUTSTR_P("\r
> \n>");
> UART_PUTSTR_P("Value =
> ");Utils_SendFloatStrToSerial(ui16_8Value.ui16Temp);
>
> I would like to get the interrupt working, but failing that... why
> am I reading the wrong thing, why do the 'T' and 'U' never match?
> I think I can sort out this part, but the interrupt?
>
> Many thatks,
>
> Cat
>
> [Non-text portions of this message have been removed]
>
>
>
Just the obvious: I don't see a global interrupt enable!
Jim Wagner
Oregon Research Electronics
[Non-text portions of this message have been removed]Message
Re: [AVR-Chat] Can't get interrupt to work in SPI Slave mode. Sorry for the length.
2011-03-03 by Jim Wagner
Attachments
- No local attachments were found for this message.