Ⅰ 51單片機按鍵控制數碼管數字加減問題
void
keyScan()
//1*5按鍵掃描函數
{
P3
=
P3
|
0xf8;
//P3高5位置1,設置為輸入,默認為高電平
0xf8=11111000
keyValue
=
P3;
if((keyValue
&
0xf8)
!=
0xf8)
{
//判斷是否有按鍵按下
delay(20);
//延時肖抖
keyValue
=
P3;
if((keyValue
&
0xf8)
!=
0xf8)
//再次判斷是否有按鍵按下
keyValue
&=
0xf8;
//讀取掃描結果
}
}
Ⅱ c51單片機怎麼用兩個按鍵控制兩個數碼管的加減,加到99就好,求程序
1、首先先在proteus畫出模擬圖,方便模擬程序。
Ⅲ 51單片機按鍵控制數碼管數據的加減
DAT EQU 30H
SCANLED EQU 32H
FSDAT EQU 33H
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP T0ISR
ORG 0030H
MAIN:
MOV SP,#5FH
MOV TMOD,#01H
MOV TH0,#0F4H
MOV TL0,#048H
MOV P2,#00H
MOV SCANLED,#0
MOV 30H,#2
MOV 31H,#0
MOV FSDAT,#20
SETB EA
SETB ET0
SETB TR0
LOOP:
JB P3.0,$
JNB P3.0,$
DEC FSDAT
MOV A,FSDAT
MOV B,#10
DIV AB
MOV 30H,A
MOV 31H,B
MOV A,FSDAT
JNZ LOOP
MOV FSDAT,#20
SJMP LOOP
;--------------------
T0ISR:
PUSH ACC
CLR TR0
MOV TH0,#0F4H
MOV TL0,#48H
SETB TR0
MOV DPTR,#LEDTAB1
T000:
MOV R0,#DAT
MOV A,SCANLED
ADD A,R0
MOV R0,A
MOV A,SCANLED
JNZ T001
MOV P2,#02H
SJMP T0DIS
T001:
MOV P2,#01H
T0DIS:
MOV A,@R0
MOVC A,@A+DPTR
CPL A
MOV P0,A
INC SCANLED
MOV A,SCANLED
ANL A,#01H
MOV SCANLED,A
POP ACC
RETI
;--------------------
LEDTAB1:
DB 0C0H ;"0" 00H
DB 0F9H ;"1" 01H
DB 0A4H ;"2" 02H
DB 0B0H ;"3" 03H
DB 99H ;"4" 04H
DB 92H ;"5" 05H
DB 82H ;"6" 06H
DB 0F8H ;"7" 07H
DB 80H ;"8" 08H
DB 90H ;"9" 09H
DB 88H ;"A" 0AH
DB 83H ;"B" 0BH
DB 0C6H ;"C" 0CH
DB 0A1H ;"D" 0DH
DB 86H ;"E" 0EH
DB 8EH ;"F" 0FH
DB 0FFH ;" " 10H
;--------------------
END
Ⅳ 51單片機C語言程序4個獨立按鍵實現對數碼管數字顯示的加減清零等
#include<reg52.h>
//P0是數碼管。P1是LED.P2是按鍵
sbitKEY_OUT_1=P2^3;
sbitKEY_OUT_2=P2^2;
sbitKEY_OUT_3=P2^1;
sbitKEY_OUT_4=P2^0;
#defineucharunsignedchar
#defineulintunsignedlong
#defineFrequency10//定時器中斷時間=f*T
#defineTime1//一個周期1ms
#defineTubeNumber6//數碼管個數
#defineKeyLine4//矩陣按鍵行數
#defineKeyColumn4//矩陣按鍵列數
//數碼管真值表
ucharcodeLED_Number[]={0x0C,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
//ucharcodeLED_Alphabet[]={0x88,0x83,0xC6,0xA1,0x86,0x8E,0x89,0xC7,0x8C,0xC1,0x91,0x9C};
/*0~9
A~F(b、d為小寫)HLPUyo*/
ucharLED_Buff[TubeNumber]={0xff,0xff,0xff,0xff,0xff,0xff};
/*數碼管顯示緩沖區,0xff確保初始時都不亮.
不可寫成ucharcodeLED_Buff[]。code定義變數寫入room,不可修改*/
//矩陣按鍵編號到標准盤碼的映射表
ucharcodeKeyCodeMap[4][4]={
(0x31,0x32,0x33,0x26),//數字鍵1、數字鍵2、數字鍵3、向上鍵
(0x34,0x35,0x36,0x25),//數字鍵4、數字鍵5、數字鍵6、向左鍵
(0x37,0x38,0x39,0x28),//數字鍵7、數字鍵8、數字鍵9、向下鍵
(0x30,0x1B,0x0D,0x27)};//數字鍵0、ESC鍵、回車鍵、向右鍵
ucharStaFlag[KeyLine][KeyColumn]={(1,1,1,1),(1,1,1,1),(1,1,1,1),(1,1,1,1)};//按鍵是否穩定標志
voidStartTime0();
voidTubeDisplay(ulintsec);
ulintpow(x,y);
voidTubeScan();
voidKeyAction(ucharkeycode);
voidKeyDriver();
voidKeyScan();
voidmain()
{
P1=0x08;//使能U3,選擇數碼管。
StartTime0();
while(1)KeyDriver();
}
//定時器0啟動函數
voidStartTime0()
{
EA=1;
ET0=1;
TMOD=0x01;
TH0=(65536-Time*100)/256;
TL0=(65536-Time*100)%256;
PT0=1;
/*定時器0優先中斷控制位。
IP這個寄存器的每一位,表示對應中斷的搶占優先順序,每一位的復值都是0,當我們把某一位設置為1的時候,這一位優先順序就比其它位的優先順序高了。
比如我們設置了PT0位為1後,當單片機在主循環或其他中斷程序執行時,一旦TO發生中斷,作為更高優先順序,程序馬上執行T0.若在T0程序執行時,
其他中斷程序發生中斷,仍執行TO直到T0中斷結束後再執行其他程序。
*/
}
//中斷服務函數
voidTo_time0()interrupt1using0
{
staticucharcnt;//記錄TO中斷次數
// staticulintsec;//記錄經過秒速
//判斷是否溢出
if(TF0==1)
{
TF0=0;
TH0=(65536-Time*100)/256;
TL0=(65536-Time*100)%256;
}
if(cnt>=Frequency)
{
cnt=0;
//sec++;
// Tube_Display(sec);
TubeScan();
KeyScan();
}
}
//數碼管顯示函數
voidTubeDisplay(ulintnom)
{
ucharm=2;//小數部分位數
uchari;//傳輸索引
//秒速達到上限清零
if(nom>pow(10,TubeNumber-m))nom=0;
//分別傳輸小數部分和整數部分
for(i=0;i<m;i++)
LED_Buff[i]=LED_Number[nom/pow(10,i)%10];
for(i=0;i<(TubeNumber-m);i++)
LED_Buff[i+m]=LED_Number[nom/pow(10,i)%10];
//點亮小數點
LED_Buff[m]&=0x7f;
}
//平方運算函數
ulintpow(x,y)//x為底,為冪
{
ulintp,i=1;
//平方運算
for(i=1;i<=y;i++)
p*=x;
//輸出結果
returnp;
}
//數碼管動態函數
voidTubeScan()
{
staticuchari=0;//動態掃描索引
//關閉所有段選位,數碼管消隱
P0=0xff;
//for(i=0;i<Tube_number;i++)
P1=(P1&0xf8)|i;//位選索引賦值到P1口低3位
P0=LED_Buff[i];//緩沖區中的索引位置數據傳輸到P0口
if(++i>=TubeNumber)i=0;//索引遞增循環,遍歷整個緩沖區
}
//矩陣按鍵動作函數
voidKeyAction(ucharkeycode)
{
staticulintresult;
ulintnom=0;
//輸入數字0~9
if((keycode>=0x30)&&(keycode<=39))
{
nom=(nom*10)+(keycode-0x30);//十進制整體左移,新數進入各位
TubeDisplay(nom);
}
//輸入方向鍵
if((keycode>=0x25)&&(keycode<=28))
switch(keycode)
{
case0x26:result+=nom;nom=0;TubeDisplay(result);
case0x28:result-=nom;nom=0;TubeDisplay(result);
case0x25:result=1;result*=nom;nom=0;TubeDisplay(result);
case0x27:result=1;result/=nom;nom=0;TubeDisplay(result);
}
elseif(keycode==0x0d)TubeDisplay(result);//輸入回車鍵,輸出最終結果
elseif(keycode==0x1b)//輸入ESC鍵,清零
{
nom=result=0;
TubeDisplay(nom);
}
}
//矩陣按鍵驅動函數
voidKeyDriver()
{
ucharl,c;
staticucharbackup[KeyLine][KeyColumn]={(1,1,1,1),(1,1,1,1),(1,1,1,1),(1,1,1,1)};//按鍵值備份,保存前一次值
for(l=0;l<KeyLine;l++)
{
for(c=0;c<KeyColumn;c++)
{
if(backup[l][c]!=StaFlag[l][c])
{//檢測按鍵動作
if(backup[l][c]==1)//按鍵按下時執行
KeyAction(KeyCodeMap[l][c]);//調用動作函數
backup[l][c]=StaFlag[l][c];//刷新前一次備份值
}
}
}
}
//矩陣按鍵掃描函數
voidKeyScan()
{
ucharl=0;//矩陣按鍵掃描輸出索引
ucharc=0;//矩陣按鍵掃描列索引
ucharkeybuff[KeyLine][KeyColumn]={(0xff,0xff,0xff,0xff),(0xff,0xff,0xff,0xff),
(0xff,0xff,0xff,0xff),(0xff,0xff,0xff,0xff)};//矩陣按鍵掃描緩沖區
//將一行的四個按鍵移入緩沖區
for(l=0;l<KeyColumn;l++)
keybuff[l][c]=((0xfe|(P2>>(4+l))&0x01));
//按鍵消抖
for(l=0;l<KeyLine;l++)
{
if((keybuff[l][c]&0x0f)==0x00)//連續4次掃描都為0,判斷4*4ms內都是按下狀態,可認為按鍵已穩定按下
StaFlag[l][c]=0;
elseif((keybuff[l][c]&0x0f)==0x0f)//連續4次掃描都為1,判斷4*4ms內都是彈起狀態,可認為按鍵已穩定彈起
StaFlag[l][c]=1;
}
for(c=0;c<KeyColumn;c++)
{
switch(c)//根據索引,釋放當前輸出腳拉低下次的根據索引
{
case0:KEY_OUT_4=1;KEY_OUT_1=0;break;
case1:KEY_OUT_1=1;KEY_OUT_2=0;break;
case2:KEY_OUT_2=1;KEY_OUT_3=0;break;
case3:KEY_OUT_3=1;KEY_OUT_4=0;break;
default:break;
}
}
}
Ⅳ c51單片機按鍵控制數碼管循環加1、減1電路設計
設計程序之前,要先確定電路。
我的網路空間,有這樣的電路和程序,可供參考。
Ⅵ 怎樣用單片機編程。兩個獨立按鍵,控制數碼管的加減
這個很容易嘛,你先設置一個寄存器,然後一直掃描兩個按鍵(假設K1按下為加,K2按下為減),假設檢測到K1被按下,寄存器就加1,如果檢測到K2被按下,寄存器就減1;然後再調用顯示函數就OK了。、 ORG 0000H
LJMP START
ORG 0030H
START:
MOV R2, #1
LOOP:
CALL DISP
JB P1.6, NEXT
CALL DL10MS
JB P1.6, NEXT
JNB P1.6, $
DJNZ R2, NEXT
MOV R2, #10
NEXT:
JB P1.7, LOOP
CALL DL10MS
JB P1.7, LOOP
JNB P1.7, $
INC R2
CJNE R2, #11, LOOP
JMP START
;----------------------------------------
DISP:
MOV A, R2
DEC A
MOV DPTR, #TAB
MOVC A, @A + DPTR
MOV P2, A
RET
DL10MS:
MOV R6, #20
DJNZ R7, $
DJNZ R6, $ - 2
RET
;----------------------------------------
TAB:
DB 0C0H, 0F9H, 0A4H, 0B0H, 99H
DB 92H, 82H, 0F8H, 80H, 90H
;----------------------------------------
END
Ⅶ 單片機按鍵加一、減一
利用外部中斷實現按鍵按一下數碼管數字加1,實現00-99的循環,另一個按鍵實現清零,不管數碼管數字是多少,該按鍵按下數碼管顯示00
Ⅷ 請教高手,用51單片機獨立按鍵控制數碼管數字加減,為什麼在按下獨立按鍵的時候會出現閃爍怎麼回事
因為你按鍵的時候影響了數碼管刷新;
數碼管一般都是動態掃描的,利用人眼的視覺暫留做的,你按下按鍵的時候,肯定有延時消抖,延時的時候就影響了數碼管顯示,所以數碼管刷新的慢了,人眼就能分辨出來亮和滅的狀態....
解決辦法
1、改進按鍵掃描
2、改進數碼管顯示
3、用嵌入式系統
以上三選一即可解決
Ⅸ 匯編語言51單片機怎麼實現用KEY 1控制數碼管上顯示的數字加1 KEY2控制數碼管上顯示數字減1
原有key1為P3.4,添加個key2鍵為P3.5;
1、按你顯示程序的邏輯,對TAB修改如下:
TAB:DB 00H,3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,77H,7CH,39H,5EH,79H,71H,00H
即數據的首尾為0(這是個標記而已),中間才是七段碼 0--F 的顯示數據;
2、對CK1、CK2鍵盤按下及松開程序做了修改;
3、顯示程序也進行了修改,唯獨延時程序不用修改;
代碼如下:
MAIN:
MOV DPTR,#TAB
MOV R4,#00H
MOV R5,#01H
CLR A
LCALL DISPLAY
LOOP:
LCALL KEYDOWN
LCALL DISPLAY
SJMP LOOP
KEYDOWN:
JB P3.4,CK11 ;key1沒有按下則轉到key2
LCALL DS1MS ;P3.4=0表示Key1按下
JB P3.4,CK11 ;key1還不能松開
MOV R5,#01H
INC R4;key1按下為加
RET
CK11:
JB P3.5,KEYDOWN ;key2沒有按下則轉到key1
LCALL DS1MS ;P3.5=0表示Key2按下
JB P3.4,KEYDOWN ;key2還不能松開
MOV R5,#10H
DEC R4;key2按下為減
RET
D1::
MOV R4,R5
DISPLAY:
MOV A,R4
MOVC A,@A+DPTR
JZ D1 //累加器(A)=0轉
MOV P0,A
SETB P2.6
CLR P2.6
MOV P0,#0FEH
SETB P2.7
CLR P2.7
LCALL DS1MS ;延時
LCALL KEYUP
RET
KEYUP:
JNB P3.4,KEYUP ;P3.4=0轉
JNB P3.5,KEYUP ;等待松開按鍵
LCALL DS1MS
JNB P3.4,KEYUP
JNB P3.5,KEYUP
RET
TAB:DB 00H,3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,77H,7CH,39H,5EH,79H,71H,00H