找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6276|回复: 0
打印 上一主题 下一主题
收起左侧

单片机鼠标驱动源程序

[复制链接]
跳转到指定楼层
楼主
ID:59284 发表于 2014-2-26 18:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
//PS2鼠标驱动程序
//测试发送其他命令鼠标如何回复。比如0xff
#include <reg51.H>
sbit mouse_sda = P1^6; //鼠标数据线
sbit mouse_clk = P3^2; //鼠标时钟线:单片机0号中断
sbit led_jc    = P0^7; //LED检测鼠标时钟是否发生
sbit led_L     = P0^3;
//按键LED指示,鼠标左键
sbit led_R     = P0^4; //按键LED指示,鼠标右键
//数据定义
unsigned char n, m; //循环变量
unsigned int  mouse_word;mouse_wordbf=0; //接收字16bits,临时变量用于接受11位的数据
unsigned char mouse_data[3]; //接收字节缓冲区,保存3字节的数据报告
bit mouse_left; //左键,
bit mouse_right;//右键,按键状态变量
unsigned int  move_x;//横坐标无符号整形2字节
unsigned int  move_y;//纵坐标
//函数声明
void int0(void); //外部中断INT0初始化
void delay100us(void); //延时100微妙 函数定义
void mouse_write_dat(unsigned char dat); //发送数据
void mouse_read_dat(void); //读出数据
bit check_parity(void); //奇校验
void ys (x);
void delay50ms(void);  //50毫秒延时
//外部中断INT0初始化
void int0(void)  //初始化外部中断p3.2状态
{EA  = 1;       //总中断
EX0 = 1; //外部中断
PX0 = 1; //中断优先级
IT0 = 0; //低电平触发
}
void delay100us(void)//这里是乱写的延时函数居然正确。
{unsigned char i, j;
for(i = 30; i > 0; i--)
for(j = 1; j > 0; j--);
}
void ys (x)//这是一条测试用的延时函数,可以延时几秒钟
{unsigned char ii, jj;
for(ii = x; ii > 0; ii--)
for(jj = 9000; jj > 0; jj--);
}
//外部中断INT0服务
//接收完11位数据就开始处理
void INT0_intservice(void) interrupt 0  //安装0号中断
{EX0 = 0;
mouse_word >>= 1; //先向右空移一位
if(mouse_sda) mouse_word |= 0x0400;//先接收最低位00001000 00000000,
n++;
if(n == 11) {mouse_read_dat(); n = 0;}//接收完成则读出数据
//检led_jc=1; 测是否有时钟信号
EX0 = 1;
}
//处理程序段
//读出3字节数据,数据整理、奇校验、和指挥拆分3字节数据
void mouse_read_dat(void)
{mouse_data[m] = (unsigned char)(mouse_word >> 1);//去掉
mouse_wordbf=mouse_word;
  mouse_word=0;
  if(check_parity()) //奇校验成功
   {mouse_word = 0; //清接收数据字
    m++;
    if(m == 3) //数据处理,拆分数据包 注意拆分的是第一字节
     {move_x+=mouse_data[2];//获得位移量
      move_y+=mouse_data[3];//获得y位移量
      if(mouse_data[0] & 0x01) mouse_left = 1;//左键
      else mouse_left = 0;
      if(mouse_data[0] & 0x02) mouse_right = 1;//右键
      else mouse_right = 0;
      m = 0;
       }
    }
}
//奇校验
bit check_parity(void)
{ACC=mouse_data[m];
if(~P == (bit)(mouse_wordbf & 0x0200)) return 1; //奇校验成功则返回1
else           return 0; //奇校验失败则返回0
}
//发送数据
//发送11位数据:1START-8DATA-1PARITY-1STOP
//并接收一个应答位ack = 0
void mouse_write_dat(unsigned char dat)
{ unsigned char i; //循环变量
  bit parity; //奇校验位
  EX0 = 0; //关闭外部中断
  ACC = dat; //存入累加器A,得到P(为偶校验)
  parity = ~P; //对P求反获得奇校验位
  mouse_clk = 0;//拉低时钟线
  delay100us(); //至少延时100us
  mouse_sda = 0;//发送起始位
  mouse_clk = 1;//释放时钟线
for(i = 0; i < 8; i++)
{while(mouse_clk); //等待设备把时钟线拉低
mouse_sda =(bit)(dat& 0x01);  //先发送最低位
dat >>= 1;    //下降沿写入数据
while(!mouse_clk);//等待设备把时钟线拉高
}
while(mouse_clk); //等待设备把时钟线拉低
mouse_sda = parity; //发送奇校验位
while(!mouse_clk); //等待设备把时钟线拉高
while(mouse_clk); //等待设备把时钟线拉低
mouse_sda = 1;    //发送停止位
while(!mouse_clk);//等待设备把时钟线拉高
while(mouse_sda);  //等待接收应答位(总是为0)
while(mouse_clk);  //等待设备把时钟线拉低
while(!mouse_clk); //等待设备释放时钟线,把时钟拉高
while(!mouse_sda); //等待设备释放数据线,把时钟拉高
EX0 = 1;    //打开外部中断INT0
}
void main(void)
{P0=0xff;//先把LED关了
mouse_clk = 1;  //拉高时钟线
ys(100000);
int0();
mouse_write_dat(0xf4); //立马发送鼠标使能命令过去
while(mouse_data[0] != 0xfa); //数据包的第一字节判断鼠标是否应答,不然就一直停在这里
mouse_data[0] = 0;    //清应答数据
m = 0;
while(1)
{
//检led_jc=0;//guandeng
led_L = mouse_left;//显示数据包1的内容
led_R = mouse_right;
P0=mouse_x;//P0口直接显示x位移量的值

}     
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表