AVR单片机读PS2鼠标(贤集网刊)
时间:10-02
整理:3721RD
点击:
#include#include
#include "myh.h"//MOUSE//时钟接CLK:5--INT0--PD2
#define PINMCLK (PIND&BIT2)
#define PRTMCLK_H {DDRD&=NBIT2;PORTD|=BIT2;}
#define PRTMCLK_L {DDRD|=BIT2;PORTD&=NBIT2;}//数据接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;}//数据接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) //延时 t*10us{ char i; for(;t>0;t--) for(i=10;i>0;i--);}uchar send2m(uchar dat)//高电平期间改变数据,下降沿发出去{ 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; //校验,出现奇数个一该位为0。 dat>>=1; } buf|=check<<8; //校验位 buf|=3<<9; //停止位,以及应答位// pclk=0;// pdat=0; PRTMCLK_L; PRTMDAT_L; //下接时钟和数据 delay(10);// pclk=1; //请求 PRTMCLK_H; //释放时钟线 for(i=0;i<11;i++) //发送8位数据 { while(PINMCLK); //等待下降沿 if(buf&0x01) PRTMDAT_H else PRTMDAT_L //pdat=buf&0x01; buf>>=1; //if(i==10)ack=pdat; //最后一位为输入的应答 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}, //要显示的四个数字 num[16]={0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X27,0X7F,0X6F, 0X77,0X7C,0X39,0X5E,0X79,0X71};//十六个数字的段码 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];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:2void int0_isr(void){ //external interupt on INT0 char i; uint buf;// EX0=0; PRTKCLK_L; //抑制键盘时钟 //PRTKDAT_L; //-while(1); buf=0; if(PINMDAT) { PORTC|=BIT0; delay(10); PORTC&=NBIT0; return; //启始位为0 } while(!PINMCLK); //等待启始位结束 for(i=0;i<10;i++) //8位数据+校验+停止,LSB在前 { while(PINMCLK);//下降沿接收数据 if(PINMDAT)buf|=(1< while(!PINMCLK); } mbuf[mcnt]=buf&0xff; wait=50; mcnt++; if(mcnt==3) chuli(); PRTKCLK_H; //允许键盘时钟 GIFR=0XC0; //向高两位写1,清中断标志 //IE0=0;}#pragma interrupt_handler int1_isr:3void int1_isr(void){ char i; uint buf; PRTMCLK_L; //抑制鼠标时钟 buf=0; if(PINKDAT) { PORTC|=BIT0; delay(10); PORTC&=NBIT0; return; //启始位为0 } while(!PINKCLK); //等待启始位结束 for(i=0;i<10;i++) //8位数据+校验+停止,LSB在前 { while(PINKCLK);//下降沿接收数据 if(PINKDAT)buf|=(1< while(!PINKCLK); } kbuf[kcnt]=buf&0xff; kcnt=0; PRTMCLK_H; //允许鼠标时钟 GIFR=0XC0; //向高两位写1,清中断标志}//call this routine to initialise all peripheralsvoid 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; } }}
#include "myh.h"//MOUSE//时钟接CLK:5--INT0--PD2
#define PINMCLK (PIND&BIT2)
#define PRTMCLK_H {DDRD&=NBIT2;PORTD|=BIT2;}
#define PRTMCLK_L {DDRD|=BIT2;PORTD&=NBIT2;}//数据接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;}//数据接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) //延时 t*10us{ char i; for(;t>0;t--) for(i=10;i>0;i--);}uchar send2m(uchar dat)//高电平期间改变数据,下降沿发出去{ 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; //校验,出现奇数个一该位为0。 dat>>=1; } buf|=check<<8; //校验位 buf|=3<<9; //停止位,以及应答位// pclk=0;// pdat=0; PRTMCLK_L; PRTMDAT_L; //下接时钟和数据 delay(10);// pclk=1; //请求 PRTMCLK_H; //释放时钟线 for(i=0;i<11;i++) //发送8位数据 { while(PINMCLK); //等待下降沿 if(buf&0x01) PRTMDAT_H else PRTMDAT_L //pdat=buf&0x01; buf>>=1; //if(i==10)ack=pdat; //最后一位为输入的应答 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}, //要显示的四个数字 num[16]={0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X27,0X7F,0X6F, 0X77,0X7C,0X39,0X5E,0X79,0X71};//十六个数字的段码 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];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:2void int0_isr(void){ //external interupt on INT0 char i; uint buf;// EX0=0; PRTKCLK_L; //抑制键盘时钟 //PRTKDAT_L; //-while(1); buf=0; if(PINMDAT) { PORTC|=BIT0; delay(10); PORTC&=NBIT0; return; //启始位为0 } while(!PINMCLK); //等待启始位结束 for(i=0;i<10;i++) //8位数据+校验+停止,LSB在前 { while(PINMCLK);//下降沿接收数据 if(PINMDAT)buf|=(1< while(!PINMCLK); } mbuf[mcnt]=buf&0xff; wait=50; mcnt++; if(mcnt==3) chuli(); PRTKCLK_H; //允许键盘时钟 GIFR=0XC0; //向高两位写1,清中断标志 //IE0=0;}#pragma interrupt_handler int1_isr:3void int1_isr(void){ char i; uint buf; PRTMCLK_L; //抑制鼠标时钟 buf=0; if(PINKDAT) { PORTC|=BIT0; delay(10); PORTC&=NBIT0; return; //启始位为0 } while(!PINKCLK); //等待启始位结束 for(i=0;i<10;i++) //8位数据+校验+停止,LSB在前 { while(PINKCLK);//下降沿接收数据 if(PINKDAT)buf|=(1< while(!PINKCLK); } kbuf[kcnt]=buf&0xff; kcnt=0; PRTMCLK_H; //允许鼠标时钟 GIFR=0XC0; //向高两位写1,清中断标志}//call this routine to initialise all peripheralsvoid 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; } }}