0

PS2ジョイスティックをマイクロコントローラーSPIを備えたavr Atmega 640とインターフェースしようとしています。インターネットで利用可能なビットバンには多くのコードがありますが、AVRでPS2とSPIをインターフェースしたいです。ボタンが押されると、対応する LED がオフではなく点滅を開始します。

#include<avr/io.h>
#include<avr/interrupt.h>
#include<util/delay.h>

#define MISO 3   //data
#define MOSI 2   //cmnd 
#define SCK  1   //clock
#define SS   0   //attention






//--------------------------------** SPI **-------------------------------------------------------------------------
void SPI_int_MSTR()
{

 SPCR=(1<<SPE)|(1<<DORD)|(1<<MSTR)|(1<<CPOL)|(1<<CPHA)|(1<<SPR1)|(1<<SPR0); //interupt enable,spi enable,LSB first,master ,Fosc/128=115200hz  
 //SPSR=(1<<SPI2X);     // not working at Fosc/64

 DDRB=(1<<MOSI)|(1<<SCK)|(1<<SS);            // mosi,sck,ant-output
 DDRB&=~(1<<MISO);
 //PORTB|=(1<<MISO);                            //ENABLE internal pull-up
 PORTB|=(1<<SS);
}

unsigned char sendTo_slave(unsigned char cmd)
{
  unsigned char data; 

  SPDR=cmd;
  while(!(SPSR & (1<<SPIF)));

  _delay_us(170);  // 170-best
  data=SPDR;

  //_delay_us(40);
  return(data);

}

//---------------------------** PS2 CONTROLLER **------------------------------------------------------------------------

 void int_inanalogue()
{ 
       // this loop continues to put PSx controller into analouge mode untill the 
       // controller responds with 0x73 in the 2nd byte.  
       // (PS2 controller responds with 0x73 when in analouge mode.)
       // the status LEDs will continue to count upwards untill a controller is found.
       // if everything is working correctly this should happen on the first pass of 
       // this loop but occasionally errors occur and a 2nd or 3rd itteration happen.

//lcd_string("0");
unsigned char chk_ana = 0,cnt = 0;;

    while(chk_ana != 0x73)
    { 
        //put controller in config mode-43

         PORTB&=~(1<<SS);
           sendTo_slave(0x01);
           sendTo_slave(0x43);
           sendTo_slave(0x00);
           sendTo_slave(0x01); //enter confi
           sendTo_slave(0x00);
         _delay_us(1); 
         PORTB|=(1<<SS);
        _delay_us(10);




        // put controller in analouge mode-44
         PORTB&=~(1<<SS);
           sendTo_slave(0x01);
           sendTo_slave(0x44);  // for seting mode
           sendTo_slave(0x00);

           sendTo_slave(0x01);  // for anlogue mode-0x01 ,digital=0x00
           sendTo_slave(0x03);  // lock the controller ,otherwise the user can change from analog to digital mode using the analog button on the controller.
           sendTo_slave(0x00);
           sendTo_slave(0x00);
           sendTo_slave(0x00);
           sendTo_slave(0x00);
         _delay_us(1);
          PORTB|=(1<<SS);
         _delay_us(10);




                // 0x4F Config controller to return all pressure values

              /*   PORTB&=~(1<<SS);
                   sendTo_slave(0x01);
                   sendTo_slave(0x4F);
                   sendTo_slave(0x00);

                   sendTo_slave(0xFF);  //exit confi
                   sendTo_slave(0xFF);
                   sendTo_slave(0x03);
                   sendTo_slave(0x00);
                   sendTo_slave(0x00);
                   sendTo_slave(0x00);
                  PORTB|=(1<<SS);
                 _delay_us(20);  */  


       // exit config mode-4
          PORTB&=~(1<<SS);   
           sendTo_slave(0x01);
           sendTo_slave(0x43);
           sendTo_slave(0x00);

           sendTo_slave(0x00);  //exit confi
           sendTo_slave(0x5A);
           sendTo_slave(0x5A);
           sendTo_slave(0x5A);
           sendTo_slave(0x5A);
           sendTo_slave(0x5A);
         _delay_us(1);
         PORTB|=(1<<SS);
         _delay_us(10);



    // poll controller and check in analouge mode
          PORTB&=~(1<<SS);   
           sendTo_slave(0x01);
           chk_ana=sendTo_slave(0x42);  // the 2nd byte to be returned from the controller should = 0x73 for "red" analouge controller.
           sendTo_slave(0x00);
           sendTo_slave(0x00);
           sendTo_slave(0x00);
           sendTo_slave(0x00);
           sendTo_slave(0x00);
           sendTo_slave(0x00);

         _delay_us(1);
         PORTB|=(1<<SS);
         _delay_us(10);

        PORTC=cnt++;                     
        if (cnt > 254){ cnt=0;}
     }
}


//-----------------------------------------For Analogue-------------------------------------------------------------------

int main (void)
{

 SPI_int_MSTR();
 sei();
 DDRC=0XFF;
 int_inanalogue();

 unsigned char data0, data1, data2, data3, data4, data5,temp;

 while(1)
  {
        PORTB&=~(1<<SS);

        sendTo_slave(0x01);                              // byte 0. header.
        temp = sendTo_slave(0x42);                       // byte 1. header. (should possibly put test on this byte to detect unplugging of controller.)
        sendTo_slave(0x00);                              // byte 2. header.

        data0 = sendTo_slave(0x00);                         // byte 3. first data bite.
        data1 = sendTo_slave(0x00);                         // byte 4.
        data2 = sendTo_slave(0x00);                         // byte 5.
        data3 = sendTo_slave(0x00);                         // byte 6.
        data4 = sendTo_slave(0x00);                         // byte 7.
        data5 = sendTo_slave(0x00);                         // byte 8.

        PORTB|=(1<<SS);
        PORTC=data1;   
  }

}

友達あなたの助けは非常に高く評価されます

4

0 に答える 0