用单片机pic16f877a实现鼠标数据的采集
现在继续写下去 !!!!!!尽管和比赛没有关系了
一、先要熟悉鼠标的协议和接口
下面是PS2的接口
:
这是鼠标在传输过程中数据的一个帧:
一个开始位:(为0)
八个数据位:
一个奇校验位:
一个停止位:(它总是1)
鼠标和单片机通信:
1、单片机给鼠标发命令是按下面的格式进行的:
(注意:一个应答信号的接收)
这是它的详细过程:
2、鼠标向单片机传送数据是下面的格式:
二、下面就是设计鼠标和单片机的通信电路:(可以参考下面这个接法)
(注意:数据和时钟都这是集电极开路的结构,平时是高电平 )
三、外围布置好了就是具体程序的实现
我们可以采用单片机16F877A的外部中断来响应鼠标的时钟,在中断中接收数据。
我 们可按下面的步骤实现:
1)把时钟线拉低至少100微秒
2)把数据线拉低
3)释放数据线
4)等待设备把时钟线拉低
5)设置/复位数据线发送第一个数据位
6)等待设备把时钟拉高
7)等待设备把时钟拉低
8)重复5-7步发送剩下的7个数据位和校验位
9)释放数据线
10)等待设备把数据线拉低
11)等待设备把时钟线拉低
12)等待设备释放数据线和时钟线
程序如下:
//外部中断INT0初始化
void INTE_init(void)
{
INTCON=0X00;
GIE=1; //总中断
RBPU=0;
//INTE=1;//外部中断
//INTEDG=0;//下升沿触发有效
INTEDG=1;//上升沿触发有效
TRISB=0x00;//正常工作下时钟RB0和数据RB2均输入
INTF=0;//这三句是开外部中断
PORTB=0X00;
}
//发送数据
//发送11位数据:1START-8DA
//并接收一个应答位ack = 0
void mouse_write_dat(unsigned char dat)
{
unsigned char i; //循环变量
INTE = 0; //关闭外部中断
asm( "nop");
mouse_clk = 0; //拉低时钟线
delay(33); //至少延时100us
mouse_sda = 0; //发送起始位
mouse_clk = 1; //释放时钟线
mouse_sda = 1; //释放数据线
TRISB0=1;//时钟输入
asm( "nop");
TRISB=0X01;
for(i = 0; i < 8; i++)
{ //至少要在25us内完成发送一位
while(!mouse_clk); //等待设备把时钟线拉高
mouse_sda =(bit)(dat& 0x01);//先发送最低位
dat >>= 1; //下降沿写入数据
while(mouse_clk); //等待设备把时钟线拉低
}
while(!mouse_clk); //等待设备把时钟线拉高
mouse_sda = 0; //发送奇校验位
while(mouse_clk); //等待设备把时钟线拉低
while(!mouse_clk); //等待设备把时钟线拉高
mouse_sda = 1; //发送停止位
while(mouse_clk); //等待设备把时钟线拉低
TRISB2=1;//数据输入
asm( "nop");
asm( "nop");
while(!mouse_clk); //等待设备把时钟线拉高
while(mouse_sda); //等待接收应答位(总是为0)
while(mouse_clk); //等待设备把时钟线拉低
while(!mouse_clk); //等待设备释放时钟线
while(!mouse_sda); //等待设备释放数据线
INTE = 1; //打开外部中断INTE
}
再就是鼠标的发数据模块可以参考下面的步骤:
1)等待时钟线为高
2)数据线仍然为低吗 有错误发生放弃
3)读入8个数据位\在读入这些位后
4)读入校验位>测试时钟线数否被主机拉低
5)读入停止位/这就意味着放弃这次传送
6)数据线仍旧为0吗
是保持时钟直到数据1然后产生一个错误
7)输出应答位
8)检查校验位
如果校验位不正确则产生一个错误
9)延迟45微秒给主机时间抑制下次的传送
按如下次序读取每位8个数据位检验位和停止位
1)延迟20微秒
2)把时钟拉低
3)延迟40微秒
4)释放时钟
5)延迟20微秒
7)读数据线
按如下次序发送应答位
1)延迟15微秒
2)把数据线拉低
3)延迟5微秒
4)把时钟线拉低
5)延迟40微秒
6)释放时钟线
7)延迟5微秒
8)释放数据线
void interrupt INTE_ISR(void)
{
mouse_word >>= 1; //先向右空移一位
if(mouse_sda) {mouse_word |= 0x0400; } //11位数据先接收最低位0000 010 (0 0000 000) 0 1START-8DA
n++; if(n == 11) {mouse_read_dat(); n = 0;} //接收完成则读出数据
INTF=0;
}
接下来就是读鼠标的数据了,首先要明白这个数据包中具体是些什么,看下面的图:
(一般的鼠标就这些,具体的就要查鼠标的资料了)同志们 还不清楚就看下面的解释吧!!!
鼠标内部有一个位移计数器,位移计数器是一个9位2的补码整数。它的最高位作为
符号位出现在位移数据包的第一个字节里。这些计数器在鼠标读取输入发现有位移
时被更新。这些值是自从最后一次发送位移数据包给主机后位移的累计量(即最后
一次包发给主机后位移计数器被复位)。位移计数器可表示的值的范围是-255到+255,
如果超过了范围,相
单片机pic16f877a鼠标数 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)