Fork me on GitHub

02/04/14

PIC: Mouse PS2

PIC: Mouse PS/2



Olá! Neste post mostrarei como conectar um mouse via PS/2.

A interface de mouse PS/2 utiliza um protocolo serial bidirecional para transmitir dados de movimento e botão de estado para controlador de dispositivo auxiliar( Computador ou até mesmo o PIC! ). O controlador, por sua vez, pode enviar uma série de comandos para o mouse para definir a taxa, a resolução, redefinir o mouse, desativar o mouse, etc.



MODOS DE OPERAÇÃO

A transmissão dos dados é tratado de acordo com o modo em que o mouse está operando. Existem quatro modos de operação:
  • Reset( 0xFF ) - O modo inicial, em que o mouse faz a inicialização e auto-diagnóstico.
  • Stream( 0xEA ) - O modo de operação padrão, na qual os pacotes de dados de movimento são enviados quando ocorre movimentos ou mudanças de estado dos botão.
  • Remoto( 0xF0 ) - O host deve requisita pacotes de dados de movimento.
  • Wrap( 0xEE ) - Um modo puramente de diagnóstico onde o mouse ecoa cada pacote recebido de volta para o host.


Veja mais detalhes e a lista completa de comandos aqui.

BIBLIOTECA - PS2
MikroC PRO PIC
/*
   Autor: Tiago Henrique
*/

#define Clock_Enable() PS2_Clk_Direction = 1
#define Clock_Disable() PS2_Clk_Direction = 0; PS2_Clk = 0
 
extern sfr sbit PS2_Clk;
extern sfr sbit PS2_Data;
extern sfr sbit PS2_Clk_Direction;
extern sfr sbit PS2_Data_Direction;

void PS2_Init()
{
 PS2_Data_Direction = 0;
 PS2_Clk_Direction = 0;
 Delay_us(2);
 PS2_Data_Direction = 1;
 PS2_Clk_Direction = 1;
 Delay_us(2);
}

void PS2_Write( char _data )
{
char i, parity = 1;

 Clock_Disable();
 Delay_us( 200 );
 PS2_Data = 0;
 PS2_Data_Direction = 0;
 Delay_us( 10 );
 Clock_Enable();
 Delay_us(2);
 
 while( PS2_Clk );
 
 for( i = 0; i <= 8; i++ )
 {
  if( i < 8 )
  {
   PS2_Data = _data.B0;
   parity ^= _data;
   _data >>= 1;
  }
  else
  {
   PS2_Data = parity.B0;
  }
  
  while( !PS2_Clk );
  while( PS2_Clk );  
 } 
  
 PS2_Data = 1;
 PS2_Data_Direction = 1;
 
 while( !PS2_Clk );
 while( PS2_Clk );
  
 while( PS2_Clk );
 while( !PS2_Clk || !PS2_Data );
  
 PS2_Data_Direction = 1;
 PS2_Data = 1;
 Clock_Enable();
 Delay_us(2);
 Clock_Disable();
 Delay_us(2); 
}

char PS2_Read()
{
char _data = 0;
char i;
unsigned timeOut = 1000;

 Clock_Enable();
 Delay_us(2);
 
 while( PS2_Clk && --timeOut )
     Delay_us(1);
  
 if( timeOut == 0 )
  goto Sair;
  
 while( PS2_Clk );
 
 for( i = 0; i < 11; i++ )
 {
  timeOut = 2000;
  while( PS2_Clk && --timeOut )
      Delay_us(1);
  
  if( timeOut == 0 )
   goto Sair;
  
  Delay_us(10);
  
  if( i > 0 && i < 9 )
  {
      _data >>= 1;
      _data.B7 = PS2_Data;
  }
  while( !PS2_Clk );  
 }

Sair: 
 Clock_Disable();
 return(_data);
}

BIBIOTECA - MOUSE
/*
  Autor: Tiago Henrique
*/
typedef struct
{
 union
 {
  char L:1;//botao esquerdo
  char R:1;//botao direito
  char M:1;//botao do meio
  char:1;
  char XS:1;//sinal negativo para eixo X
  char YS:1;//sinal negativo para eixo Y
  char Buttons;
 };
 char XAxis;
 char YAxis;
 char ZAxis;
}MousePS2;

void Mouse_Init()
{
 PS2_Write( 0xFF ); //Reset
 PS2_Read(); //Acknowledge
 PS2_Read(); //Self-test passed
 PS2_Read(); //Mouse ID
 PS2_Write( 0x0F ); //Remote Mode
 PS2_Read(); //Acknowledge
}

void Mouse_Read( MousePS2 *mouse )
{
 PS2_Write( 0xeb );
 PS2_Read(); //Acknowledge
 mouse->Buttons = PS2_Read();
 mouse->XAxis = PS2_Read();
 mouse->YAxis = PS2_Read();
}

EXEMPLO:
//copiar e colar a biblioteca PS2 aqui!!!
//copiar e colar a biblioteca MOUSE aqui!!!

sbit PS2_Clk at RD6_Bit;
sbit PS2_Data at RD5_Bit;
sbit PS2_Clk_Direction at TRISD6_Bit;
sbit PS2_Data_Direction at TRISD5_Bit;

MousePS2 mouse;

void main()
{
    ADCON1 = 15;
    TRISA = 0;
    PORTA = 0;
    
    PS2_Init();
    Mouse_Init();

    mouse.Buttons = 0;
    
    while(1)
    {
        Mouse_Read( &mouse );

        //acende um led por exemplo
        PORTA.B4 = mouse.L; //indicador do botao direito
        PORTA.B5 = mouse.R; //indicador do botao esquerdo

        Delay_ms( 200 );
    }

}

6 comentários:

Postagens Relacionadas!!