?? 3x4矩陣鍵盤的掃描程序.log
字號:
//新動力2005
/* 3x4矩陣鍵盤的掃描程序
按相應的按鍵,數碼管顯示相應的數字,星號鍵和井號鍵分別顯示為E和F
*********************************
Create by:左秀龍
support:
Tel:0755-82879296
email: cutedesign@tom.com
Date: 2005/06/23
*********************************
測試通過*/
#include<AT89X51.h>
unsigned char code table[]={0xC0,0xF9,0xA4,0xB0,0x99, //0~4
0x92,0x82,0xF8,0x80,0x90, //5~9
0x88,0x83,0xA7,0xA1,0x86,0x8E}; //A~F
void KeyScan();
void delay10ms(unsigned char time);
void Dispaly(unsigned char k);
unsigned char key,temp;
void main() //主程序
{
while(1)
{
KeyScan();
}
}
void KeyScan() //按鍵掃描子程序
{
P1=0xFF;
P1_3=0;
temp=P1;
temp&=0xF0;
if(temp !=0xF0)
{
delay10ms(1);
temp=P1;
temp&=0xF0;
if(temp !=0xF0)
{
temp=P1;
temp&=0xF0;
switch(temp)
{
case 0x70:
key=1;break;
case 0xB0:
key=2;break;
case 0xD0:
key=3;break;
}
Dispaly(key);
}
}
P1=0xFF;
P1_2=0;
temp=P1;
temp&=0xF0;
if(temp !=0xF0)
{
delay10ms(1);
temp=P1;
temp&=0xF0;
if(temp !=0xF0)
{
temp=P1;
temp&=0xF0;
switch(temp)
{
case 0x70:
key=4;break;
case 0xB0:
key=5;break;
case 0xD0:
key=6;break;
}
Dispaly(key);
}
}
P1=0xFF;
P1_1=0;
temp=P1;
temp&=0xF0;
if(temp !=0xF0)
{
delay10ms(1);
temp=P1;
temp&=0xF0;
if(temp !=0xF0)
{
temp=P1;
temp&=0xF0;
switch(temp)
{
case 0x70:
key=7;break;
case 0xB0:
key=8;break;
case 0xD0:
key=9;break;
}
Dispaly(key);
}
}
P1=0xFF;
P1_0=0;
temp=P1;
temp&=0xF0;
if(temp !=0xF0)
{
delay10ms(1);
temp=P1;
temp&=0xF0;
if(temp !=0xF0)
{
temp=P1;
temp&=0xF0;
switch(temp)
{
case 0x70:
key=14;break;
case 0xB0:
key=0;break;
case 0xD0:
key=15;break;
}
Dispaly(key);
}
}
}
//延時程序
void delay10ms(unsigned char time)
{
unsigned char a,b,c;
for(a=0;a<time;a++)
for(b=0;b<10;b++)
for(c=0;c<120;c++)
;
}
void Dispaly(unsigned char k) //顯示程序
{
P0=table[k];
P2_1=0;
}
/*這是一個控制步進電機正反轉的實際應用程序*/
/*選用的是三相步進電機驅動器,p14口線用做步進電機的脈沖控制*/
/*p13口線用做步進電機的方向控制。p15,p16,p17是光耦開關量輸入*/
/*信號端,p20,p21,p22,p23與x25045看門狗存儲器相連*/
/*k7,k8鍵是設定步進電機轉動速度參數的加減鍵*/
/*k9是啟動運行鍵,按一下k9,步進電機開始運行,直到p17口線有信號輸入才停止*/
/*k10是停止鍵,任何時候按下k10都將停止步進電機當前的運行*/
/*k11是步進運行鍵,按一下,步進電機動一下*/
/*k12鍵是反向運行鍵,按一下,步進電機開始反向運行,知道p15口線有信號才停止*/
/*如果p16口線有信號輸入,則只有k12鍵才起作用,其它鍵都沒反應。*/
START:do;
$INCLUDE(REG51.DCL)
DECLARE (addrl,n,I,j,ok,ds) byte; /*定義變量*/
declare l(5) byte;
declare (dat,data) byte at (30h);
declare delay word;
DECLARE ACO(11) BYTE CONSTANT (05h,9fh,23h,0bh,99h,49h,/*定義LED段碼表*/
41h,1fh,01h,09h,00h);
declare si literally 'p21',sck literally 'p20'; /*X25045囗線定義*/
declare so literally 'p22',cs literally 'p23';
dog:procedure; /* 初始化看門狗x25045 */
cs=1;
call time(1);
cs=0;
call time(1);
cs=1;
end dog;
run:procedure; /*步進電機運行脈沖輸出程序*/
if ok=1 then
call dog;
do;
p14=0;
call time(1);
p14=1;
call time(1);
end;
end run;
DISPLAY:PROCEDURE(L0,L10); /*顯示子程序*/
DECLARE (L0,L10) BYTE; /*定義顯示二位*/
n=L10;
n=aco(n); /*十位數BCD碼譯成段碼*/
sbuf=n; /*十位數送164顯示*/
do while ti=0; /*等待發送結束*/
call dog; /*看門狗定時器復位*/
end;
n=L0;
n=aco(n);
sbuf=n; /*個位數送164顯示*/
do while ti=0;
call dog;
end;
end display;
outbyt: procedure(da); /*向看門狗存儲器寫入一字節*/
declare (i,da) byte;
j=da; /*將要寫入的字節賦給臨時變量J */
do i=0 to 7; /*左移8位,送到口線si */
sck=0;
j=scl(j,1);
si=cy;
sck=1; /*每移一位數據,跟一個時鐘信號*/
end;
end outbyt;
inbyt: procedure; /* 從看門狗存儲器讀出一字節 */
declare (i,di) byte;
j=0;
do i=0 to 7;
sck=1;
sck=0;
cy=so;
j=scl(j,1); /*從看門狗存儲器讀出一字節送入臨時變量j*/
end;
dat=j;
end inbyt;
wrenable: procedure; /* 置看門狗寫使能*/
sck=0;
cs=0;
; /* write enable command */
call outbyt(06h); /* x25045 寫使能指令06h */
cs=1;
sck=0;
end wrenable;
wrdisable: procedure; /* 置看門狗寫禁止 */
sck=0;
cs=0;
; /* write disable command */
call outbyt(04h);
sck=0;
cs=1;
end wrdisable;
wrregister: procedure; /* 寫狀態寄存器 */
sck=0;
cs=0;
dat=01h; /* write register command */
call outbyt(dat);
; /* 00h--1.4S, 20h--200MS, 10h--600MS, 30h--disable Wdog */
call outbyt(00h); /* 設定看門狗定時時間 */
;
sck=0;
cs=1;
call time(200); /* wait to complete writting cycle */
end wrregister;
rdregister:procedure; /* 讀看門狗狀態寄存器 */
sck=0;
cs=0;
; /* register read command */
call outbyt(05h);
call inbyt; /* status register read in <DAT> */
sck=0;
cs=1;
end rdregister;
wbyte:procedure; /* 看門狗存儲器字節寫入子程序 */
declare comm byte;
sck=0;
cs=0;
comm=02h; /* 寫指令 02h */
call outbyt(comm);
call outbyt(addrl);
call outbyt(dat); /* send one byte data to X25043 */
cs=1;
sck=0;
call time(150);
end wbyte;
rbyte:procedure; /*看門狗存儲器字節讀出子程序 */
declare comm byte;
sck=0;
cs=0;
comm=03h; /* read command */
call outbyt(comm);
call outbyt(addrl);
call inbyt; /* read one byte to <DAT> */
sck=0;
cs=1;
end rbyte;
incdata: procedure; /* 參數修改--"加"鍵處理子程序+ */
if p10=0 then /* 如果K7鍵按下*/
do;
do while p10=0; /* 等待鍵松開有效 */
call dog; /* 此處必需調用看門狗復位子程序("喂狗"),否則程序將被看門狗復位*/
end;
data=data+1; /* 設定值+1 */
if data>99 then data=1; /* 規定設定值的上限*/
L(1)=data MOD 10; /*將設定值的十位數拆出來送給十位數顯示變量L(1) */
L(2)=data/10; /*將設定值的個位數拆出來送給個位數顯示變量L(2) */
call display(L(1),L(2)); /* 將改變后的設定值送164顯示出來*/
call time(200); /* 延時 */
call dog;
call time(200);
call dog;
call wrenable; /* 置存儲器寫使能 */
addrl=00h; /* 置存儲器地址 */
dat=l(1);
call wbyte; /* 將變量L(1)的值寫入存儲器00h位置 */
call wrenable;
addrl=01h;
dat=l(2);
call wbyte; /* 將變量L(2)的值寫入存儲器01h位置 */
end;
end incdata;
decdata: PROCEDURE; /* 參數修改---"減"鍵處理子程序- */
IF p11=0 THEN /* k8 鍵處理子程序 */
do;
do while p11=0;
call dog;
end;
DATA=DATA-1; /* 設定值-1 */
if data=0 then data=99;
L(1)=data MOD 10;
L(2)=data/10;
call display(l(1),l(2));
call dog;
call time(200);
call dog;
call time(200);
call dog;
call wrenable;
addrl=00h;
dat=l(1);
call wbyte;
call wrenable;
addrl=01h;
dat=l(2);
call wbyte;
end;
END decdata;
starton: PROCEDURE; /* start */
declare sd byte;
if p12=0 THEN /* K9鍵處理子程序 */
do;
do while p12=0;
call dog;
end;
if p17=0 then ok=0; /* 如果p17 口線上有信號輸入,則運行標志置0 (停止運行)*/
p13=1; /* 置步進電機正向運轉 */
call time(200);
call dog;
do while ok=1; /* 當運行標志為1時,執行速度延時操作 */
do sd= 0 to data; /* 根據設定值 data的數值延時來確定步進電機運行時的脈沖給定速度*/
call dog;
end;
end;
END starton;
step: PROCEDURE; /* step */
declare sd byte;
p13=1; /* 置步進電機正向運轉 */
call time(200);
call dog;
IF p33=0 THEN /* k11鍵處理子程序 */
do;
if p17=0 then ok=0; /* 如果p17上有信號輸入,則停止運行*/
do while p33=0;
do sd= 0 to data; /* 調用延時,調整步進電機的運行速度 */
call dog;
call time(2);
end;
call run;
call dog;
end;
end;
ok=0;
END step;
back: PROCEDURE; /* 反向運行處理子程序 */
declare sd byte;
IF p34=0 THEN
do;
do while p34=0;
call dog;
end;
if p15=0 then ok=0; /* 反向運行時,如果遇到p15上有信號輸入,則停止步進電機運行 */
p13=0; /* 置步進電機反向運行 */
call time(200);
call dog;
do while ok=1;
do sd=0 to data; /*根據設定值調節步進電機的運行速度 */
call dog;
call time(2);
end;
call run;
if (p15=0 or p32=0 ) then ok=0; /* p15 或 p32 口線任意一個有信號輸入,停止運行 */
end;
end;
END back;
MAIN$PROGRAM: /* 初始化主程序 */
ea=0; /* 關中斷 */
SCON=00h; /*置串口方式0 ,串行數據輸出模式*/
PCON=00h;
tmod=11h;
et0=1;
enable; /* 開中斷 (ea=1) */
SCK=0;cs=1; /* 定義存儲器口線初始狀態 */
call wrenable;
call wrregister; /* 看門狗存儲器 初始化 */
call wrenable;
call dog;
p2=0ffh; /* 初始化各個口線的狀態 */
p1=0ffh;ok=0;
p14=1;p32=1;p33=1;p34=1;
p13=1;
ADDRL=00h; /* 上電復位后從存儲器中讀出設定的速度值 */
CALL rbyte;
l(1)=dat;
addrl=01h;
call rbyte;
l(2)=dat;
DATA=L(1)+L(2)*10; /*將讀出的值合并成十進制,存入變量data中 */
/* 以下是主循環程序 */
LOOP:
IF p10=0 THEN CALL incdata; /* 檢測各個按鍵是否有按下 */
IF p11=0 THEN CALL decdata;
if p12=0 then
do;
ok=1;
call starton;
end;
if p34=0 then
do;
ok=1;
call back;
end;
if p33=0 then
do;
ok=1;
call step;
end;
call dog;
CALL DISPLAY(L(1),L(2)); /* 將設定值送164顯示 */
call dog;
CALL TIME(100);
call dog;
GOTO LOOP;
END START;
AT89C2051驅動步進電機的電路和源碼
電路如圖所示:
程序:
stepper.c
stepper.hex
/*
* STEPPER.C
* sweeping stepper's rotor cw and cww 400 steps
* Copyright (c) 1999 by W.Sirichote
*/
#i nclude c:\mc5151io.h /* include i/o header file */
#i nclude c:\mc5151reg.h
register unsigned char j,flag1,temp;
register unsigned int cw_n,ccw_n;
unsigned char step[8]={0x80,0xc0,0x40,0x60,0x20,0x30,0x10,0x90}
#define n 400
/* flag1 mask byte
0x01 run cw()
0x02 run ccw()
*/
main()
{
flag1=0;
serinit(9600);
disable(); /* no need timer interrupt */
cw_n = n; /* initial step number for cw */
flag1 |=0x01; /* initial enable cw() */
while(1){
{
tick_wait(); /* wait for 10ms elapsed */
energize(); /* round-robin execution the following tasks every 10ms */
cw();
ccw();
}
}
}
cw(){
if((flag1&0x01)!=0)
{
cw_n--; /* decrement cw step number */
if (cw_n !=0)
j++; /* if not zero increment index j */
else
{flag1&=~0x01; /* disable cw() execution */
ccw_n = n; /* reload step number to ccw counter */
flag1 |=0x02; /* enable cww() execution */
}
}
}
ccw(){
if((flag1&0x02)!=0)
{
ccw_n--; /* decremnent ccw step number */
if (ccw_n !=0)
j--; /* if not zero decrement index j */
else
{flag1&=~0x02; /* disable ccw() execution */
cw_n = n; /* reload step number to cw counter */
flag1 |=0x01; /* enable cw() execution */
}
}
}
tick_wait(){ /* cputick was replaced by simpler ASM code 10ms wait */
asm" JNB TCON.5,*"; /* wait for TF0 set */
asm" CLR TCON.5"; /* clear TF0 for further set */
asm" ORL TH0,#$DC"; /* reload TH0 with $DC, TL0 = 0 */
}
energize(){
P1 = step[(j&0x07)]; /* only step 0-7 needed */
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -