如果該程序已驗(yàn)證過的,用的是AVR系列單片機(jī)的IO口模擬PS2協(xié)議。#include
本文引用地址:http://m.butianyuan.cn/article/201611/320643.htm#include
#include "myh.h"
//MOUSE
//時(shí)鐘接CLK:5--INT0--PD2
#define PINMCLK (PIND&BIT2)
#define PRTMCLK_H {DDRD&=NBIT2;PORTD|=BIT2;}
#define PRTMCLK_L {DDRD|=BIT2;PORTD&=NBIT2;}
//數(shù)據(jù)接DAT:1--PC4
#define PINMDAT (PINC&BIT4)
#define PRTMDAT_H {DDRC&=NBIT4;PORTC|=BIT4;}
#define PRTMDAT_L {DDRC|=BIT4;PORTC&=NBIT4;}
//KEYBOARD
#define PINKCLK (PIND&BIT3)
#define PRTKCLK_H {DDRD&=NBIT3;PORTD|=BIT3;}
#define PRTKCLK_L {DDRD|=BIT3;PORTD&=NBIT3;}
//數(shù)據(jù)接DAT:1--PC4
#define PINKDAT (PINC&BIT5)
#define PRTKDAT_H {DDRC&=NBIT5;PORTC|=BIT5;}
#define PRTKDAT_L {DDRC|=BIT5;PORTC&=NBIT5;}
//sbit pclk=P3^2;
//sbit pdat=P3^1;
uchar wait;
uchar mcnt=0;
uchar kcnt=0;
schar axes_x=0,axes_y=0;
schar mbuf[4];
uchar kbuf[4];
void delay(uint t)//延時(shí) t*10us
{
char i;
for(;t>0;t--)
for(i=10;i>0;i--);
}
uchar send2m(uchar dat)//高電平期間改變數(shù)據(jù),下降沿發(fā)出去
{
uchar i,ack,intc,check=1;
uint buf;
//EX0=0;
//IE0=0;
intc=GICR;
GICR&=0x3f; //不使能中斷
buf=dat;
for(i=0;i<8;i++)
{
check^=dat&0x01; //校驗(yàn),出現(xiàn)奇數(shù)個(gè)一該位為0。
dat>>=1;
}
buf|=check<<8; //校驗(yàn)位
buf|=3<<9; //停止位,以及應(yīng)答位
// pclk=0;
// pdat=0;
PRTMCLK_L;
PRTMDAT_L; //下接時(shí)鐘和數(shù)據(jù)
delay(10);
// pclk=1;//請(qǐng)求
PRTMCLK_H;//釋放時(shí)鐘線
for(i=0;i<11;i++)//發(fā)送8位數(shù)據(jù)
{
while(PINMCLK);//等待下降沿
if(buf&0x01)
PRTMDAT_H
else
PRTMDAT_L
//pdat=buf&0x01;
buf>>=1;
//if(i==10)ack=pdat;//最后一位為輸入的應(yīng)答
if(i==10)ack=PINMDAT;
//while(!pclk);
while(!PINMCLK);//等待上升沿
}
PRTMDAT_H;
//EX0=1;
GICR=intc;
return ack;
}
void chuli(void)
{
mcnt=0;
axes_x+=(schar)mbuf[1];
axes_y+=(schar)mbuf[2];
}
void display(uint number)//從0到F顯示
{
char i,n[4]={0}, //要顯示的四個(gè)數(shù)字
num[16]={0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X27,0X7F,0X6F,
0X77,0X7C,0X39,0X5E,0X79,0X71};//十六個(gè)數(shù)字的段碼
n[0]=number>>12&0X0F;
n[1]=number>>8 &0X0F;
n[2]=number>>4 &0X0F;
n[3]=number &0X0F;
for(i=0;i<4;i++)
{
PORTD=~(0X80>>i);
PORTB=num[n[i]];delay(500);
PORTB=0x00; //顯示清空
}
}
void port_init(void)
{
DDRB = 0xFF;//B用于顯示
PORTB = 0xFF;
DDRC = 0x0F;//PC4,PC5為輸入
PORTC = 0x7F; //m103 output only
DDRD = 0xF0; //INT0 INT1 為輸入
PORTD = 0xFF;
}
#pragma interrupt_handler int0_isr:2
void int0_isr(void)
{
//external interupt on INT0
char i;
uint buf;
// EX0=0;
PRTKCLK_L; //抑制鍵盤時(shí)鐘
//PRTKDAT_L;
//-while(1);
buf=0;
if(PINMDAT)
{
PORTC|=BIT0;
delay(10);
PORTC&=NBIT0;
return; //啟始位為0
}
while(!PINMCLK); //等待啟始位結(jié)束
for(i=0;i<10;i++)//8位數(shù)據(jù)+校驗(yàn)+停止,LSB在前
{
while(PINMCLK);//下降沿接收數(shù)據(jù)
if(PINMDAT)buf|=(1< while(!PINMCLK);
}
mbuf[mcnt]=buf&0xff;
wait=50;
mcnt++;
if(mcnt==3)
chuli();
PRTKCLK_H; //允許鍵盤時(shí)鐘
GIFR=0XC0; //向高兩位寫1,清中斷標(biāo)志
//IE0=0;
}
#pragma interrupt_handler int1_isr:3
void int1_isr(void)
{
char i;
uint buf;
PRTMCLK_L; //抑制鼠標(biāo)時(shí)鐘
buf=0;
if(PINKDAT)
{
PORTC|=BIT0;
delay(10);
PORTC&=NBIT0;
return; //啟始位為0
}
while(!PINKCLK); //等待啟始位結(jié)束
for(i=0;i<10;i++)//8位數(shù)據(jù)+校驗(yàn)+停止,LSB在前
{
while(PINKCLK);//下降沿接收數(shù)據(jù)
if(PINKDAT)buf|=(1< while(!PINKCLK);
}
kbuf[kcnt]=buf&0xff;
kcnt=0;
PRTMCLK_H; //允許鼠標(biāo)時(shí)鐘
GIFR=0XC0; //向高兩位寫1,清中斷標(biāo)志
}
//call this routine to initialise all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
MCUCR = 0x0A;//1010,int0,int1 下降沿
GICR = 0xC0; //int1,int0 enable
TIMSK = 0x00; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialised
}
void main()
{
uint dat;
init_devices();
send2m(0xff);
delay(10);
send2m(0xeb);
while(1)
{
//dat=axes_x<<8|axes_y;
dat=axes_x<<8|kbuf[0];
display(dat);
//display(kbuf[0]);
if(wait)
{
wait--;
if(wait==0)
mcnt=0;
}
}
}
評(píng)論