標題:
51單片機設計秒表計時器,proteus仿真程序
[打印本頁]
作者:
songkdksljf
時間:
2021-1-5 16:00
標題:
51單片機設計秒表計時器,proteus仿真程序
27,28兩個按鍵用于控制時間的暫停和重新計數(shù)
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei截圖20210105155944.jpg
(119.48 KB, 下載次數(shù): 76)
下載附件
2021-1-5 16:00 上傳
單片機源程序如下:
#include <reg51.h>
#include <absacc.h>
#include <intrins.h>
#define BIT0 0x01
#define BIT1 0x02
#define BIT2 0x04
#define BIT3 0x08
#define BIT4 0x10
#define BIT5 0x20
#define BIT6 0x40
#define BIT7 0x80
#define KeyInPort XBYTE[0xE800]
#define KeyOutPort XBYTE[0xEC00]
typedef unsigned int u16; //對數(shù)據(jù)類型進行聲明定義
typedef unsigned char u8;
u16 Timer0_flag = 0;
u16 time100ms_cnt = 0;//100ms計數(shù)變量
u8 xdata smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,//0x00全滅
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71, 0x00};//顯示0~F的值,18不顯示
u8 xdata smgduan_num[] = { 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0xff};//0xff選中所有數(shù)碼管
u8 code KeyOutTAB[] = {
0xFF, // 湊數(shù)的
~BIT0,
~BIT1,
~BIT2,
~BIT3,
~BIT4,
~BIT5,
~BIT6,
~BIT7,
};
u8 code conKeyFunCode[] = {
3, // 湊數(shù)
0x81,// 0
0x22,// 1
0x42,// 2
0x82,// 3
0x83,// 4
0x43,// 5
0x23,// 6
0x84,// 7
0x44,// 8
0x24,// 9
0x14,// A
0x13,// B
0x12,// C
0x11,// D
0x21,// E
0x41,// F
0x00,// 空鍵 16
0x85,// 17
0x45,// 18
0x25,// 19
0x15,// 20
0x86,// 21
0x46,// 22
0x26,// 23
0x16,// 24
0x0C,// 25
0x0B,// 26
0x0A,// 27
0x09,// 28
};
u16 smgduan_addr = 0XE3FF; //E3FF是PS0的地址,段碼的8位數(shù)據(jù)
u16 smgduan_num_addr = 0XE7FF; //E7FF是PS1的地址,選擇那一個數(shù)碼管亮
u16 key_out_addr = 0XEFFF; //EFFF是PS3的地址,矩陣按鍵輸出地址
u16 key_in_addr = 0XEBFF; //EBFF是PS2的地址,矩陣按鍵讀地址
u8 Key_Flag = 0;
u8 Sys_Key = 0; // 鍵值存放在這里
u8 duanma_mode = 0;
u8 preKey = 0;
u8 curKey = 0;
u8 SameKeyNum = 0;
bit Flag_1ms = 0;
unsigned char Cnt_1ms = 0;
bit Flag_10ms = 0;
unsigned char Cnt_10ms = 0;
bit Flag_100ms = 0;
unsigned char Cnt_100ms = 0;
bit Flag_1s = 0;
unsigned char Cnt_1s = 0;
void Fun_KeyScan( void ){
unsigned char Temp = 0;
unsigned char LineNum = 0;
// 1、獲取鍵值
for( LineNum = 6; LineNum > 0; LineNum-- ){
KeyOutPort = KeyOutTAB[LineNum]; // 輸出
Temp = KeyInPort; // 讀取
Temp = ~Temp; // 取反,有按下的是低電平
Temp &= 0x1F; // 屏蔽,0001 1111
if( Temp ){ // 如果有鍵按下
break; // 則跳出循環(huán)
} // 否則繼續(xù)掃描
}
// 2、拼合鍵值
Temp <<= 3;//左移3位
Temp |= LineNum;//6 = 110B
// 3、獲取功能碼
for( LineNum = 29; LineNum > 0; LineNum-- ){//一共30個數(shù),但是第一個數(shù)是無效數(shù),從29掃描到1
if( Temp == conKeyFunCode[ LineNum ] ){
break;
}
}
if( LineNum > 0 ){ LineNum--; }
// 4、數(shù)字濾波
curKey = LineNum;
if( curKey != preKey ){//判斷下一次掃描的是不是還是上一個按鍵
preKey = curKey;
SameKeyNum = 0;
}
else{
SameKeyNum++;
if( SameKeyNum == 30 ){ Key_Flag = 1; Sys_Key = curKey; }
if( SameKeyNum == 80 ){ Key_Flag = 1; Sys_Key = curKey; }
if( SameKeyNum >= 100 ){ Key_Flag = 1; Sys_Key = curKey; SameKeyNum = 80; }
}
}
bit key28_down = 0;
bit key28_up = 0;
bit key27_down = 0;
bit key27_up = 0;
bit time_start = 1;
void InitTimer0(void)
{
TMOD = 0x01;
TH0 = 0x0FC;
TL0 = 0x18;
EA = 1;
ET0 = 1;
TR0 = 1;
}
void delay1ms(void) //誤差 0us
{
unsigned char a,b,c;
for(c=1;c>0;c--)
for(b=142;b>0;b--)
for(a=2;a>0;a--);
}
void main(void)
{
InitTimer0();
while(1)
{
Fun_KeyScan();
if (Sys_Key == 28)//當28號鍵按下去然后在松開,key28_up == 1
{
key28_down = 1;
}
if(key28_down == 1 && Sys_Key == 16)
{
key28_down = 0;
key28_up = 1;
}
if(key28_up == 1)
{
key28_up = 0;
time_start = ~time_start;
}
if (Sys_Key == 27)//當27號鍵按下去然后在松開,key27_up == 1
{
key27_down = 1;
}
if(key27_down == 1 && Sys_Key == 16)
{
key27_down = 0;
key27_up = 1;
}
if((key27_up == 1) && (time_start == 0))
{
key27_up = 0;
duanma_mode++;
// if(duanma_mode >= 3)
// {
// duanma_mode = 0;
// }
}
if(duanma_mode == 1)
{
time100ms_cnt = 0;
}
if(duanma_mode == 2)
{
duanma_mode = 0;
time_start = 1;
}
XBYTE[smgduan_num_addr] = smgduan_num[1];
……………………
…………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
51.zip
(69.18 KB, 下載次數(shù): 19)
2021-1-5 16:00 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1