0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

stc52單片機(jī)鍵盤原理圖及程序介紹

jf_f8pIz0xS ? 來源:電子發(fā)燒友整理 ? 2018-02-09 11:18 ? 次閱讀

STC89C52RC是STC公司生產(chǎn)的一種低功耗、高性能CMOS8位微控制器,具有8K字節(jié)系統(tǒng)可編程Flash存儲器。STC89C52使用經(jīng)典的MCS-51內(nèi)核,但是做了很多的改進(jìn)使得芯片具有傳統(tǒng)51單片機(jī)不具備的功能。在單芯片上,擁有靈巧的8 位CPU 和在系統(tǒng)可編程Flash,使得STC89C52為眾多嵌入式控制應(yīng)用系統(tǒng)提供高靈活、超有效的解決方案。

stc52單片機(jī)鍵盤原理圖

stc52單片機(jī)鍵盤原理圖及程序介紹

說明:

1. 獨立鍵盤部分

S2~S5為4個獨立鍵盤, 與單片機(jī)的P3.4~P3.7分別相連

2. 矩陣鍵盤部分

S6~S21為16個矩陣鍵盤,8條線分別與單片機(jī)的P3口相連, 其中矩陣鍵盤的4行分別與單片機(jī)的P3.0~P3.3相連,矩陣鍵盤的4列分別與單片機(jī)的P3.4~P3.7相連。

程序設(shè)計詳解

1. 用數(shù)碼管的前兩位顯示一個十進(jìn)制數(shù),變化范圍為00-59.

程序功能:

數(shù)碼管的前兩位顯示一個十進(jìn)制數(shù),變化范圍為00-59,開始時顯示00,每按下S2鍵一次,數(shù)值加1;每按下S3鍵一次,數(shù)值減1;每按下S4鍵一次,數(shù)值歸零;按下S5鍵一次,利用定時器功能使數(shù)值開始每秒加1,再次按下S5鍵,數(shù)值停止自動加1,保持原數(shù)。

程序源碼:

#include

#define uchar unsigned char

#define uint unsigned int

sbit key1 = P3 ^ 4;

sbit key2 = P3 ^ 5;

sbit key3 = P3 ^ 6;

sbit key4 = P3 ^ 7;

sbit dula = P2 ^ 6;

sbit wela = P2 ^ 7;

uchar code table[] = {

0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71

};

void init();

void keyscan();

void display(uchar);

void delayms(uint);

uchar t0, num;

void main()

{

init();

while (1)

{

keyscan();

display(num);

}

}

void init()

{

TMOD = 0x01;

TH0 = (65536 - 45872) / 256;

TL0 = (65536 - 45872) % 256;

EA = 1;

ET0 = 1;

}

void keyscan()

{

if (key1 == 0)

{

delayms(10);

if (key1 == 0)

{

if (num == 60)

num = 0;

num++;

while (!key1)

display(num);

}

}

if (key2 == 0)

{

delayms(10);

if (key2 == 0)

{

if (num == 0)

num = 60;

num--;

while (!key2)

display(num);

}

}

if (key3 == 0)

{

delayms(10);

if (key3 == 0)

{

num = 0;

while (!key3)

display(num);

}

}

if (key4 == 0)

{

delayms(10);

if (key4 == 0)

{

TR0 = ~TR0;

while (!key4)

display(num);

}

}

}

void display(uchar numDis)

{

dula = 1;

P0 = table[numDis / 10];

dula = 0;

P0 = 0xff;

wela = 1;

P0 = 0xfe;

wela = 0;

delayms(5);

dula = 1;

P0 = table[numDis % 10];

dula = 0;

P0 = 0xff;

wela = 1;

P0 = 0xfd;

wela = 0;

delayms(5);

}

void delayms(uint xms)

{

uint i, j;

for (i = xms; i 》 0; i--)

for (j = 110; j 》 0; j--)

;

}

void T0_timer() interrupt 1

{

TH0 = (65536 - 45872) / 256;

TL0 = (65536 - 45872) % 256;

t0++;

if (t0 == 20)

{

t0 = 0;

num++;

if (num == 60)

num = 0;

}

}

程序小結(jié):

a. 鍵盤按鍵檢測需要做兩次 (每個鍵盤按鍵用了兩個if)

b. 鍵盤按鍵退出也需要檢測 (每次按鍵退出用了一個while(!key))

c. 這段程序包含按鍵加1,按鍵減1,按鍵歸零,按鍵開始計數(shù),再按停止計數(shù)

2. 按矩陣鍵盤,在數(shù)碼管上顯示0~F,6個數(shù)碼管同時靜態(tài)顯示即可。

程序功能

上電不顯示, 按矩陣鍵盤,在數(shù)碼管上顯示0~F,6個數(shù)碼管同時靜態(tài)顯示即可。

程序源碼

#include

#define uchar unsigned char

#define uint unsigned int

sbit dula = P2 ^ 6;

sbit wela = P2 ^ 7;

uchar code table[] = {

0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71

};

void delayms(uint);

void display(uchar);

void matrixkeyscan();

void main()

{

dula = 1;

P0 = 0;

dula = 0;

wela = 1;

P0 = 0xc0;

wela = 0;

while (1)

{

matrixkeyscan();

}

}

void delayms(uint xms)

{

uint i, j;

for (i = xms; i 》 0; i--)

for (j = 110; j 》 0; j--)

;

}

void display(uchar num)

{

dula = 1;

P0 = table[num];

dula = 0;

}

void matrixkeyscan()

{

uchar temp, key;

P3 = 0xfe;

temp = P3;

temp = temp & 0xf0;

if (temp != 0xf0)

{

delayms(10);

temp = P3;

temp = temp & 0xf0;

if (temp != 0xf0)

{

temp = P3;

switch(temp)

{

case 0xee:

key = 0;

break;

case 0xde:

key = 1;

break;

case 0xbe:

key = 2;

break;

case 0x7e:

key = 3;

break;

}

while (temp != 0xf0)

{

temp = P3;

temp = temp & 0xf0;

}

display(key);

}

}

P3 = 0xfd;

temp = P3;

temp = temp & 0xf0;

if (temp != 0xf0)

{

delayms(10);

temp = P3;

temp = temp & 0xf0;

if (temp != 0xf0)

{

temp = P3;

switch(temp)

{

case 0xed:

key = 4;

break;

case 0xdd:

key = 5;

break;

case 0xbd:

key = 6;

break;

case 0x7d:

key = 7;

break;

}

while (temp != 0xf0)

{

temp = P3;

temp = temp & 0xf0;

}

display(key);

}

}

P3 = 0xfb;

temp = P3;

temp = temp & 0xf0;

if (temp != 0xf0)

{

delayms(10);

temp = P3;

temp = temp & 0xf0;

if (temp != 0xf0)

{

temp = P3;

switch(temp)

{

case 0xeb:

key = 8;

break;

case 0xdb:

key = 9;

break;

case 0xbb:

key = 10;

break;

case 0x7b:

key = 11;

break;

}

while (temp != 0xf0)

{

temp = P3;

temp = temp & 0xf0;

}

display(key);

}

}

P3 = 0xf7;

temp = P3;

temp = temp & 0xf0;

if (temp != 0xf0)

{

delayms(10);

temp = P3;

temp = temp & 0xf0;

if (temp != 0xf0)

{

temp = P3;

switch(temp)

{

case 0xe7:

key = 12;

break;

case 0xd7:

key = 13;

break;

case 0xb7:

key = 14;

break;

case 0x77:

key = 15;

break;

}

while (temp != 0xf0)

{

temp = P3;

temp = temp & 0xf0;

}

display(key);

}

}

}

程序小結(jié)

a. 先送行線低電平,檢測列線信號

b. 通過延時來消抖

c. 需要檢查釋放

3. 數(shù)碼管前三位顯示一個跑表,從000到999之間以1%秒速度運(yùn)行

程序功能

當(dāng)按下一個獨立鍵盤時跑表停止,松開手后跑表繼續(xù)運(yùn)行。用定時器設(shè)計表。

程序源碼

#include

#define uint unsigned int

#define uchar unsigned char

sbit dula = P2 ^ 6;

sbit wela = P2 ^ 7;

sbit s2 = P3 ^ 4;

uchar code table[] = {

0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71,

0x76,0x79,0x38,0x3f,0

};

uchar flag, t0, bai, shi, ge;

uint shu;

void init();

void display(uchar aa, uchar bb, uchar cc);

void delayms(uint);

void main()

{

init();

while (1)

{

display(bai, shi, ge);

if (s2 == 0)

{

delayms(10);

if (s2 == 0)

{

TR0 = 0;

while (!s2)

display(bai, shi, ge);

TR0 = 1;

}

}

}

}

void init()

{

TMOD = 0x01;

TH0 = (65536 - 10000) / 256;

TL0 = (65536 - 10000) % 256;

EA = 1;

ET0 = 1;

TR0 = 1;

}

void T0_timer() interrupt 1

{

TH0 = (65536 - 10000) / 256;

TL0 = (65536 - 10000) % 256;

t0++;

if (t0 == 1)

{

t0 = 0;

shu++;

if (shu == 1000)

shu = 0;

bai = shu / 100;

shi = shu % 100 / 10;

ge = shu % 10;

}

}

void display(uchar aa, uchar bb, uchar cc)

{

dula = 1;

P0 = table[aa];

dula = 0;

P0 = 0xff;

wela = 1;

P0 = 0xfe;

wela = 0;

delayms(1);

dula = 1;

P0 = table[bb];

dula = 0;

P0 = 0xff;

wela = 1;

P0 = 0xfd;

wela = 0;

delayms(1);

dula = 1;

P0 = table[cc];

dula = 0;

P0 = 0xff;

wela = 1;

P0 = 0xfb;

wela = 0;

delayms(1);

}

void delayms(uint xms)

{

uint i, j;

for (i = xms; i 》 0; i--)

for (j = 110; j 》 0; j--)

;

}

程序小結(jié)

a. 松開檢測 while (!s2)

b. 1%秒速度運(yùn)行: 選擇定時基數(shù)為1000(即10ms), 定時倍數(shù)為1,相乘為10ms

說明: 由于間隔時間太短,所以這里出現(xiàn)的問題是低位數(shù)據(jù)顯示看不清楚,可以選用定時倍數(shù)為10 (但定時數(shù)變成了100ms, 可能與題意不符)

4. 數(shù)碼管前三位顯示一個跑表,從000到999之間以1%秒速度運(yùn)行

程序功能

當(dāng)按下第一個獨立鍵盤時跑表停止,松開手后跑表繼續(xù)運(yùn)行。

當(dāng)按下第二個獨立鍵盤時計時停止,

當(dāng)按下第三個獨立鍵盤時計時開始,

當(dāng)按下第三個獨立鍵盤時計數(shù)值清零從頭開始

程序源碼

#include

#define uint unsigned int

#define uchar unsigned char

sbit dula = P2 ^ 6;

sbit wela = P2 ^ 7;

sbit s2 = P3 ^ 4;

sbit s3 = P3 ^ 5;

sbit s4 = P3 ^ 6;

sbit s5 = P3 ^ 7;

uchar code table[] = {

0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71,

0x76,0x79,0x38,0x3f,0

};

uchar flag, t0;

uint shu;

void init();

void display(uint num);

void delayms(uint);

void keyscan();

void main()

{

init();

while (1)

{

display(shu);

keyscan();

}

}

void init()

{

TMOD = 0x01;

TH0 = (65536 - 10000) / 256;

TL0 = (65536 - 10000) % 256;

EA = 1;

ET0 = 1;

TR0 = 1;

}

void keyscan()

{

if (s2 == 0)

{

delayms(10);

if (s2 == 0)

{

TR0 = 0;

while (!s2)

display(shu);

TR0 = 1;

}

}

if (s3 == 0)

{

delayms(10);

if (s3 == 0)

{

TR0 = 0;

while (!s3)

display(shu);

}

}

if (s4 == 0)

{

delayms(10);

if (s4 == 0)

{

TR0 = 1;

while (!s4)

display(shu);

}

}

if (s5 == 0)

{

delayms(10);

if (s5 == 0)

{

shu = 0;

while (!s5)

display(shu);

}

}

}

void T0_timer() interrupt 1

{

TH0 = (65536 - 10000) / 256;

TL0 = (65536 - 10000) % 256;

t0++;

if (t0 == 1)

{

t0 = 0;

shu++;

if (shu == 1000)

shu = 0;

}

}

void display(uint num)

{

dula = 1;

P0 = table[num / 100];

dula = 0;

P0 = 0xff;

wela = 1;

P0 = 0xfe;

wela = 0;

delayms(1);

dula = 1;

P0 = table[num % 100 / 10];

dula = 0;

P0 = 0xff;

wela = 1;

P0 = 0xfd;

wela = 0;

delayms(1);

dula = 1;

P0 = table[num % 100 % 10];

dula = 0;

P0 = 0xff;

wela = 1;

P0 = 0xfb;

wela = 0;

delayms(1);

}

void delayms(uint xms)

{

uint i, j;

for (i = xms; i 》 0; i--)

for (j = 110; j 》 0; j--)

;

}

程序小結(jié)

1. 按鍵退出檢測時需要加上display(shu), 否則數(shù)碼管顯示前兩位為空白

2. 按鍵退出檢測與執(zhí)行動作的順序問題

1) 如果要求一按鍵馬上執(zhí)行動作, 應(yīng)該時先執(zhí)行動作,再做按鍵退出檢測

即如:

shu = 0;

while (!s5)

display(shu);

2) 如果要求按鍵退出后再執(zhí)行動作, 應(yīng)該時先檢查按鍵退出,再執(zhí)行動作

即如:

while (!s5)

display(shu);

shu = 0;

5. 按下16個矩陣鍵盤,依次在前三個數(shù)碼管上顯示1~16的平方

程序功能

按下16個矩陣鍵盤,依次在前三個數(shù)碼管上顯示1~16的平方,即按下第一個顯示1,按下第二個顯示4,…按下第16個顯示16*16 (256)

程序源碼

#include

#define uchar unsigned char

#define uint unsigned int

sbit dula = P2 ^ 6;

sbit wela = P2 ^ 7;

uchar code table[] = {

0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71

};

void delayms(uint);

void display(uint);

void matrixkeyscan();

void main()

{

while (1)

{

matrixkeyscan();

}

}

void delayms(uint xms)

{

uint i, j;

for (i = xms; i 》 0; i--)

for (j = 110; j 》 0; j--)

;

}

void display(uint num)

{

dula = 1;

P0 = table[num / 100];

dula = 0;

P0 = 0xff;

wela = 1;

P0 = 0xfe;

wela = 0;

delayms(1);

dula = 1;

P0 = table[num % 100 / 10];

dula = 0;

P0 = 0xff;

wela = 1;

P0 = 0xfd;

wela = 0;

delayms(1);

dula = 1;

P0 = table[num % 100 % 10];

dula = 0;

P0 = 0xff;

wela = 1;

P0 = 0xfb;

wela = 0;

delayms(1);

}

void matrixkeyscan()

{

uchar temp, key;

P3 = 0xfe;

temp = P3;

temp = temp & 0xf0;

if (temp != 0xf0)

{

delayms(10);

temp = P3;

temp = temp & 0xf0;

if (temp != 0xf0)

{

temp = P3;

switch(temp)

{

case 0xee:

key = 1;

break;

case 0xde:

key = 2;

break;

case 0xbe:

key = 3;

break;

case 0x7e:

key = 4;

break;

}

while (temp != 0xf0)

{

temp = P3;

temp = temp & 0xf0;

}

}

}

P3 = 0xfd;

temp = P3;

temp = temp & 0xf0;

if (temp != 0xf0)

{

delayms(10);

temp = P3;

temp = temp & 0xf0;

if (temp != 0xf0)

{

temp = P3;

switch(temp)

{

case 0xed:

key = 5;

break;

case 0xdd:

key = 6;

break;

case 0xbd:

key = 7;

break;

case 0x7d:

key = 8;

break;

}

while (temp != 0xf0)

{

temp = P3;

temp = temp & 0xf0;

}

}

}

P3 = 0xfb;

temp = P3;

temp = temp & 0xf0;

if (temp != 0xf0)

{

delayms(10);

temp = P3;

temp = temp & 0xf0;

if (temp != 0xf0)

{

temp = P3;

switch(temp)

{

case 0xeb:

key = 9;

break;

case 0xdb:

key = 10;

break;

case 0xbb:

key = 11;

break;

case 0x7b:

key = 12;

break;

}

while (temp != 0xf0)

{

temp = P3;

temp = temp & 0xf0;

}

}

}

P3 = 0xf7;

temp = P3;

temp = temp & 0xf0;

if (temp != 0xf0)

{

delayms(10);

temp = P3;

temp = temp & 0xf0;

if (temp != 0xf0)

{

temp = P3;

switch(temp)

{

case 0xe7:

key = 13;

break;

case 0xd7:

key = 14;

break;

case 0xb7:

key = 15;

break;

case 0x77:

key = 16;

break;

}

while (temp != 0xf0)

{

temp = P3;

temp = temp & 0xf0;

}

}

}

display(key * key);

}

程序小結(jié)

1. display(key * key)不能馬上放到每一個按鍵退出檢測后,如果那樣做,數(shù)碼管上只會顯示最后一位數(shù)字(即個位)

換句話說,

程序不能這樣:

while (temp != 0xf0)

{

temp = P3;

temp = temp & 0xf0;

}

display(key*key);

而是應(yīng)該放到程序最后結(jié)束處

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 單片機(jī)
    +關(guān)注

    關(guān)注

    6030

    文章

    44489

    瀏覽量

    631968
  • STC52
    +關(guān)注

    關(guān)注

    0

    文章

    2

    瀏覽量

    2978
收藏 人收藏

    評論

    相關(guān)推薦

    STC52單片機(jī)如何控制直流電機(jī)正反轉(zhuǎn)?

    STC52單片機(jī)如何控制直流電機(jī)正反轉(zhuǎn)?
    發(fā)表于 10-14 07:42

    stc52單片機(jī)晶振不起振是為什么?

    stc52單片機(jī)晶振不起振兩端電壓只有0.1V晶振和芯片都換過了電容20
    發(fā)表于 09-26 07:52

    stc89s52單片機(jī)設(shè)計應(yīng)用原理圖

    stc89s52單片機(jī)設(shè)計應(yīng)用原理圖原理圖包括以下幾個模塊:流水燈模塊、數(shù)碼管顯示模塊、溫度傳感器模塊、液晶顯示模塊、串口通信模塊、鍵盤
    發(fā)表于 05-21 15:06 ?272次下載
    <b class='flag-5'>stc89s52</b><b class='flag-5'>單片機(jī)</b>設(shè)計應(yīng)用<b class='flag-5'>原理圖</b>

    STC52單片機(jī)心形流水燈音樂播放

    STC52單片機(jī)心形流水燈 音樂播放 源碼 PCB 原理圖
    發(fā)表于 11-10 17:39 ?51次下載

    基于單片機(jī)STC89C52的搖搖棒

    基于單片機(jī)STC89C52的搖搖棒設(shè)計,有電路和源程序
    發(fā)表于 11-23 14:38 ?28次下載

    點陣時鐘-基于STC52單片機(jī)的時鐘設(shè)計

    16*16點陣時鐘——基于STC52單片機(jī)的時鐘設(shè)計
    發(fā)表于 12-24 18:28 ?31次下載

    單片機(jī)STC89C52程序

    單片機(jī)STC89C52程序。
    發(fā)表于 01-11 18:16 ?112次下載

    STC89C52單片機(jī)介紹

    STC89C52單片機(jī)介紹。
    發(fā)表于 05-20 13:55 ?257次下載

    STC52計算器1602顯示

    基于STC52單片機(jī)芯片的簡單運(yùn)算計算器,結(jié)果保留3位小數(shù)(可隨意更改保留位數(shù)),采用1602液晶顯示
    發(fā)表于 02-27 16:28 ?4次下載

    STC89C52單片機(jī)的輸出電壓型和輸出LED型電路原理圖免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是STC89C52單片機(jī)的輸出電壓型和輸出LED型電路原理圖免費(fèi)下載。
    發(fā)表于 04-25 18:33 ?8次下載
    <b class='flag-5'>STC89C52</b><b class='flag-5'>單片機(jī)</b>的輸出電壓型和輸出LED型電路<b class='flag-5'>原理圖</b>免費(fèi)下載

    STC89C52單片機(jī)電路原理圖免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是STC89C52單片機(jī)電路原理圖免費(fèi)下載。
    發(fā)表于 05-23 08:00 ?90次下載
    <b class='flag-5'>STC89C52</b><b class='flag-5'>單片機(jī)</b>電路<b class='flag-5'>原理圖</b>免費(fèi)下載

    STC89C52RC單片機(jī)最小系統(tǒng)電路原理圖免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是STC89C52RC單片機(jī)最小系統(tǒng)電路原理圖免費(fèi)下載。
    發(fā)表于 12-05 17:23 ?292次下載
    <b class='flag-5'>STC89C52</b>RC<b class='flag-5'>單片機(jī)</b>最小系統(tǒng)電路<b class='flag-5'>原理圖</b>免費(fèi)下載

    STC89C52單片機(jī)開發(fā)板的電路原理圖免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是STC89C52單片機(jī)開發(fā)板的電路原理圖免費(fèi)下載
    發(fā)表于 04-17 08:00 ?64次下載
    <b class='flag-5'>STC89C52</b><b class='flag-5'>單片機(jī)</b>開發(fā)板的電路<b class='flag-5'>原理圖</b>免費(fèi)下載

    STC89C52單片機(jī)的應(yīng)用電路原理圖免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是STC89C52單片機(jī)的應(yīng)用電路原理圖免費(fèi)下載。
    發(fā)表于 05-11 08:00 ?107次下載
    <b class='flag-5'>STC89C52</b><b class='flag-5'>單片機(jī)</b>的應(yīng)用電路<b class='flag-5'>原理圖</b>免費(fèi)下載

    基于單片機(jī)的指紋識別和鍵盤密碼鎖

    方案介紹這是一個基于AS608+STC89C52單片機(jī)的指紋識別和鍵盤密碼鎖。里面包括程序,原理圖
    發(fā)表于 12-27 15:27 ?12次下載