atmega as both master and slave spi

Discussion in 'Embedded Systems and Microcontrollers' started by meiya777, May 3, 2010.

  1. meiya777

    Thread Starter New Member

    Jun 28, 2008
    3
    0
    I have atmega8 that controls MAX541 for DAC, but it (atmega8) is also one of the slave for atmega128.

    The easy part is that it will ONLY become master (to drive MAX541) if there's a data received from atmega128. In other word, it is a slave when receiving data from atmega128, and it will then become master to drive MAX541.

    For the MAX541, the pins connetion will be SS, SCK, and MOSI.

    My problems:
    1. What are the pin connections atmega8 to atmega128?
    2. The following code is to drive the MAX541, how to receive the data from atmega128? Can I just simply use SPI interrupt, and run the codes IN THE BODY of SPI interrupt?


    #define CS PORTB.2
    #define SCK PORTB.5
    #define DLY 20

    unsigned char Set_DAC(unsigned char dath, unsigned char datl)
    {
    CS = 0;
    delay_us(DLY);

    //16
    SCK = 0;
    CMD = dath&0x80;
    delay_us(DLY);
    SCK = 1;
    delay_us(DLY);

    //15
    SCK = 0;
    CMD = dath&0x40;
    delay_us(DLY);
    SCK = 1;
    delay_us(DLY);

    //14
    SCK = 0;
    CMD = dath&0x20;
    delay_us(DLY);
    SCK = 1;
    delay_us(DLY);

    //13
    SCK = 0;
    CMD = dath&0x10;
    delay_us(DLY);
    SCK = 1;
    delay_us(DLY);

    //12
    SCK = 0;
    CMD = dath&0x08;
    delay_us(DLY);
    SCK = 1;
    delay_us(DLY);

    //11
    SCK = 0;
    CMD = dath&0x04;
    delay_us(DLY);
    SCK = 1;
    delay_us(DLY);

    //10
    SCK = 0;
    CMD = dath&0x02;
    delay_us(DLY);
    SCK = 1;
    delay_us(DLY);

    //9
    SCK = 0;
    CMD = dath&0x01;
    delay_us(DLY);
    SCK = 1;
    delay_us(DLY);

    //8
    SCK = 0;
    CMD = datl&0x80;
    delay_us(DLY);
    SCK = 1;
    delay_us(DLY);

    //7
    SCK = 0;
    CMD = datl&0x40;
    delay_us(DLY);
    SCK = 1;
    delay_us(DLY);

    //6
    SCK = 0;
    CMD = datl&0x20;
    delay_us(DLY);
    SCK = 1;
    delay_us(DLY);

    //5
    SCK = 0;
    CMD = datl&0x10;
    delay_us(DLY);
    SCK = 1;
    delay_us(DLY);

    //4
    SCK = 0;
    CMD = datl&0x08;
    delay_us(DLY);
    SCK = 1;
    delay_us(DLY);

    //3
    SCK = 0;
    CMD = datl&0x04;
    delay_us(DLY);
    SCK = 1;
    delay_us(DLY);

    //2
    SCK = 0;
    CMD = datl&0x02;
    delay_us(DLY);
    SCK = 1;
    delay_us(DLY);

    //1
    SCK = 0;
    CMD = datl&0x01;
    delay_us(DLY);
    SCK = 1;
    delay_us(DLY);

    CS=1;
    delay_us(100);
    return 0;
    }

    Thanks.
     
  2. rjenkins

    AAC Fanatic!

    Nov 6, 2005
    1,015
    69
    It looks like you are doing the SPI interface purely in software rather than using any SPI hardware, so why not use different pins for the master & slave sides?

    Or, if that device has SPI hardware, use that for the command side and talk to the DAC on other i/o pins.

    You should not really run any time-consuming routines within an interrupt.
    Preferably, store the received data in a buffer and set a bit to tell your main routine that it has new data to process.
     
Loading...