您的位置 首页 IOT

AVR单片机读PS2鼠标

如果该程序已验证过的,用的是AVR系列单片机的IO口模拟PS2协议。includeiom8vh>includemacrosh>includemyhhMOUSE

假如该程序已验证过的,用的是AVR系列单片机的IO口模仿PS2协议。

#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:2
void 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:3
void 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 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;
}
}
}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/yingyong/iot/259909.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部