#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[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: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; } }}
导读:目前正在解读《AVR单片机读PS2鼠标》的相关信息,《AVR单片机读PS2鼠标》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《AVR单片机读PS2鼠标》的详细说明。
简介:本文给大家分享了一个AVR单片机读PS2鼠标代码。
提醒:《AVR单片机读PS2鼠标》最后刷新时间 2024-03-14 00:57:42,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《AVR单片机读PS2鼠标》该内容的真实性请自行鉴别。