找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 2374|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

PXA270矩陣鍵盤與數(shù)碼管試驗(yàn)報(bào)告

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:108615 發(fā)表于 2016-3-14 16:47 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
實(shí)驗(yàn)?zāi)康?/font>
①學(xué)習(xí)如何配置鍵盤控制器的寄存器
②掌握鍵盤掃描程序的實(shí)現(xiàn)過程

實(shí)驗(yàn)內(nèi)容
①熟悉PXA270提供的鍵盤接口
②分析Eeliod實(shí)驗(yàn)平臺(tái)的鍵盤原理圖
③參考示例程序?qū)崿F(xiàn)矩陣鍵盤掃描,利用數(shù)碼管顯示區(qū)分不同按鍵
④編譯程序,下載執(zhí)行,驗(yàn)證程序工作是否正常

實(shí)驗(yàn)原理
①鍵盤控制
矩陣鍵盤的掃描方式有多種,逐行掃描,翻轉(zhuǎn)掃描等,本實(shí)驗(yàn)中由于PXA270自帶了鍵盤控制器,且輸入輸出口是單向的,所以只能采用逐行掃描方式。本實(shí)驗(yàn)采用手動(dòng)掃描,不利用中斷,掃描控制方式與一般的矩陣鍵盤掃描方式一樣,都是列線上逐位送出高電平,行線讀取電平值,如果讀取到高電平則說明在當(dāng)前列線和讀到的行線交叉點(diǎn)的按鍵被按下了。該實(shí)驗(yàn)主要工作是設(shè)置鍵盤控制器相應(yīng)的寄存器和讀取相應(yīng)的寄存器。通過設(shè)置鍵盤接口寄存器KPC中相應(yīng)的位來控制矩陣鍵盤4個(gè)列信號(hào)逐位為高,通過讀取矩陣鍵盤寄存器KPMK中相應(yīng)的位來判斷矩陣鍵盤4個(gè)行信號(hào)的高低,進(jìn)而根據(jù)當(dāng)前的列信號(hào)狀態(tài)來確定按鍵的物理坐標(biāo)。
②數(shù)碼管控制
數(shù)碼管控制與實(shí)驗(yàn)一中的數(shù)碼管控制方法一樣。

實(shí)驗(yàn)步驟
第一步 分析代碼
結(jié)合以上說明,對(duì)本實(shí)驗(yàn)提供的示例代碼分析,深入理解針對(duì)具體的硬件實(shí)現(xiàn),軟件是如何配合工作的。
第二步 程序的編譯和下載
利用ADS打開示例工程文件,執(zhí)行Project→Make,編譯、鏈接生成可執(zhí)行映像文件
第三步 觀察系統(tǒng)運(yùn)行情況,對(duì)系統(tǒng)進(jìn)行源碼調(diào)試

程序說明
①鍵盤程序
鍵盤程序通過依次給出列線高電平讀行線電平狀態(tài)來判斷當(dāng)前按下的按鍵的位置,通過讀寫相應(yīng)的寄存器即可,由于鍵盤實(shí)際連線對(duì)應(yīng)的IO口實(shí)際上不是連續(xù)的,導(dǎo)致須通過4次判斷來完成,而不是利用循環(huán)實(shí)現(xiàn)。
②數(shù)碼管程序
數(shù)碼管程序在實(shí)驗(yàn)一中已經(jīng)寫過,本次實(shí)驗(yàn)可以直接使用
③主程序
主程序?yàn)橐凰姥h(huán),通過觸發(fā)手動(dòng)鍵盤掃描函數(shù),讀取到鍵盤按下的按鍵,判斷鍵值,進(jìn)行相應(yīng)的處理

程序源代碼、注釋
①鍵盤程序
1)MyKeypad.h
#ifndef __MyKeypad_h__
#define __MyKeypad_h__

extern unsigned char KeypadScan(void);

#endif
2)MyKeypad.c
#define KPC_VALUE    (*((volatile unsigned int *)(0x41500000)))  //鍵盤接口控制寄存器
#define KPMK_VALUE (*((volatile unsigned int *)(0x41500018)))  //矩陣鍵盤寄存器,讀取掃描的狀態(tài)

//這句宏定義控制鍵盤掃描返回值,不注釋時(shí)返回是4x4矩陣鍵盤的實(shí)際物理坐標(biāo),從上到下從左到右為0x00~0x0F
//注釋掉后返回的是4x4矩陣鍵盤按鍵上印刷的ASCII字符
//#define KEYPAD_RETPHY

void Delay(unsigned int x)
{
       unsignedint i, j, k;
       for(i =0; i <=x; i++)
              for (j = 0; j <0xff; j++)
                     for(k = 0; k <0xff; k++)
                     ;
}

unsigned char KeypadScan(void)
{
       unsignedshort int inRow;
      
       //掃描第一列
       KPC_VALUE&= 0xFFE01FFF;  //先將列線全復(fù)位拉低
       KPC_VALUE|= (0x01 << 13);     //再將列線第一列置1
       Delay(1);
       inRow= KPMK_VALUE;
       Delay(1);
      
       if(inRow== KPMK_VALUE)      //消抖后還相等表明確實(shí)有按鍵按下
       {
              switch(inRow & 0xFF)
              {
                     
                     #ifdefKEYPAD_RETPHY
                     //注意這里返回的是掃描到的按鍵的物理坐標(biāo),從鍵盤左上角到右下角分別為0x00~0x0F
                            case 0x01:      return 0x00;
                            case 0x02:      return 0x04;
                            case 0x04:      return 0x08;
                            case 0x20:      return 0x0C;
                            default:;
                     #else
                     //注意這里返回的是鍵盤上印刷的字符的ASCII
                            case 0x01:      return '1';
                            case 0x02:      return '4';
                            case 0x04:      return '7';
                            case 0x20:      return '*';
                            default:;
                     #endif                  
              }
       }
      
       //掃描第二列
       KPC_VALUE&= 0xFFE01FFF;  //先將列線全復(fù)位拉低
       KPC_VALUE|= (0x01 << 14);     //再將列線第二列置1
       Delay(1);
       inRow= KPMK_VALUE;
       Delay(1);
      
       if(inRow== KPMK_VALUE)      //消抖后還相等表明確實(shí)有按鍵按下
       {
              switch(inRow & 0xFF)
              {
                     
                     #ifdefKEYPAD_RETPHY
                     //注意這里返回的是掃描到的按鍵的物理坐標(biāo),從鍵盤左上角到右下角分別為0x00~0x0F
                            case 0x01:      return 0x01;
                            case 0x02:      return 0x05;
                            case 0x04:      return 0x09;
                            case 0x20:      return 0x0D;
                            default:;
                     #else
                     //注意這里返回的是鍵盤上印刷的字符的ASCII
                            case 0x01:      return '2';
                            case 0x02:      return '5';
                            case 0x04:      return '8';
                            case 0x20:      return '0';
                            default:;
                     #endif                  
              }
       }
      
       //掃描第三列
       KPC_VALUE&= 0xFFE01FFF;  //先將列線全復(fù)位拉低
       KPC_VALUE|= (0x01 << 15);     //再將列線第三列置1
       Delay(1);
       inRow= KPMK_VALUE;
       Delay(1);
      
       if(inRow== KPMK_VALUE)      //消抖后還相等表明確實(shí)有按鍵按下
       {
              switch(inRow & 0xFF)
              {
                     
                     #ifdefKEYPAD_RETPHY
                     //注意這里返回的是掃描到的按鍵的物理坐標(biāo),從鍵盤左上角到右下角分別為0x00~0x0F
                            case 0x01:      return 0x03;
                            case 0x02:      return 0x06;
                            case 0x04:      return 0x0A;
                            case 0x20:      return 0x0E;
                            default:;
                     #else
                     //注意這里返回的是鍵盤上印刷的字符的ASCII
                            case 0x01:      return '3';
                            case 0x02:      return '6';
                            case 0x04:      return '9';
                            case 0x20:      return '#';
                            default:;
                     #endif                  
              }
       }
      
       //掃描第四列
       KPC_VALUE&= 0xFFE01FFF;  //先將列線全復(fù)位拉低
       KPC_VALUE|= (0x01 << 19);     //再將列線第四列置1
       Delay(1);
       inRow= KPMK_VALUE;
       Delay(1);
      
       if(inRow== KPMK_VALUE)      //消抖后還相等表明確實(shí)有按鍵按下
       {
              switch(inRow & 0xFF)
              {
                     
                     #ifdefKEYPAD_RETPHY
                     //注意這里返回的是掃描到的按鍵的物理坐標(biāo),從鍵盤左上角到右下角分別為0x00~0x0F
                            case 0x01:      return 0x03;
                            case 0x02:      return 0x07;
                            case 0x04:      return 0x0B;
                            case 0x20:      return 0x0F;
                            default:;
                     #else
                     //注意這里返回的是鍵盤上印刷的字符的ASCII
                            case 0x01:      return 'A';
                            case 0x02:      return 'B';
                            case 0x04:      return 'C';
                            case 0x20:      return 'D';
                            default:;
                     #endif                  
              }
       }
      
       return0xFF;
}
②數(shù)碼管程序
本次實(shí)驗(yàn)使用的數(shù)碼管程序?yàn)閷?shí)驗(yàn)一中的數(shù)碼管程序,可以直接使用。
③主函數(shù)
#include "SegLed.h"
#include "MyKeypad.h"

int main()
{
       unsignedchar keyValue;
       shorttempDisp = 0;
              
//這幾句用于調(diào)試時(shí)單步執(zhí)行查看結(jié)果
       SegLedDispNum(123,DISP_BLANKING);
       SegLedDispNum(23,DISP_BLANKING);
       SegLedDispNum(3,DISP_BLANKING);
       SegLedDispNum(0,DISP_BLANKING);
      
       while(1)
       {
//手動(dòng)掃描一次矩陣鍵盤,得到按鍵的ASCII碼
              keyValue = KeypadScan();
              switch(keyValue)
              {
                     //普通數(shù)字鍵
                     case'0':
                     case'1':
                     case'2':
                     case'3':
                     case'4':
                     case'5':
                     case'6':
                     case'7':
                     case'8':
                     case'9':
                     {
                            tempDisp = tempDisp * 10 + keyValue - '0';
                            if(tempDisp > 9999)
                                   tempDisp= 0;
                                   
                            SegLedDispNum(tempDisp, DISP_BLANKING);
                            break;
                     }
                     
                     //取消鍵
                     case'*':
                     {
                            break;
                     }

                     //確認(rèn)鍵
                     case'#':
                     {
                            break;
                     }
                     
                     //清零鍵
                     case'A':
                     {
                            tempDisp = 0;
                            SegLedDispNum(tempDisp, DISP_BLANKING);
                            break;
                     }
                     
                     //退位鍵
                     case'B':
                     {
                            tempDisp /= 10;
                            SegLedDispNum(tempDisp, DISP_BLANKING);
                            break;
                     }
                     
                     case'C':
                     {
                            break;
                     }
                     
                     case'D':
                     {
                            break;
                     }
                     
                     default:
                            break;
              }     //endof switch(keyValue)
       }     //end of while(1)

}     //endof main()


總結(jié)
在鍵盤程序中,在語(yǔ)句中間定義了變量,編譯時(shí)提示錯(cuò)誤,看錯(cuò)誤的提示,沒有發(fā)現(xiàn)問題,后來突然想到之前Keil中在語(yǔ)句中間定義變量C51的編譯器也提示錯(cuò)誤,將變量定義放在函數(shù)開頭,果然編譯正確。

嵌入式實(shí)驗(yàn)報(bào)告.rar

34.79 KB, 下載次數(shù): 8, 下載積分: 黑幣 -5

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表