<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

stc52單片機鍵盤原理圖及程序介紹

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

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

stc52單片機鍵盤原理圖

stc52單片機鍵盤原理圖及程序介紹

說明:

1. 獨立鍵盤部分

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

2. 矩陣鍵盤部分

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

程序設計詳解

1. 用數碼管的前兩位顯示一個十進制數,變化范圍為00-59.

程序功能:

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

程序源碼:

#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;

}

}

程序小結:

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

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

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

2. 按矩陣鍵盤,在數碼管上顯示0~F,6個數碼管同時靜態顯示即可。

程序功能

上電不顯示, 按矩陣鍵盤,在數碼管上顯示0~F,6個數碼管同時靜態顯示即可。

程序源碼

#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);

}

}

}

程序小結

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

b. 通過延時來消抖

c. 需要檢查釋放

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

程序功能

當按下一個獨立鍵盤時跑表停止,松開手后跑表繼續運行。用定時器設計表。

程序源碼

#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--)

;

}

程序小結

a. 松開檢測 while (!s2)

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

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

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

程序功能

當按下第一個獨立鍵盤時跑表停止,松開手后跑表繼續運行。

當按下第二個獨立鍵盤時計時停止,

當按下第三個獨立鍵盤時計時開始,

當按下第三個獨立鍵盤時計數值清零從頭開始

程序源碼

#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--)

;

}

程序小結

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

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

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

即如:

shu = 0;

while (!s5)

display(shu);

2) 如果要求按鍵退出后再執行動作, 應該時先檢查按鍵退出,再執行動作

即如:

while (!s5)

display(shu);

shu = 0;

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

程序功能

按下16個矩陣鍵盤,依次在前三個數碼管上顯示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);

}

程序小結

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

換句話說,

程序不能這樣:

while (temp != 0xf0)

{

temp = P3;

temp = temp & 0xf0;

}

display(key*key);

而是應該放到程序最后結束處

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 單片機
    +關注

    關注

    6002

    文章

    43990

    瀏覽量

    621143
  • STC52
    +關注

    關注

    0

    文章

    2

    瀏覽量

    2965
收藏 人收藏

    評論

    相關推薦

    STC單片機開發板原理圖

    本帖最后由 lcl05072099 于 2011-4-25 08:45 編輯 基于STC89C52單片機開發板原理圖
    發表于 04-25 08:42

    鍵盤開關LED與直接單片機程序控制LED亮度差距大(已解決

    本帖最后由 minDragon 于 2012-8-4 09:58 編輯 是這樣的,我P1上接了限流電阻和8個小的LED燈,寫入程序STC52單片機里去點亮P1上的LED燈時,亮度很亮。但
    發表于 08-04 09:35

    stc52單片機做的利用蜂鳴播放音樂資源占用大嗎?

    stc52單片機做的利用蜂鳴器播放音樂,很耗單片機資源嗎?為什么放我在播放的時候,單片機好像反應不過來了,我做用ds18b20檢測溫度報警,已經實現了,但我覺得蜂鳴太單調,我就想播放
    發表于 10-14 22:34

    請問有stc52 hc05通信的程序代碼嗎?

    買的hc05 帶的測試c是stm32 的 求 stc52程序代碼,本人放學單片機 ,個人愛好 請多指教 想用android 控制 電磁繼電器
    發表于 03-20 04:44

    STC52單片機簡單控制直流電機正反轉

    單片機STC52簡單控制直流電機正反轉(已驗證)本實驗源碼來源于:壇友-書盲《STC單片機簡單控制直流電機正反轉》源代碼:main.c#include***it EN= P1^0;//
    發表于 06-28 07:38

    STC52單片機如何控制直流電機正反轉?

    STC52單片機如何控制直流電機正反轉?
    發表于 10-14 07:42

    stc52單片機晶振不起振是為什么?

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

    stc89s52單片機設計應用原理圖

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

    STC52單片機心形流水燈音樂播放

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

    點陣時鐘-基于STC52單片機的時鐘設計

    16*16點陣時鐘——基于STC52單片機的時鐘設計
    發表于 12-24 18:28 ?31次下載

    單片機STC89C52程序

    單片機STC89C52程序。
    發表于 01-11 18:16 ?107次下載

    STC89C52單片機介紹

    STC89C52單片機介紹。
    發表于 05-20 13:55 ?245次下載

    STC52計算器1602顯示

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

    STC89C52單片機的I2C使用程序免費下載

    本文檔的主要內容詳細介紹的是STC89C52單片機的I2C使用程序免費下載。
    發表于 07-26 17:36 ?18次下載
    <b class='flag-5'>STC89C52</b><b class='flag-5'>單片機</b>的I2C使用<b class='flag-5'>程序</b>免費下載

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

    方案介紹這是一個基于AS608+STC89C52單片機的指紋識別和鍵盤密碼鎖。里面包括程序,原理圖
    發表于 12-27 15:27 ?12次下載
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>