微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > AVR单片机读PS2鼠标(贤集网刊)

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;  } }}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top