機(jī)電之家資源網(wǎng)
單片機(jī)首頁|單片機(jī)基礎(chǔ)|單片機(jī)應(yīng)用|單片機(jī)開發(fā)|單片機(jī)文案|軟件資料下載|音響制作|電路圖下載 |嵌入式開發(fā)
培訓(xùn)信息
贊助商
單片機(jī)與PS/2鍵盤應(yīng)用實(shí)例
單片機(jī)與PS/2鍵盤應(yīng)用實(shí)例
 更新時間:2008-7-27 16:11:25  點(diǎn)擊數(shù):2
【字體: 字體顏色

 

SMC1602A(16*2)模擬口線接線方式
連接線圖:

------------------------------------------------
   |LCM-----51   | LCM-----51   | LCM------51      |
   |-------------|--------------|------------------|
   |DB0-----P1.0 | DB4-----P1.4 | RW-------P2.0    |
   |DB1-----P1.1 | DB5-----P1.5 | RS-------P2.1    |
   |DB2-----P1.2 | DB6-----P1.6 | E--------P2.2    |
   |DB3-----P1.3 | DB7-----P1.7 | VLCD接1K電阻到GND|
   -------------------------------------------------

PS/2的電氣特性如下(電腦端):

Keyboard接線
    PS/2--------51單片機(jī)
    1 DATA------P3.4
    2 不接
    3 GND
    4 VCC
    5 CLK-------P3.3 接在51的外部中斷,觸發(fā)方式為低電平
    6 不接

本程序源碼只供學(xué)習(xí)參考,不得應(yīng)用于商業(yè)用途,如有需要請聯(lián)系作者。

[注:AT89x51使用12M或11.0592M晶振,實(shí)測使用11.0592M]
[Keil uV2 7.01編譯運(yùn)行通過 程序中沒有做鍵盤數(shù)據(jù)的奇偶校驗(yàn)]

[站長在AT89S51+12M晶振+JHD 162A液晶上調(diào)試通過]

=============================================================*/

#include "reg51.h"#include "scancodes.h"#define LCM_RW  P2_0//定義LCD引腳#define LCM_RS  P2_1#define LCM_E   P2_2#define LCM_Data  P1#define Key_Data P3_4//定義Keyboard引腳#define Key_CLK  P3_3#define Busy    0x80//用于檢測LCM狀態(tài)字中的Busy標(biāo)識void LCMInit(void);void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);void Delay5Ms(void);void Delay400Ms(void);void Decode(unsigned char ScanCode);void WriteDataLCM(unsigned char WDLCM);void WriteCommandLCM(unsigned char WCLCM,BuysC);unsigned char ReadDataLCM(void);unsigned char ReadStatusLCM(void);unsigned char code cdle_net[] = {"www.cdle.net--"};unsigned char code email[] = {"pnzwzw@cdle.net"};unsigned char code Cls[] = {"                "};static unsigned char IntNum = 0;//中斷次數(shù)計(jì)數(shù)static unsigned char KeyV;//鍵值static unsigned char DisNum = 0;//顯示用指針static unsigned char Key_UP=0, Shift = 0;//Key_UP是鍵松開標(biāo)識,Shift是Shift鍵按下標(biāo)識static unsigned char BF = 0;//標(biāo)識是否有字符被收到void main(void){        unsigned char TempCyc;                Delay400Ms();//啟動等待,等LCM講入工作狀態(tài)        LCMInit();//LCM初始化        Delay5Ms();//延時片刻(可不要)                DisplayListChar(0, 0, cdle_net);        DisplayListChar(0, 1, email);        ReadDataLCM();//測試用句無意義        for (TempCyc=0; TempCyc<10; TempCyc++)        Delay400Ms();//延時        DisplayListChar(0, 1, Cls);                IT1 = 0;//設(shè)外部中斷1為低電平觸發(fā)        EA = 1;        EX1 = 1;//開中斷                do        {                if (BF)                Decode(KeyV);                else                EA = 1;//開中斷        }        while(1);}//寫數(shù)據(jù)void WriteDataLCM(unsigned char WDLCM){        ReadStatusLCM();//檢測忙        LCM_Data = WDLCM;        LCM_RS = 1;        LCM_RW = 0;        LCM_E = 0;//若晶振速度太高可以在這后加小的延時        LCM_E = 0;//延時        LCM_E = 1;}//寫指令void WriteCommandLCM(unsigned char WCLCM,BuysC)//BuysC為0時忽略忙檢測{        if (BuysC) ReadStatusLCM();//根據(jù)需要檢測忙        LCM_Data = WCLCM;        LCM_RS = 0;        LCM_RW = 0;        LCM_E = 0;        LCM_E = 0;        LCM_E = 1;}//讀數(shù)據(jù)unsigned char ReadDataLCM(void){        LCM_RS = 1;        LCM_RW = 1;        LCM_E = 0;        LCM_E = 0;        LCM_E = 1;        return(LCM_Data);}//讀狀態(tài)unsigned char ReadStatusLCM(void){        LCM_Data = 0xFF;        LCM_RS = 0;        LCM_RW = 1;        LCM_E = 0;        LCM_E = 0;        LCM_E = 1;        while (LCM_Data & Busy);//檢測忙信號        return(LCM_Data);}void LCMInit(void)//LCM初始化{        LCM_Data = 0;        WriteCommandLCM(0x38,0);//三次顯示模式設(shè)置,不檢測忙信號        Delay5Ms();        WriteCommandLCM(0x38,0);        Delay5Ms();        WriteCommandLCM(0x38,0);        Delay5Ms();                WriteCommandLCM(0x38,1);//顯示模式設(shè)置,開始要求每次檢測忙信號        WriteCommandLCM(0x08,1);//關(guān)閉顯示        WriteCommandLCM(0x01,1);//顯示清屏        WriteCommandLCM(0x06,1);// 顯示光標(biāo)移動設(shè)置        WriteCommandLCM(0x0F,1);// 顯示開及光標(biāo)設(shè)置}//按指定位置顯示一個字符void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData){        Y &= 0x1;        X &= 0xF;//限制X不能大于15,Y不能大于1        if (Y) X |= 0x40;//當(dāng)要顯示第二行時地址碼+0x40;        X |= 0x80;//算出指令碼        WriteCommandLCM(X, 1);//發(fā)命令字        WriteDataLCM(DData);//發(fā)數(shù)據(jù)}//按指定位置顯示一串字符void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData){        unsigned char ListLength;                ListLength = 0;        Y &= 0x1;        X &= 0xF;//限制X不能大于15,Y不能大于1        while (DData[ListLength]>0x19)//若到達(dá)字串尾則退出        {                if (X <= 0xF)//X坐標(biāo)應(yīng)小于0xF                {                        DisplayOneChar(X, Y, DData[ListLength]);//顯示單個字符                        ListLength++;                        X++;                }        }}//5ms延時void Delay5Ms(void){        unsigned int TempCyc = 5552;        while(TempCyc--);}//400ms延時void Delay400Ms(void){        unsigned char TempCycA = 5;        unsigned int TempCycB;        while(TempCycA--)        {                TempCycB=7269;                while(TempCycB--);        };}void Keyboard_out(void) interrupt 2{        if ((IntNum > 0) && (IntNum < 9))        {                KeyV = KeyV >> 1;//因鍵盤數(shù)據(jù)是低>>高,結(jié)合上一句所以右移一位                if (Key_Data) KeyV = KeyV | 0x80;//當(dāng)鍵盤數(shù)據(jù)線為1時為1到最高位        }        IntNum++;        while (!Key_CLK);//等待PS/2CLK拉高                if (IntNum > 10)        {                IntNum = 0;//當(dāng)中斷10次后表示一幀數(shù)據(jù)收完,清變量準(zhǔn)備下一次接收                BF = 1;//標(biāo)識有字符輸入完了                EA = 0;//關(guān)中斷等顯示完后再開中斷 (注:如這里不用BF和關(guān)中斷直接調(diào)Decode()則所Decode中所調(diào)用的所有函數(shù)要聲明為再入函數(shù))        }}void Decode(unsigned char ScanCode)//注意:如SHIFT+G為12H 34H F0H 34H F0H 12H,也就是說shift的通碼+G的通碼+shift的斷碼+G的斷碼{        unsigned char TempCyc;                if (!Key_UP)//當(dāng)鍵盤松開時        {                switch (ScanCode)                {                        case 0xF0 :// 當(dāng)收到0xF0,Key_UP置1表示斷碼開始                        Key_UP = 1;                        break;                                                case 0x12 :// 左 SHIFT                        Shift = 1;                        break;                                                case 0x59 :// 右 SHIFT                        Shift = 1;                        break;                                                default:                        if (DisNum > 15)                        {                                DisplayListChar(0, 1, Cls);//清LCD第二行                                DisNum = 0;                        }                        if(!Shift)//如果SHIFT沒按下                        {                                for (TempCyc = 0;(UnShifted[TempCyc][0]!=ScanCode)&&(TempCyc<59); TempCyc++);//查表顯示                                if (UnShifted[TempCyc][0] == ScanCode) DisplayOneChar(DisNum, 1, UnShifted[TempCyc][1]);                                DisNum++;                        }                        else//按下SHIFT                        {                                for(TempCyc = 0; (Shifted[TempCyc][0]!=ScanCode)&&(TempCyc<59); TempCyc++);//查表顯示                                if (Shifted[TempCyc][0] == ScanCode) DisplayOneChar(DisNum, 1, Shifted[TempCyc][1]);                                DisNum++;                        }                                                break;                }        }        else        {                Key_UP = 0;                switch (ScanCode)//當(dāng)鍵松開時不處理判碼,如G 34H F0H 34H 那么第二個34H不會被處理                {                        case 0x12 :// 左 SHIFT                        Shift = 0;                        break;                                                case 0x59 :// 右 SHIFT                        Shift = 0;                        break;                }        }        BF = 0;//標(biāo)識字符處理完了}以下為 scancodes.h 文件unsigned char code UnShifted[59][2] = {        0x1C, 'a',        0x32, 'b',        0x21, 'c',        0x23, 'd',        0x24, 'e',        0x2B, 'f',        0x34, 'g',        0x33, 'h',        0x43, 'i',        0x3B, 'j',        0x42, 'k',        0x4B, 'l',        0x3A, 'm',        0x31, 'n',        0x44, 'o',        0x4D, 'p',        0x15, 'q',        0x2D, 'r',        0x1B, 's',        0x2C, 't',        0x3C, 'u',        0x2A, 'v',        0x1D, 'w',        0x22, 'x',        0x35, 'y',        0x1A, 'z',        0x45, '0',        0x16, '1',        0x1E, '2',        0x26, '3',        0x25, '4',        0x2E, '5',        0x36, '6',        0x3D, '7',        0x3E, '8',        0x46, '9',        0x0E, '`',        0x4E, '-',        0x55, '=',        0x5D, '\\',        0x29, ' ',        0x54, '[',        0x5B, ']',        0x4C, ';',        0x52, '\'',        0x41, ',',        0x49, '.',        0x4A, '/',        0x71, '.',        0x70, '0',        0x69, '1',        0x72, '2',        0x7A, '3',        0x6B, '4',        0x73, '5',        0x74, '6',        0x6C, '7',        0x75, '8',        0x7D, '9',};unsigned char code Shifted[59][2] = {        0x1C, 'A',        0x32, 'B',        0x21, 'C',        0x23, 'D',        0x24, 'E',        0x2B, 'F',        0x34, 'G',        0x33, 'H',        0x43, 'I',        0x3B, 'J',        0x42, 'K',        0x4B, 'L',        0x3A, 'M',        0x31, 'N',        0x44, 'O',        0x4D, 'P',        0x15, 'Q',        0x2D, 'R',        0x1B, 'S',        0x2C, 'T',        0x3C, 'U',        0x2A, 'V',        0x1D, 'W',        0x22, 'X',        0x35, 'Y',        0x1A, 'Z',        0x45, '0',        0x16, '1',        0x1E, '2',        0x26, '3',        0x25, '4',        0x2E, '5',        0x36, '6',        0x3D, '7',        0x3E, '8',        0x46, '9',        0x0E, '~',        0x4E, '_',        0x55, '+',        0x5D, '|',        0x29, ' ',        0x54, '{',        0x5B, '}',        0x4C, ':',        0x52, '"',        0x41, '<',        0x49, '>',        0x4A, '?',        0x71, '.',        0x70, '0',        0x69, '1',        0x72, '2',        0x7A, '3',        0x6B, '4',        0x73, '5',        0x74, '6',        0x6C, '7',        0x75, '8',        0x7D, '9',};
  • 上一篇: 最簡單的Keil C51程序
  • 下一篇: PS/2 PC鍵盤編程資料
  • 發(fā)表評論   告訴好友   打印此文  收藏此頁  關(guān)閉窗口  返回頂部
    熱點(diǎn)文章
     
    推薦文章
     
    相關(guān)文章
    網(wǎng)友評論:(只顯示最新5條。)
    關(guān)于我們 | 聯(lián)系我們 | 廣告合作 | 付款方式 | 使用幫助 | 機(jī)電之家 | 會員助手 | 免費(fèi)鏈接

    點(diǎn)擊這里給我發(fā)消息66821730(技術(shù)支持)點(diǎn)擊這里給我發(fā)消息66821730(廣告投放) 點(diǎn)擊這里給我發(fā)消息41031197(編輯) 點(diǎn)擊這里給我發(fā)消息58733127(審核)
    本站提供的機(jī)電設(shè)備,機(jī)電供求等信息由機(jī)電企業(yè)自行提供,該企業(yè)負(fù)責(zé)信息內(nèi)容的真實(shí)性、準(zhǔn)確性和合法性。
    機(jī)電之家對此不承擔(dān)任何保證責(zé)任,有侵犯您利益的地方請聯(lián)系機(jī)電之家,機(jī)電之家將及時作出處理。
    Copyright 2007 機(jī)電之家 Inc All Rights Reserved.機(jī)電之家-由機(jī)電一體化網(wǎng)更名-聲明
    電話:0571-87774297 傳真:0571-87774298
    杭州濱興科技有限公司提供技術(shù)支持

    主辦:杭州市高新區(qū)(濱江)機(jī)電一體化學(xué)會
    中國行業(yè)電子商務(wù)100強(qiáng)網(wǎng)站

    網(wǎng)站經(jīng)營許可證:浙B2-20080178-1