天堂草原最受欢迎的角色,天堂动漫,天堂在线,色天堂下载,天堂中文在线资源,亚洲男人天堂

技術熱線: 4007-888-234

技術支持

QLdsPIC3] PS2協議 {C30+dsPIC30F6014A]

更新時間: 2019-03-23

深圳市英銳恩科技有限公司:臺灣麥肯單片機(Micon MDT單片機)亞太地區A級代理商

QLdsPIC3] PS2協議 {C30+dsPIC30F6014A]
//實驗目的:熟悉MCU與PS2設備通信
//軟件規劃:
//         1,采用查詢的方法檢測PS2設備發送過來的時鐘和數據
//         2,軟件只檢測字母(小寫)數字(左邊鍵盤)和數字鍵的通碼,暫時不能檢測斷碼。
//         3,不檢測組合鍵盤
//         4,掃描按鍵結果送LCD1602顯示
//硬件要求:
//         1,撥碼開關S4全部置ON端
//         2,連接好鍵盤
//         3,跳線J18全部接通
#include             //dsPIC30F6014標準頭文件

  _FOSC(0x0ffe5);                 //XT振蕩,4倍頻晶振.
  _FWDT(WDT_OFF);                 //關閉看門狗定時器
  _FBORPOR(PBOR_OFF & MCLR_EN);   //掉電復位禁止,MCLR復位使能。
  _FGS(CODE_PROT_OFF);            //代碼保護禁止

unsigned char __attribute__((address(0x900))) recdata1;    //按鍵結果緩存單元1
unsigned char __attribute__((address(0x902))) recdata2;    //按鍵結果緩存單元2
unsigned char __attribute__((address(0x904))) result;      //按鍵的ASCII碼保存單元
unsigned char __attribute__((address(0x906))) result1;
unsigned char __attribute__((address(0x908))) count;       //循環次數
unsigned int  __attribute__((address(0x90a))) temp;        //臨時單元
unsigned char __attribute__((address(0x9a0))) loop;        //LCD顯示次數計數器

#define rs LATBbits.LATB4            //定義LCD控制位(注意這里只能用LATB寄存器,不能直接用PORTB寄存器)
#define rw LATBbits.LATB5            //定義LCD的RW控制信號
#define e  LATBbits.LATB6            //定義LCD的使能信號E

unsigned char const noshift[80][2]=  //shift鍵不按下時按鍵的鍵碼與ASCII對應表
{
//鍵盤碼  ASCII碼
    22     ,49,  // { 1 }
   30    ,50,  // { 2 }
    38    ,51,  // { 3 }
 37    ,52,  // { 4 }
 46     ,53,  // { 5 }
 54     ,54,  // { 6 }
 61     ,55,  // { 7 }
 62    ,56,  // { 8 }
 70     ,57,  // { 9 }
 69     ,48,  // { 0 }

 28     ,97,  // { a }
 50     ,98,  // { b }
 33     ,99,  // { c }
 35     ,100, // { d }
 36     ,101, // { e }
 43     ,102, // { f }
 52     ,103, // { g }
 51     ,104, // { h }
 67     ,105, // { i }
 59     ,106, // { j }

 66     ,107, // { k }
 75     ,108, // { l }
 58     ,109, // { m }
 49     ,110, // { n }
 68     ,111, // { o }
 77     ,112, // { p }
 21     ,113, // { q }
 45     ,114, // { r }
 27     ,115, // { s }
 44     ,116, // { t }

 60     ,117, // { u }
 42     ,118, // { v }
 29     ,119, // { w }
 34     ,120, // { x }
 53     ,121, // { y }
 26     ,122, // { z }
 84     ,91,  // { [ }
 91     ,93,  // { ] }
 76     ,59,  // { ; }
 82     ,39,  // { ' }

 65     ,44,  // { , }
 73     ,46,  // { . }
 74     ,47,  // { / }
 78     ,45,  // { - }
 85     ,61,  // { = }
 93     ,92,  // { \ }
 14     ,96,  // { ` }
 90     ,32,  // { enter }
 5      ,0,   // { f1 }
 6      ,1,   // { f2 }

 4      ,2,   // { f3 }
 12     ,3,   // { f4 }
 3      ,4,   // { f5 }
 11     ,5,   // { f6 }
 131    ,6,   // { f7 }
 10     ,7,   // { f8 }
 1      ,8,   // { f9 }
 9      ,9,   // { f10 }
 120    ,10,  // { f11 }
 7      ,11,  // { f12 }

 102    ,12,  // { back }
 224    ,13,  // { home }
 105    ,14,  // { end }
 125    ,15,  // { pageup }
 122    ,16,  // { pagedown }
 117    ,17,  // { up }
 114    ,18,  // { down }
 107    ,19,  // { left }
 116    ,20,  // { right }
 113    ,21,  // { del }

 112    ,22,  // { insert }
 225    ,23,  // { pause }
 118    ,24,  // { esc }
 13     ,25,  // { tab }
 88     ,26,  // { caps }
 20     ,27,  // { ctrl }
 17     ,28,  // { alt }
 41     ,29,  // { space }
 31     ,30,  // { win }
 47    ,31,   // { winright
};

unsigned char const addshift[47][2]=           //shift鍵按下時按鍵的鍵碼與ASCII對應表
{
 14 ,126,   // { ~ }
 22 , 33,   // { ! }
 30 , 64,   // { @ }
 38 , 35,   // { # }
 37 , 36,   // { $ }
 46 , 37,   // { % }
 54 , 94,   // { ^ }
 61 , 38,   // { & }
 62 , 42,   // { * }
 70 , 40,   // { ( }

 69 , 41,   // { ) }
 78 , 95,   // { _ }
 85 , 43,   // { + }
 93 ,124,   // { | }
 84 ,123,   // { { }
 91 ,125,   // { } }
 76 , 58,   // { : }
 82 , 34,   // { " }
 65 , 60,   // { < }
 73 , 62,   // { > }

 74 , 63,   // { ? }
 28  ,65,    // { a }
 50  ,66,    // { b }
 33  ,67,    // { c }
 35  ,68,    // { d }
 36  ,69,    // { e }
 43  ,70, // { f }
 52  ,71, // { g }
 51  ,72, // { h }
 67  ,73, // { i }

 59  ,74, // { j }
 66  ,75, // { k }
 75  ,76, // { l }
 58  ,77, // { m }
 49  ,78, // { n }
 68  ,79, // { o }
 77  ,80, // { p }
 21  ,81, // { q }
 45  ,82, // { r }
 27  ,83, // { s }

 44  ,84, // { t }
 60  ,85, // { u }
 42  ,86, // { v }
 29  ,87, // { w }
 34  ,88, // { x }
 53  ,89, // { y }
 26  ,90, // { z }
};

void init();                          //I/O口初始化函數
void getkey();                        //讀取按鍵鍵碼函數
void judge();                         //鍵碼轉換成ASCII碼
void lcd_display(unsigned char res);  //LCD顯示函數

void lcd_init();                      //申明LCD初始化函數
void write_web();                     //申明顯示公司web地址函數
void write(unsigned int x);           //申明顯示1字節數據函數
void lcd_enable();                    //申明LCD顯示設置函數
void delay();                         //申明延時函數

//************************初始化函數**************************
void init()
{
 TRISC=0X0018;
    TRISB=0X0000;                     //設置B口為輸出
    TRISD=0X0000;                     //設置D口為輸出
    result=0;
    result1=0;
}

//********************讀取按鍵鍵碼函數*************************
void getkey()
{
    unsigned char i;
 temp=0;
    for(count=1;count<21;count++)    //循環20次(第1字節的1bit起始位,8bit數據,1bit校驗位,1bit停止位,第2字節的1bit起始位和8bit數據,忽略校驗位和停止位)
       {
         while(PORTCbits.RC4);       //等待低電平
         while(!PORTCbits.RC4)       //低電平
          {
           for(i=0;i<15;i++);        //延時一定時間,保證下降沿足夠時間
           if(count<10|count>12)     //只讀取數據位,忽略起始位和校驗位,停止位
             {
               temp=temp>>1;         //讀取的數據右移1位(傳輸時低位在前)
               if(PORTCbits.RC3) temp=temp|0x8000;   //若為高,最高位加1
               else temp=temp&0x7fff;                //若為低,最高位清0
             }
           while(!PORTCbits.RC4);    //等待恢復為高電平(下降沿讀取數據)
          }
       }
    recdata1=0;
    recdata2=0;
    recdata1=(unsigned char)temp&0x00ff;             //按鍵碼低8位
    recdata2=(unsigned char)((temp>>8)&0x00ff);      //按鍵碼高8位
}

//*********************按鍵碼轉ASCII碼**************************
void judge()
{
   unsigned char i;
   if(!(recdata1==0xf0))                            //若按鍵碼低8位為0XF0,則是按鍵的斷碼
   {
    if(recdata1==0x12)                              //shift有按下
    {
      if(recdata2=0xf0) return;                     //若只有shift按下,則返回
      for(i=0;i<47;i++)                             //查找shift按下時按鍵的ASCII碼
        {
          if(addshift[i][0]==recdata2)
             {
               result=addshift[i][1];              //返回讀取的ASCII碼
               break;
             }
        }
    }
   else                                            //shift鍵沒有按下
    {
      for(i=0;i<80;i++)
        {
          if(noshift[i][0]==recdata1)
             {
               result=noshift[i][1];
               break;
             }
        }
     }
 }
}


//*******************LCD初始化函數*******************************
void lcd_init()
 {
    PORTD=0X1;                 //清除顯示
    lcd_enable();
    PORTD=0X38;                //8位2行5*7點陣
    lcd_enable();
    PORTD=0X0e;                //顯示開,光標開,閃爍
    lcd_enable();
    PORTD=0X06;                //文字不動,光標右移
    lcd_enable();
    PORTD=0X80;                //產品名字顯示地址
    lcd_enable();
 }
 
//*********************LCD顯示函數*******************************
void lcd_display(unsigned char res)
 {
    unsigned char j;
         if(loop<16)           //一行只顯示16字符
          {
           write(res);          //寫一個字節數據函數送LCD顯示
           loop++;
           for(j=0;j<5;j++)      //延時一段時間(主要是為了控制顯示的速度)
            {
              delay();
            }
           }
         else
           {
             loop=0;
             PORTD=0X80;           //重頭開始顯示
             lcd_enable();
             write(res);          //寫一個字節數據函數送LCD顯示
           }
 }

//*****************寫一個字節數據函數***************************
//在電平發生改變后需要插入一段延時時間,否則LCD反應不過來。
void write(unsigned int x)
 {
  PORTD=x;                   //待顯示數據送PORTD口
  delay();                  
  rs=1;                      //該字節數據為數據,而不是命令
  delay();
  rw=0;                      //此次操作為寫,而不是讀
  delay();
  e=0;                       //拉低使能信號
  delay();                   //保持使能信號為低一段時間
  e=1;                       //拉高使能信號,建立LCD操作所需要的上升沿
  delay();
 }


//******************LCD顯示設置函數*****************************
//在電平發生改變后需要插入一段延時時間,否則LCD反應不過來。
void lcd_enable()
 {
   delay();
   rs=0;                     //該字節數據為命令,而不是數據
   delay();
   rw=0;                     //此次操作為寫,而不是讀
   delay();
   e=0;                      //拉低使能信號
   delay();                  //保持使能信號為低一段時間
   e=1;                      //拉高使能信號,建立LCD操作所需要的上升沿
   delay();
}


//**********************延時函數*********************************
void delay()
 {
   unsigned int i;
   for(i=0;i<100;i++);
 }

//**********************主函數***********************************
int main(void)
{  
    unsigned char m, k=0;
    delay();
    delay();
    delay();
    delay();
    delay();               //延時一段時間,保證鍵盤,LCD等工作穩定
    init();                //調用I/O口初始化函數
    lcd_init();            //調用LCD初始化函數
    while(1)
     {
       getkey();           //調用讀取按鍵碼函數
       judge();            //調用按鍵碼轉ASCII碼函數
       if(recdata1!=0x12) lcd_display(result);   //如按下鍵不為shift則送LCD顯示
       for(m=0;m<100;m++)  //延長一段時間
       {
       delay();
       delay();
       }
     }
}

404
返回首頁 |  返回上一頁
联系我们: 定安县| 平定县| 黑水县| 遵化市| 洪洞县| 沙湾县| 化州市| 长治县| 辽阳县| 温宿县| 安乡县| 新野县| 和林格尔县| 常熟市| 大宁县| 吉木乃县| 江西省| 双鸭山市| 鄱阳县| 平安县| 特克斯县| 额敏县| 福州市| 九江市| 彝良县| 柳州市| 城口县| 敖汉旗| 恭城| 盱眙县| 监利县| 汪清县| 罗平县| 肥城市| 宿州市| 宜良县| 渭南市| 遵义县| 交口县| 龙游县| 凤山市|