正文

单片机PS2鼠标程序源码2006-09-22 11:32:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/embed/18646.html

分享到:

PC鼠标示例源代码: 1.  主文件: /*****************************Copyright (c)*************** ************;**    日期:      2005.5.10;**    描述:      PC鼠标,本程序也通过调试,仅供参考。;**    实验内容:   利用点阵显示鼠标当前按下的按键和移动的方向与距离;**    适用机型:  AT89S52********************************************************************/ #include "Com.h"#include "Display.h"/******************************************************* 名称:   初始化运行环境   功能:  初始化各寄存器与端口状态 参数:  无 返回值:无********************************************************/ void Init_device(void) {     EA=1;      EX1=1;                   //允许外部中断1      TL0=0xf0;              //置定时器初值0x3CB0  中断时间为25ms      TH0=0xd8;      TMOD=0x01;            //设定定时器/计数器0工作方式为1      ET0=0x01;              //允许全局中断,允许定时器/计数器0溢出中断      PX1=1;                 //设置中断优先级      PT0=0;      TR0=0x01;             //启动定时器/计数器0 } /******************************************************* 名称:   主函数 功能:  应用程序入口 参数:  无 返回值:无*******************************************************/ void main(){      Init_device();                 //调用初始化模块         Send_data(0xF4);            //使能鼠标,允许鼠标发送数据      do{      }while(Temp_Buffer!=0xFA);      ChoiceData(char_P);       //显示鼠标点      while(1)      {         ProcessData();        //调用数据处理模块      } }   2.  头文件Com.h: /****************************Copyright (c)**************** *************;**       文件名:      com.h;**       功能:        数据处理头文件,接收和处理鼠标发送到主机的数据;**                     发送对鼠标的控制命令;**       包含头文件:    at89x52.h   芯片功能模块定义 ********************************************************************/ #include <at89x52.h>/************************************************************/                    sbit Data_Line=P3^5;                       //数据线P3_5 sbit Clock_Line=P3^3;                    //时钟线P3_3 /***********************定义位变量***************************/ unsigned char bdata Temp_Buffer;       //接收字节 sbit D_Buf0=Temp_Buffer^0;             //Temp_Buffer第0位 sbit D_Buf1=Temp_Buffer^1; sbit D_Buf2=Temp_Buffer^2; sbit D_Buf3=Temp_Buffer^3; sbit D_Buf4=Temp_Buffer^4; sbit D_Buf5=Temp_Buffer^5; sbit D_Buf6=Temp_Buffer^6; sbit D_Buf7=Temp_Buffer^7;                    //Temp_Buffer第7位0 /************************************************************/ unsigned char Buffer[11];                      //接收位数据缓冲区 unsigned char Rec_ptr=0x00;                 //接收数据指针 unsigned char Rec_data=0xFF;           //接收数据 unsigned char Data_Buf[3];            //接收鼠标数据缓冲区 unsigned char Buffer_ptr=0x00;          //缓冲区指针 unsigned char Data_ptr=0;                  //数据处理指针 /*******************************************************  名称:   延时模块  功能:  软件延时  参数:  unsigned int count 延时长度  返回值:无 *******************************************************/     void Delay(unsigned int count) {         unsigned char j,k;     unsigned int i;     for(i=0;i<count;i++)        for(j=0;j<10;j++)           for(k=0;k<120;k++)            ; } /*******************************************************  名称:   发送模块  功能:  发送一个字节的控制命令  参数:  unsigned char dat 控制命令  返回值:无 *******************************************************/     //发送一个字符 void Send_data(unsigned char dat) {      unsigned char ptr;      TR0=0;                                        //关闭定时器      EX1=0;                                        //关闭外部中断1      ACC=dat;                                //将要发送的数据放入A寄存器      Clock_Line=0;                         //拉低时钟线      Delay(30);                                //延时100ms以上      Data_Line=0;                           //拉低数据线      Delay(2);      Clock_Line=1;                         //释放时钟线      for(ptr=0;ptr<=7;ptr++)         //低位在前,一次发送8个数据位      {          do{          }while(Clock_Line==1);      //等待设备释放时钟线          Data_Line=(dat>>ptr)&0x01;  //发送数据位          do{          }while(Clock_Line==0);    //等待设备拉低时钟线      }      do{      }while(Clock_Line==1);      Data_Line=~P;                             //发送校验位,奇校验      do{      }while(Clock_Line==0);           do{      }while(Clock_Line==1);      Data_Line=1;                                 //发送停止位      do{      }while(Clock_Line==0);           do{      }while(Clock_Line==1);      do{      }while(Clock_Line==0);        EX1=1;                                              //打开外部中断1      TR0=1;                                              //打开定时器中断 } /*******************************************************  名称:   奇偶校验模块  功能:  对接收到的数据进行奇偶校验  参数:  无  返回值:校验正确  1          校验错误  0 *******************************************************/  unsigned char Checkout(void) {      ACC=Temp_Buffer;      if(~P==Buffer[9])         return 1;      else         return 0; } /*******************************************************  名称:   组合数据模块  功能:  将接收到的数据为组合成数据  参数:  无  返回值:无 *******************************************************/ void CombinData(void) { /*********将接收到的各位赋值给Temp_Buffer对应的位***********/        D_Buf0=Buffer[1];     D_Buf1=Buffer[2];        D_Buf2=Buffer[3];        D_Buf3=Buffer[4];        D_Buf4=Buffer[5];        D_Buf5=Buffer[6];        D_Buf6=Buffer[7];        D_Buf7=Buffer[8]; /************************************************************/      if(Checkout())                      //如果校验正确      {         if(Data_ptr<=2)         //将鼠标发送的3字节信号分别存入缓冲区             Data_Buf[Data_ptr++]=Temp_Buffer;         else         {             Data_Buf[0]=Temp_Buffer;             Data_ptr=1;         }      } } /*******************************************************  名称:   外部中断1服务程序  功能:  接收鼠标发送到主机的各个数据位  参数:  无  返回值:无 *******************************************************/ void ReceiveData(void)  interrupt 0 {      if(Rec_ptr<=10)      {          do{          }while(Clock_Line==0);        //等待设备拉高时钟线          Buffer[Rec_ptr++]=Data_Line;   //接收数据      }      else      {          CombinData();                 //组合接收到的数据          do{          }while(Clock_Line==0);        //等待设备拉高时钟线          Buffer[0]=Data_Line;          //接收数据             Rec_ptr=0x01;      } } <!--[if !supportLists]-->3.  <!--[endif]-->头文件pointdisplay.h: /***************************Copyright (c)***************** ************ ;**       文件名:       pointdisplay.h ;**       功能:         点阵显示头文件,在点阵模块上显示图形 ;**       含头文件:    intrins.h  Keil内部函数头文件 ********************************************************************/ #include <intrins.h> /*******************点阵显示数据字符编码*****************************/ //鼠标移动点 const unsigned char code char_P[8]={0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00}; //鼠标左键被按下 const unsigned char code char_L[8]={0x00,0x24,0x14,0x8C,0x97,0xF4,0x94,0x84}; //鼠标中键被按下 const unsigned char code char_M[8]={0x00,0x3C,0x24,0xFF,0xFF,0x24,0x3C,0x00}; //鼠标右键被按下 Const unsigned char code char_R[8]={0x00,0x24,0x14,0xEC, 0xA7,0xA4,0xA4,0xE4}; //多个按键被按下 const unsigned char code char_S[8]={0xFF,0xFF,0xFF,0xE7,0xF7,0xFF,0xFF,0xFF}; //---------------------------------扫描位数组---------------------------------- const unsigned char Row_Control[8]={0xFE,0xFD,0xFB,0xF7, 0xEF,0xDF,0xBF,0x7F}; unsigned char send_data[8];      //发送数据缓冲区 //鼠标移动数据缓冲区 unsigned char move_data[8]={0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00}; unsigned char ptr_send=0x00;     //发送数据指针     unsigned char ptr_con1=0x00;     //扫描指针 unsigned char button_L;                  //左键标志 unsigned char button_R;                  //右键标志 unsigned char button_M;                 //中键标志 unsigned char length_X;                  //横向位移 unsigned char length_Y;                  //纵向位移 unsigned char flag_Y;                 //横向移动标志 左移为1,右移为0 unsigned char flag_X;                 //纵向移动标志 下移位1,上移为0 unsigned char X_Lmove;                //横向左移距离 unsigned char Y_Umove;                //横向右移距离 unsigned char X_Rmove;                //纵向上移距离 unsigned char Y_Dmove;                //纵向下移距离 /***********************定义位变量***************************/ unsigned char bdata BitData;      //控制信息字节 sbit B_dat0=BitData^0;                    //BitData第0位 sbit B_dat1=BitData^1; sbit B_dat2=BitData^2; sbit B_dat3=BitData^3; sbit B_dat4=BitData^4; sbit B_dat5=BitData^5; sbit B_dat6=BitData^6; sbit B_dat7=BitData^7;                      //BitData第7位 /************************************************************/ /*******************************************************  名称:   显示数据模块  功能:  将要显示的数据送到点阵模块显示          P1_5 控制线  P1_6 数据线  P1_7 时钟线  参数:  unsigned char s_bit   扫描列控制          unsigned char s_data  显示数据  返回值:无 *******************************************************/              void DisplayData(unsigned char s_bit,unsigned char s_data) {    unsigned char m,n;    P1_5=0x00;                 //拉低时钟线和控制线抑制发送    P1_7=0x00;    for(m=0;m<=7;m++)          //从低位到高位按位发送数据    {                                P1_6=(s_bit<<m)&0x80;       P1_7=0x01;              //拉高时钟线允许发送       P1_7=0x00;              //拉低时钟线抑制发送    }    for(n=0;n<=7;n++)    {       P1_6=(s_data<<n)&0x80;       P1_7=0x01;       P1_7=0x00;    }    P1_5=0x01;                 //拉高控制线将移位寄存器送点阵显示    P1_5=0x00;                 //拉底控制线锁存数据 } /*******************************************************  名称:   选取显示图形数据模块   功能:  选取显示图形对应的数据  参数:  unsigned char *ptr     图形对应数组的数组名  返回值:无 *******************************************************/ void ChoiceData(unsigned char *ptr) reentrant {    unsigned char temp;    for(temp=0x00;temp<=0x07;temp++)    {        send_data[temp]=*(ptr+temp);    } } /*******************************************************  名称:   取数模块    功能:  依次从数组中取出要显示的数据  参数:  无  返回值:unsigned char setdata    要显示的数据 *******************************************************/ unsigned char LeftSet(void) {    unsigned char setdata;    if(ptr_send<=7)    {      setdata=send_data[ptr_send];      ptr_send++;    }    else    {      setdata=send_data[0];      ptr_send=0x01;    }    return setdata;                     //返回取得的数据 } /*******************************************************  名称:   扫描控制模块  功能:  控制扫描的列  参数:  无  返回值:unsigned char setbit  当前扫描的列 *******************************************************/ unsigned char RowScan(void) {    unsigned char setbit;    if(ptr_con1<=7)    {      setbit=Row_Control[ptr_con1];      ptr_con1++;    }    else    {      setbit=Row_Control[0];      ptr_con1=0x01;    }    return setbit;                       //返回扫描的列 } /*******************************************************  名称:   移动控制模块  功能:  在点阵显示模块上移动显示数据  参数:  无  返回值:unsigned char mode  模块模式          0---左移  1---右移                 2---上移  3---下移           unsigned char step  移动距离 *******************************************************/ void Move(unsigned char mode,unsigned char step) {     unsigned char i,j;     unsigned char temp[8];     for(i=0;i<=7;i++)                  //将要移动的数据放入移动缓冲区         send_data[i]=move_data[i];     switch(mode)     {         case 0:                     //左移             j=0;             for(i=0;i<=7;i++)          //保存显示数据                 temp[i]=send_data[i];              for(i=0;i<=7-step;i++)  //左移step位                 send_data[i]=send_data[i+step];             for(i=8-step;i<=7;i++)  //将移出的数据存回                 send_data[i]=temp[j++];             break;         case 1:                     //右移             j=8-step;             for(i=0;i<=7;i++)                 temp[i]=send_data[i];             for(i=7;i>=step;i--)                 send_data[i]=send_data[i-step];             for(i=0;i<step;i++)                 send_data[i]=temp[j++];             break;         case 2:                    //上移             for(i=0;i<7;i++)    //将每列数据循环移动step位                 send_data[i]=_cror_(send_data[i],step);             break;         case 3:             for(i=0;i<7;i++)       //下移                 send_data[i]=_crol_(send_data[i],step);             break;         default:             break;     }     for(i=0;i<=7;i++)                   //将移动后的数据放入移动数据缓冲区         move_data[i]=send_data[i]; } /*******************************************************  名称:   数据处理模块  功能:  处理接收到的数据  参数:  无  返回值:无 *******************************************************/ void ProcessData() {     unsigned char temp;     BitData=Data_Buf[1];     button_L=B_dat0;     button_R=B_dat1;     button_M=B_dat2;     flag_X=B_dat4;     flag_Y=B_dat5;     length_X=Data_Buf[2];     length_Y=Data_Buf[0];     if(button_L+button_R+button_M==0)  //没有键被按下     {         ChoiceData(move_data);         if(Data_Buf[0]+Data_Buf[2]!=0) //如果位移不为0         {             if(flag_X)                            //左移             {                 temp=256-length_X;         //取位移绝对值                 X_Rmove+=temp/4;          //每4个单位为1毫米,取位移毫米                 if(flag_Y)                    //上移                 {                     temp=256-length_Y; //取位移绝对值                     Y_Dmove+=temp/4;   //每4个单位为1毫米,取位移毫米                 }                 else                            //下移                 {                     Y_Umove+=length_Y/4;                 }             }             else                                    //右移             {                 X_Lmove+=length_X/4;   //每4个单位为1毫米,取位移毫米                 if(flag_Y)                 {                     temp=256-length_Y;                     Y_Dmove+=temp/4;                 }                 else                 {                     Y_Umove+=length_Y/4;                 }             }             Data_Buf[0]=0;                    //清空位移             Data_Buf[2]=0;         }     }     else                                                         //有键被按下     {           if(button_L+button_M+button_R==1)         {               if(button_L==1)                 ChoiceData(char_L);           //左键被按下             else if(button_R==1)                   ChoiceData(char_R);      //右键被按下                  else                 ChoiceData(char_M);      //中键被按下              }         else             ChoiceData(char_S);                   //多个键被按下     } } /*******************************************************  名称:   定时器中断服务模块   功能:  显示图形  参数:  无  返回值:无 *******************************************************/ void TimerOver(void) interrupt 1  {    DisplayData(RowScan(),LeftSet()); //显示点阵图形    if(X_Lmove>=1)                               //如果鼠标左移大于等于1毫米    {        Move(1,1);                                //左移一个单位        X_Lmove=0;                             //清除左移长度    }    if(X_Rmove>=1)                               //如果鼠标右移大于等于1毫米    {        Move(0,1);        X_Rmove=0;    }    if(Y_Umove>=1)                               //如果鼠标上移大于等于1毫米    {        Move(2,1);        Y_Umove=0;    }    if(Y_Dmove>=3)                            //如果鼠标下移大于等于1毫米    {        Move(3,1);        Y_Dmove=0;    }    TL0=0x78;                       //重置定时器初值0xFCB0    TH0=0xEC; }  

阅读(534) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册