找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机做PS/2鼠标电路设计

[复制链接]
跳转到指定楼层
楼主
ID:324521 发表于 2018-5-7 20:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我这个是使用数码管显示,直接贴程序吧用的是HC573驱动8位数码管
前四数码管显示X坐标,后四位显示Y坐标

实物测试有问题,个人感觉是程序问题,麻烦大家围观一下,纠纠错




#include <reg52.h>
#include <intrins.h>
sbit mouse_sda = P2^0;  //鼠标数据线
sbit mouse_clk = P3^3;  //鼠标时钟线
sbit led       = P1^3;  //按键LED指示
sbit beep      = P2^5;  //蜂鸣器指示
/*--------------------------------------------------------------*/
//数据定义
unsigned char n, m;   //循环变量
unsigned int  mouse_word; //接收字16bits
unsigned char mouse_data[3];//接收字节缓冲区
unsigned int  move_x;  //横坐标
unsigned int  move_y;  //纵坐标
bit mouse_left;    //左键
bit mouse_right;   //右键
bit mouse_middle;   //中键
/*--------------------------------------------------------------*/
//函数声明
void INT0_init(void);      //外部中断INT0初始化
void delay120us(void);      //延时120us 函数定义
void mouse_write_dat(unsigned char dat); //发送数据
void mouse_read_dat(void);     //读出数据
void mouse_data_process(void);    //数据处理
void mouse_init(void);      //鼠标初始化
/*--------------------------------------------------------------*/
//外部中断INT0初始化
void INT0_init(void)
{   
EA  = 1;   //总中断打开
EX1 = 1;   //外部中断打开
PX1 = 1;   //中断优先级
IT1 = 0;   //低电平触发
}
/*--------------------------------------------------------------*/
//延时120us 函数定义
void delay120us(void)
{   
unsigned char i, j;   
for(i = 23; i > 0; i--)   
for(j = 1; j > 0; j--);
}
/*--------------------------------------------------------------*/
//发送数据
//发送11位数据:1START-8DATA-1PARITY-1STOP
//并接收一个应答位ack = 0
void mouse_write_dat(unsigned char dat)
{
unsigned char i; //循环变量
bit parity;   //奇校验位
EX1 = 0;   //关闭外部中断
ACC = dat;   //存入累加器A,得到P(为偶校验)
parity = ~P;  //获得奇校验位
mouse_clk = 0;  //拉低时钟线
delay120us();  //至少延时100us
mouse_sda = 0;  //发送起始位
mouse_clk = 1;  //释放时钟线
mouse_sda = 1;  //释放数据线
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 = parity;    //发送奇校验位
while(mouse_clk);    //等待设备把时钟线拉低
while(!mouse_clk);    //等待设备把时钟线拉高
mouse_sda = 1;     //发送停止位
while(mouse_clk);    //等待设备把时钟线拉低
while(!mouse_clk);    //等待设备把时钟线拉高
while(mouse_sda);    //等待接收应答位(总是为0)
while(mouse_clk);    //等待设备把时钟线拉低
while(!mouse_clk);    //等待设备释放时钟线
while(!mouse_sda);    //等待设备释放数据线
EX1 = 1;              //打开外部中断INT0
}
/*--------------------------------------------------------------*/
//奇校验
bit check_parity(void)
{
  ACC = mouse_data[m];
   if(~P == (bit)(mouse_word & 0x0200))
   return 1; //奇校验成功则返回1
   else         
   return 0;                                      //奇校验失败则返回0
   }
/*--------------------------------------------------------------*/
//读出3字节数据
void mouse_read_dat(void)
{
mouse_data[m] = (unsigned char)(mouse_word >> 1); //去掉最高两位和最后一位
if(check_parity())         //奇校验成功
{
   mouse_word = 0;         //清接收数据字  
   m++;
   if(m == 3) {mouse_data_process(); m = 0;} //读出三字节数据
}
}
/*--------------------------------------------------------------*/
//数据处理
   void mouse_data_process(void)
   {                                       
        if                                                                           //水平移动
              (mouse_data[0] & 0x10)
                  move_x -= 256 - mouse_data[1]; //x坐标减                
        else      move_x += mouse_data[1];       //x坐标加               
                                                 //垂直移动
                if
                (mouse_data[0] & 0x20)
                          move_y -= 256 - mouse_data[2]; //y坐标减
                else      move_y += mouse_data[2];       //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;

   if(mouse_data[0] & 0x04)
           mouse_middle = 1;    //中键
     else  mouse_middle = 0;}
/*--------------------------------------------------------------*/
//外部中断INT0服务
//接收11位数据:1START-8DATA-1PARITY-1STOP
void INT0_intservice(void) interrupt 2   
{
mouse_word >>= 1;       //先向右空移一位
if(mouse_sda) mouse_word |= 0x0400;   //先接收最低位
  n++;
  if(n == 11) {mouse_read_dat();
  n = 0;} //接收完成则读出数据
}
/*--------------------------------------------------------------*/
//鼠标初始化
void mouse_init(void)
{
INT0_init();     //外部中断INT0初始化
mouse_write_dat(0xf4);   //Enable Data Reporting
  while(mouse_data[0] != 0xfa); //等待鼠标应答
  mouse_data[0] = 0;    //清应答数据
  m = 0;       //重新定义接收数据指针
  }
  //--定义使用的IO--//
#define GPIO_DIG P0

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

//--定义全局变量--//
unsigned char code DIG_CODE[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f};
//0、1、2、3、4、5、6、7、8、9的显示码
unsigned char disbuff[8]           ={0,0,0,0,0,0,0,0,};
/*******************************************************************************
* 函 数 名         : DigDisplay
* 函数功能                   : 使用数码管显示
*******************************************************************************/

void DigDisplay()
{
        unsigned char i;
        unsigned int j;
        for(i=0;i<8;i++)
        {
                switch(i)         //位选,选择点亮的数码管,
                {
                        case(0):
                                LSA=0;LSB=0;LSC=0; break;//显示第0位
                        case(1):
                                LSA=1;LSB=0;LSC=0; break;//显示第1位
                        case(2):
                                LSA=0;LSB=1;LSC=0; break;//显示第2位
                        case(3):
                                LSA=1;LSB=1;LSC=0; break;//显示第3位
            case(4):
                                LSA=0;LSB=0;LSC=1; break;//显示第4位
                        case(5):
                                LSA=1;LSB=0;LSC=1; break;//显示第5位
                        case(6):
                                LSA=0;LSB=1;LSC=1; break;//显示第6位
                        case(7):
                                LSA=1;LSB=1;LSC=1; break;//显示第7位       
                }

                 GPIO_DIG=disbuff[i];
                j=10;         //扫描间隔时间设定
                while(j--);       
                GPIO_DIG=0x00;//消隐
        }
}
   //********************************************************/
//void main ()
//unsigned int
        /********************************************************/

/********************************************************/
   void Conut(void)
        {          
        while(1)
                {       
          disbuff[7]=DIG_CODE[move_x%10000/1000];       
          disbuff[6]=DIG_CODE[move_x%1000/100];                 
      disbuff[5]=DIG_CODE[move_x%100/10];                  
          disbuff[4]=DIG_CODE[move_x%10/1];                         
          disbuff[3]=DIG_CODE[move_y%10000/1000];                          
          disbuff[2]=DIG_CODE[move_y%1000/100];                                  
          disbuff[1]=DIG_CODE[move_y%100/10];                                         
          disbuff[0]=DIG_CODE[move_y%10/1];                                               
     }
         }



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

使用道具 举报

沙发
ID:324521 发表于 2018-5-7 21:14 | 只看该作者
嗨呀,顶一下
回复

使用道具 举报

板凳
ID:324810 发表于 2018-5-8 10:08 | 只看该作者
学习一下
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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