关闭

举报

  • 提交
    首页 > 党建扶贫 > 正文
    购物车
    0

    《姬家寨村单片机键盘鼠标显示器》

    信息发布者:姬学瑞
    2024-12-01 13:23:42    来源:《姬家寨村电子科技》   原创

    《姬家寨村单片机键盘鼠标显示器》

    硬件设计:姬学瑞;软件编程:姬学瑞;版权所有,琴权必究!

    河南省新乡市姬家寨村电子科技研究所研制!

     

     

    《壹键盘》:

    /*此程序在SP-518USB开发板上测试过    laosong  */

    /****************************************************************

    程序名称:  程序自动接收PS2键盘的按键,并且显示出来。           

    说明:开发板上面的SE15 SE16跳线必须设置为PS2

          程序中没有做键盘数据的奇偶校验

    *****************************************************************/

    #include <reg51.h>

    #include <intrins.h>

    #include <keycode.h>

    #define uint unsigned int

    #define uchar unsigned char

     

    sbit Key_Data = P3^4;  /*定义Keyboard引脚*/

    sbit Key_CLK = P3^3;

     

    sbit lcd_rs_port = P2^7;   /*定义LCD控制端口*/

    sbit lcd_rw_port = P2^6;   /*定义LCD控制端口*/

    sbit lcd_en_port = P2^5;   /*定义LCD控制端口*/

    #define lcd_data_port P0   /*定义LCD控制端口*/  

     

    uchar IntNum = 0; /*中断次数计数*/

    uchar KeyV; /*键值*/

    uchar Key_UP=0, Shift = 0;/*Key_UP是键松开标识,ShiftShift键按下标识*/

    uchar BF = 0; /*标识是否有字符被收到*/

    uchar DisNum = 0; //显示用指针

     

    uchar code lcd_line0[]={" Sappire PS2 KB "};

    uchar code lcd_line1[]={" PS2 KB Testing "};

     

    void Decode(unsigned char ScanCode); /*按键处理*/

    void lcd_delay(uchar ms); /*LCD1602 延时*/

    void lcd_busy_wait(); /*LCD1602 忙等待*/

    void lcd_command_write(uchar command); /*LCD1602 命令字写入*/

    void lcd_system_reset(); /*LCD1602 初始化*/

    void lcd_char_write(uchar x_pos,y_pos,lcd_dat); /*LCD1602 字符写入*/

    void Delay_400Ms(); /*延时400毫秒*/

     

    void main()

    {

    uchar i;

    lcd_system_reset();

    for(i=0;i<16;i++) lcd_char_write(i,0,lcd_line0[i]);

    for(i=0;i<16;i++) lcd_char_write(i,1,lcd_line1[i]);

    Delay_400Ms();

    Delay_400Ms();

    Delay_400Ms();

    for(i=0;i<16;i++) lcd_char_write(i,1,' ');

    IT1 = 0;    /*设外部中断1为低电平触发*/

    EX1 = 1;    /*开外部中断1*/

    EA   = 1;   /*开总中断*/

    while(1){

    if (BF)  Decode(KeyV);

         else EA = 1; //开中断

    }

    }

     

    void Keyboard_out(void) interrupt 2

    {

    if ((IntNum > 0) && (IntNum < 9)){   

         KeyV = KeyV >> 1; /*因键盘数据是低>>高,结合上一句所以右移一位*/

         if (Key_Data) KeyV = KeyV | 0x80; /*当键盘数据线为1时为1到最高位*/

        }

    IntNum++;

    while (!Key_CLK); /*等待PS/2CLK拉高*/

     

    if (IntNum > 10){

         IntNum = 0; /*当中断10次后表示一帧数据收完,清变量准备下一次接收*/

         BF = 1; /*标识有字符输入完了*/

         EA = 0; /*关中断等显示完后再开中断 (注:如这里不用BF和关中断直接调Decode()则所Decode中所调用的所有函数要声明为再入函数)*/

        }

    }

     

    void Decode(unsigned char ScanCode) /*注意:SHIFT+G12H 34H F0H 34H F0H 12H,也就是说shift的通码+G的通码+shift的断码+G的断码*/

    {

    uchar i;

    uchar TempCyc;

    if (!Key_UP){                /*当键盘松开时*/

         switch (ScanCode){

           case 0xF0 : /* 当收到0xF0Key_UP1表示断码开始*/

               Key_UP = 1;

              break;

    case 0x12 : /* SHIFT*/

               Shift = 1;

              break;

    case 0x59 : /* SHIFT*/

               Shift = 1;

              break;

     

           default:      

                if (DisNum > 15){

                  DisNum = 0;

    for(i=0;i<16;i++) lcd_char_write(i,1,' '); /*LCD1行显示*/

                 }

               if(!Shift){ /*如果SHIFT没按下*/

                 for (TempCyc = 0;(UnShifted[TempCyc][0]!=ScanCode)&&(TempCyc<62); TempCyc++); /*查表显示*/

                 if (UnShifted[TempCyc][0] == ScanCode){

    lcd_char_write(DisNum, 1, UnShifted[TempCyc][1]);

                  DisNum++;

                  }

                 }

               else{  /*按下SHIFT*/

                 for(TempCyc = 0; (Shifted[TempCyc][0]!=ScanCode)&&(TempCyc<62); TempCyc++); /*查表显示*/

                 if (Shifted[TempCyc][0] == ScanCode){

    lcd_char_write(DisNum, 1, Shifted[TempCyc][1]);

                  DisNum++;

                  }

                 }

    break;

          }

        }

    else{

         Key_UP = 0;

         switch (ScanCode){ /*当键松开时不处理判码,如G 34H F0H 34H 那么第二个34H不会被处理 */

           case 0x12 : /* SHIFT*/

               Shift = 0;

              break;

     

           case 0x59 : /* SHIFT*/

               Shift = 0;

              break;

          }

        }

    BF = 0; /*标识字符处理完了*/

    }

     

    void lcd_delay(uchar ms) /*LCD1602 延时*/

    {

        uchar j;

        while(ms--){

            for(j=0;j<250;j++)

                {;}

            }   

    }

     

    void lcd_busy_wait() /*LCD1602 忙等待*/

    {

        lcd_rs_port = 0;

        lcd_rw_port = 1;

        lcd_en_port = 1;

        lcd_data_port = 0xff;

        while (lcd_data_port&0x80);

        lcd_en_port = 0;

     

    }

     

    void lcd_command_write(uchar command) /*LCD1602 命令字写入*/

    {

        lcd_busy_wait();

        lcd_rs_port = 0;

        lcd_rw_port = 0;

        lcd_en_port = 0;

        lcd_data_port = command;

        lcd_en_port = 1;

        lcd_en_port = 0;     

    }

     

    void lcd_system_reset() /*LCD1602 初始化*/

    {

        lcd_delay(20);

        lcd_command_write(0x38);

        lcd_delay(100);

        lcd_command_write(0x38);

        lcd_delay(50);

        lcd_command_write(0x38);

        lcd_delay(10);

        lcd_command_write(0x08); /* 关闭显示*/

        lcd_command_write(0x01); /* 显示清屏*/

        lcd_command_write(0x06); /* 显示光标移动设置*/

        lcd_command_write(0x0f); /* 显示开及光标设置*/

    lcd_data_port = 0xff; /*释放数据端口*/

    }

     

    void lcd_char_write(uchar x_pos,y_pos,lcd_dat) /*LCD1602 字符写入*/

    {

        x_pos &= 0x0f; /* X位置范围 0~15 */

        y_pos &= 0x01; /* Y位置范围 0~ 1 */

        if(y_pos==1) x_pos += 0x40;

        x_pos += 0x80;

        lcd_command_write(x_pos);

        lcd_busy_wait();

        lcd_rs_port = 1;

        lcd_rw_port = 0;

        lcd_en_port = 0;

        lcd_data_port = lcd_dat;

        lcd_en_port = 1;

        lcd_en_port = 0;

    lcd_data_port = 0xff; /*释放数据端口*/

    }

     

    //400ms延时

    void Delay_400Ms()

    {

    uchar TempCycA = 5;

    uint TempCycB;

    while(TempCycA--){

         TempCycB=7269;

         while(TempCycB--);

        }

    }

     

     

    《贰鼠标》:

    /*此程序在SP-518USB开发板上测试过    laosong  */

     

    #include<reg52.h>

    #include"mouse.h"

    #include"LCD1602_4.h"

     

    sbit Speaker_port=P3^7;

     

     

    /*1MS为单位的延时程序*/

    void delay_1ms(uchar x)

    {

        uchar j;

        while(x--) { for(j=0;j<125;j++); }   

    }

     

     

    /*喇叭发声简单程序*/

    void Speaker_output()

    {

    uchar i;

    for(i=0;i<100;i++){

    Speaker_port = 0;

    delay_1ms(3);

    Speaker_port = 1;

    delay_1ms(1);

    }

    }

     

     

    void main()

    {

     

    LCM1602_Init();//初始化液晶1602    

    LCM1602_write_string(0,0,"x:----");

    LCM1602_write_string(0,8,"y:----");

    LCM1602_write_string(1,0,"------");

    Init_mouse();

    mouse_send_data(0xf4);//向鼠标发送0xF4命令,开始工作

    EX1=0;//关掉外部中断以避开鼠标发回的应答

    delayms(100);

    EX1=1;//重开外部中断

    while(1)

    {  

    CLEARSCREEN;//清屏

    LCM1602_write_string(0,0,"x:");

    num(0,2,move_x);//x坐标值

    LCM1602_write_string(0,8,"y:");

    num(0,10,move_y);//y坐标值

    if(mouse_data[0]&0x01)//如果点下左键

    {

    LCM1602_write_string(1,0,"left");

    Speaker_output();//发出声音

    }

    else if(mouse_data[0]&0x02)//如果点下右键

    {

    LCM1602_write_string(1,0,"right");

    Speaker_output();//发出声音

    }

    else if(mouse_data[0]&0x04)//如果点下中键

    {

    LCM1602_write_string(1,0,"middle");

    Speaker_output();//发出声音

    }

    else

    {

    LCM1602_write_string(1,0,"nothing");

    }

    delayms(50);

    }

    }


    打赏捐赠
    0
    !我要举报这篇文章
    声明 本文由村网通注册会员上传并发布,村网通仅提供信息发布平台。文章仅代表作者个人观点,不代表村网通立场。本文如涉及侵权请及时联系我们,我们将在24小时内予以删除!