❶ 8051單片機時鍾電路
8051單片機時鍾電路如下所示:
電容C2、C3對頻率有微調的作用,電容容量的選擇范圍在30pF±10pF。震盪頻率的選擇范圍為1.2-12MHz。時鍾周期=石英振盪器頻率的倒數。
單片機是一種集成電路晶元,是採用超大規模集成電路技術把具有數據處理能力的中央處理器CPU、隨機存儲器RAM、只讀存儲器ROM、多種I/O口和中斷系統、定時器/計數器等功能(可能還包括顯示驅動電路、脈寬調制電路、模擬多路轉換器、A/D轉換器等電路)集成到一塊矽片上構成的一個小而完善的微型計算機系統,在工業控制領域廣泛應用。
❷ 求8051系列單片機C程序設計完全手冊電子版
❸ 已知8051單片機的fosc=12MHz,用T1 定時,試編程由P1.2 和P1.3 引腳分別輸出周期為2ms 和500μs 的方波
代碼如下:
第一個代碼程序:
ORG 0000H
LJMP MAIN
ORG 001BH
JMP T1_INT
ORG 0030H
MAIN:
MOV TMOD, #20H
MOV TH1, #6
MOV TL1, #6
MOV IE, #88H
SETB TR1
MOV R7, #4
SJMP $
T1_INT:
CPL P1.3
DJNZ R7, T1_END
CPL P1.2
MOV R7, #4
T1_END:
RETI
END
第二個500us程序:
#include <reg51.h>
sbit P1_0=P1^0;
void main()
{
TMOD=0x01;
TH0=0xFC;
TL0=0x18;
EA=1;
ET0=1;
TR0=1;
while(1);
}
void time0_int(void) interrupt 1
{
TH0=0xFC;
TL0=0x18;
P1_0=!P1_0;
}
程序存儲器特定入口:
0000H: 復位或開機後的程序入口
0003H: 外部中斷0 服務程序入口
000BH: 定時/計數器0 中斷服務程序入口
0013H: 外部中斷1 服務程序入口
001BH: 定時/計數器1 中斷服務程序入口
0023H: 串列I/O 中斷服務程序入口
定時/計數器
8031 片內有兩個16位定時/計數器(增量式計數)
工作方式(方式0、方式1、方式2、方式3)
以定時/計數器1為例
⑴方式0(13位定時/計數)
方波是一種非正弦曲線的波形,通常會於電子和訊號處理時出現。理想方波只有「高」和「低」這兩個值。電流的波形為矩形的電流即為方波電流。不論時間軸上下是不是對稱的,只要是矩形就可叫方波,必要時,可加「對稱」,「不對稱」加以說明
通過單片機內部的計數器/定時器,採用軟體編程來產生方波,這種方法的硬體線路較簡單,系統的功能一般與軟體設計相關。
選擇MCS-51系列中的8031單片機,由於是用指示燈顯示輸出方波信號,一個LED顯示燈即可滿足設計要求。
方波是一種非正弦曲線的波形,通常會與電子和訊號處理時出現。理想方波只有「高」和「低」這兩個值。電流或電壓的波形為矩形的信號即為矩形波信號,高電平在一個波形周期內佔有的時間比值稱為占空比,也可理解為電路釋放能量的有效釋放時間與總釋放時間的比值。
占空比為50%的矩形波稱之為方波,方波有低電平為零與為負之分。必要時,可加以說明「低電平為零」、「低電平為負」。
❹ 高分求用8051單片機設計8按鍵電子琴
一、設計題目:
設計一簡易電子琴,要求能夠發出1、2、3、4、5、6、7等七個音符。
使用元件:AT89C51、LM324,喇叭,按鍵等
二、 設計目的
(1)能夠對電子電路、電子元器件、印製電路板等方面的知識有進一步的認識,獨立對其進行測試與檢查。
(2)熟悉8051單片機的內部結構和功能,合理使用其內部寄存器,能夠完成相關軟體編程設計工作。
(3)為實現預期功能,能夠對系統進行快速的調試,並能夠對出現的功能故障進行分析,及時修改相關軟硬體。
(4)對軟體編程、排錯調試、焊接技術、相關儀器設備的使用技能等方面得到較全面的鍛煉和提高。
三、系統硬體圖
原理:
(一) 音樂產生原理及硬體設計
由於一首音樂是許多不同的音階組成的,而每個音階對應著不同的頻率,這樣我們就可以利用不同的頻率的組合,即可構成我們所想要的音樂了,當然對於單片機來產生不同的頻率非常方便,我們可以利用單片機的定時/計數器T0來產生這樣方波頻率信號,因此,我們只要把一首歌曲的音階對應頻率關系弄正確即可。
本次設計中單片機晶振為12MHZ,那麼定時器的計數周期為1MHZ,假如選擇工作方式1,那T值便為T= 216--5﹡105/相應的頻率 ,那麼根據不同的頻率計算出應該賦給定時器的計數值,列出不同音符與單片機計數T0相關的計數值如下表所示:
音符 頻率(HZ) 簡譜碼(T值)
中 1 DO 523 64580
中 2 RE 587 64684
中 3 M 659 64777
中 4 FA 698 64820
中 5 SO 784 64898
中 6 LA 880 64968
中 7 SI 988 65030
採用查表程序進行查表時,可以為這個音符建立一個表格,有助於單片機通過查表的方式來獲得相應的數據:
TABLE DW 64580,64684,64777,64820,64898,64968,65030
源程序:
方案一:產生按鍵音符
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP BREAK
MAIN: MOV TMOD,#01H ;設置定時器0的工作方式
SETB EA
SETB ET0 ; 設置定時器0中斷
SETB TR0 ; 啟動定時器0
WAIT1: LCALL KEY ; 調用KEY子程序,判斷有鍵按下否?第幾個鍵?
CLR EA ;屏蔽中斷
CJNE R3,#00H,WAIT1 ;如果R3=0,表示有鍵按下
MOV A,22H ;將22H里存放的按鍵號送給A
RL A ; 因為查表裡都是字,所以得乘2查得數據
MOV DPTR,#TABLE ;指向表頭
MOVC A,@A+DPTR ; 查表
MOV TH0,A ;將數據高位送TH0
MOV 21H,A ; 將高位備份
MOV A,22H ;將22H里存放的按鍵號送給A
RL A ;因為查表裡都是字,所以得乘2查得數據
INC A ;取低位數據
MOVC A,@A+DPTR
MOV TL0,A
MOV 20H,A
WAIT2: LCALL KEY
SETB EA
CJNE R3,#00H,WAIT1
JMP WAIT2
KEY: MOV R3,#00H ; KEY子程序,判斷有鍵按下否?第幾個鍵?
MOV R1,#0FFH
MOV R0,#00H
MOV A,R1
MOV P2,A
MOV A,P2
CLR C
CPL C ;利用標志位CY來判斷是哪個鍵按下
MOV R2,#08H
WAIT3: RLC A ;移位判斷
JNC STORE
INC R0
DJNZ R2,WAIT3
STORE: MOV 22H,R0 ; 將按鍵號存22H,R3=0有鍵按下
MOV R3,#00H
RET
BREAK: PUSH ACC ; 中斷產生方波,從P1.0口輸出
PUSH PSW
MOV TL0,20H
MOV TH0,21H
CPL P1.0
POP PSW
POP ACC
RETI
TABLE: DW 65030,64968,64898,64820,64777,64684,64580 ; 7,6,5,4,3,2,1
END
方案二:產生按鍵音符
ORG 0000H
SJMP START
ORG 000BH
AJMP INT_0
ORG 0030H
START: MOV P1,#00H
SETB EA
SETB ET0 ;計數器0
MOV TMOD,#02H
MOV TH1,#09CH
MOV TL1,#09CH ;定時器初植
CLR TR0 ;定時器不允許
SCAN: ;鍵盤掃描
MOV A,P2 ;判斷鍵盤按下,跳到SCAN_1,若未按,繼續掃描
CJNE A,#0FFH,SCAN_1
NOP
SJMP SCAN
SCAN_1:ACALL DELAY ;是不是真的要按下?如果是,則跳轉SU_KEY查詢是哪個按下?
MOV A,P2
CJNE A,#0FFH,SU_KEY
NOP
SJMP SCAN
SU_KEY:JNB P2.1,MU_1 ;判斷是哪個鍵按下?
JNB P2.2,MU_2
JNB P2.3,MU_3
JNB P2.4,MU_4
JNB P2.5,MU_5
JNB P2.6,MU_6
JNB P2.7,MU_7
SJMP SCAN
;R1信號周期
MU_1: MOV R1,#19 ;如果第一個按鍵按下,則R1=19,同時程序轉NEXT
SJMP NEXT
MU_2: MOV R1,#17
SJMP NEXT
MU_3: MOV R1,#15
SJMP NEXT
MU_4: MOV R1,#14
SJMP NEXT
MU_5: MOV R1,#13
SJMP NEXT
MU_6: MOV R1,#11
SJMP NEXT
MU_7: MOV R1,#10
SJMP NEXT
NEXT: MOV A,R1
MOV R0,A
SETB TR0 ;啟動定時器0
NEXT_1:MOV A,P2 ; 沒鍵按下繼續執行,有鍵按下,返回讀引腳
CJNE A,#0FFH,NEXT_1
ACALL DELAY
MOV A,P2 ;真的沒鍵按下?
CJNE A,#0FFH,NEXT_1
CLR TR0 ;不響
AJMP SCAN ;掃描鍵盤去
INT_0: ;中斷程序
DJNZ R0,RE ;R0不等於0時,返回
CPL P1.0
MOV A,R1
MOV R0,A
RE: RETI
DELAY:MOV R7,#100 ;延長時間等待,鍵盤消抖
D1: MOV R6,#10
D2: DJNZ R6,D2
DJNZ R7,D1
RET
END
生日快樂歌:(擴展功能部分程序)
ORG 0000H
JMP MAIN
ORG 000BH
JMP TT0
MAIN: MOV TMOD,#01H ;設置定時器0工作方式
MOV IE,#82H ;設置中斷
MAIN0:MOV 30H,#00H
NEXT: MOV A,30H
MOV DPTR,#TABLE ;查表
MOVC A,@A+DPTR
MOV R2,A
JZ STOP
ANL A,0FH
MOV R5,A
MOV A,R2
SWAP A
ANL A,#0FH
JNZ SING
CLR TR0
JMP W1
SING: DEC A
MOV 22H,A
RL A
MOV DPTR,#TABLE1 ;查表
MOVC A,@A+DPTR
MOV TH0,A
MOV 21H,A
MOV A,22H
RL A
INC A
MOVC A,@A+DPTR
MOV TL0,A
MOV 20H,A
SETB TR0
W1: CALL DELAY
INC 30H
JMP NEXT
STOP: CLR TR0
JMP MAIN0
TT0: PUSH ACC ;中斷服務程序
PUSH PSW
MOV TL0,20H
MOV TH0,21H
CPL P1.0
POP PSW
POP ACC
RETI
DELAY:MOV R7,#2 ;延時187ms
W2: MOV R4,#187
W3: MOV R3,#248
DJNZ R3,$
DJNZ R4,W3
DJNZ R7,W2
DJNZ R5,DELAY
RET
TABLE1:DW 64260,64400,64524,64580 ;音符計數植
DW 64684,64777,64820,64898
DW 64968,65030,65058,65110
DW 65157,65178,65217
TABLE:DB 82H,01H,81H,94H,84H ;節拍表
DB 0B4H,0A4H,04H
DB 82H,01H,81H,94H,84H
DB 0C4H,0B4H,04H
DB 82H,01H,81H,0F4H,0D4H
DB 0B4H,0A4H,94H
DB 0E2H,01H,0E1H,0D4H,0B4H
DB 0C4H,0B4H,04H
DB 82H,01H,81H,94H,84H
DB 0B4H,0A4H,04H
DB 82H,01H,81H,94H,84H
DB 0C4H,0B4H,04H
DB 82H,01H,81H,0F4H,0D4H
DB 0B4H,0A4H,94H
DB 0E2H,01H,0E1H,0D4H,0B4H
DB 0C4H,0B4H,04H
DB 00H
END 謝謝希望採納
❺ 單片機8051設計簡易波形發生器,要求能產生正弦波,方波,三角波,通過鍵盤可改變輸出信號的頻率和幅度
這個網上資料很多的,你可以參考下的,我前幾天也做了個,proteus模擬的,程序如下,希望能幫到你的,有問題可以交流下的
#include<reg51.h>
unsigned char i,sqar_num=128; //最大值100,默認值50
unsigned char cho=0; //0:正弦波。1:方波。2:三角波。3:鋸齒波。
unsigned char num=0;
unsigned char TIME0_H=0xff,TIME0_L=0xdc; //定時器0的初值設置;全局變數.對應正弦波,鋸齒波50HZ
sbit chg= P1^0;
sbit freq_u=P1^1;
sbit freq_d=P1^2;
sbit ty_u=P1^3;
sbit ty_d=P1^4;
sbit cs =P3^7;
bit flag=0;
unsigned int FREQ=50;//初始化頻率,30HZ
unsigned char flag1;
sbit rs=P1^5;
sbit lcdcs=P1^7;
sbit cd=P3^0;
unsigned char TempBuffer[7];
unsigned char value1[]={"Frequency:"};
void delay(unsigned int ms)
{
unsigned int i,j;
for (j=0;j<ms;j++)
for (i=0;i<120;i++);
}
unsigned char code sin_num[]={
0x80,0x82,0x85,0x88,0x8b,0x8e,0x91,0x94,0x97,0x9a,0x9d,0xa0,0xa3,0xa6,
0xa9,0xac,0xaf,0xb2,0xb6,0xb9,0xbc,0xbf,0xc2,0xc5,0xc7,0xca,0xcc,0xcf,
0xd1,0xd4,0xd6,0xd8,0xda,0xdd,0xdf,0xe1,0xe3,0xe5,0xe7,0xe9,0xea,0xec,
0xee,0xef,0xf1,0xf2,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,
0xfd,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xfe,0xfd,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf2,0xf1,
0xef,0xee,0xec,0xea,0xe9,0xe7,0xe5,0xe3,0xe1,0xde,0xdd,0xda,0xd8,0xd6,
0xd4,0xd1,0xcf,0xcc,0xca,0xc7,0xc5,0xc2,0xbf,0xbc,0xba,0xb7,0xb4,0xb1,
0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x99,0x96,0x93,0x90,0x8d,0x89,0x86,
0x83,0x80,
0x80,0x7c,0x79,0x76,0x72,0x6f,0x6c,0x69,0x66,0x63,0x60,0x5d,
0x5a,0x57,0x55,0x51,0x4e,0x4c,0x48,0x45,0x43,0x40,0x3d,0x3a,0x38,0x35,
0x33,0x30,0x2e,0x2b,0x29,0x27,0x25,0x22,0x20,0x1e,0x1c,0x1a,0x18,0x16,
0x15,0x13,0x11,0x10,0x0e,0x0d,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,
0x03,0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x01,0x02,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,
0x0d,0x0e,0x10,0x11,0x13,0x15,0x16,0x18,0x1a,0x1c,0x1e,0x20,0x22,0x25,
0x27,0x29,0x2b,0x2e,0x30,0x33,0x35,0x38,0x3a,0x3d,0x40,0x43,0x45,0x48,
0x4c,0x4e,0x51,0x55,0x57,0x5a,0x5d,0x60,0x63,0x66,0x69,0x6c,0x6f,0x72,
0x76,0x79,0x7c,0x80
/* 135,145,158,167,176,188,199,209,218,226,234,240,245,249,252,254,254,253,251,247,243,237,230,222,213,204,193,182,170,158,
146,133,121,108,96,84,72,61,50,41,32,24,17,11,7,3,1,0,0,2,5,9,14,20,28,36,45,55,66,78,90,102,114,128
*/
};
unsigned code sanjiao_num[]=
{
0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,
36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,
70,72,74,76,78,80,82,84,86,88,90,92,94,96,98,100,102,
104,106,108,110,112,114,116,118,120,122,124,126,128,130,
132,134,136,138,140,142,144,146,148,150,152,154,158,160,162,164,166,168,170,
172,174,176,178,180,182,184,186,188,190,192,194,196,198,200,202,204,206,208,210,
212,214,216,218,220,222,224,226,228,230,232,234,236,238,240,242,244,246,248,250,
252,254,255,254,252,250,248,246,244,242,240,238,236,234,232,230,228,226,224,222,220,
218,216,214,212,210,208,206,204,202,200,198,196,194,192,190,188,186,184,182,180,178,
176,174,172,170,168,166,164,162,160,158,154,152,150,148,146,144, 142,140,138,136,134,
132,130,128,126,124,122,120,118,116,114,112,110,108,106,104,102,100,98,96,94,92,90,88,
86,84,82,80,78,76,74,72,70,68,66,64,62,60,58,56,54,52,50,48,46,44,42,40,38,36,
34,32,30,28,26,24,22,20,18,16,14,12,10,8,6,4,2,0,
};
//調節部分——頻率
void freq_ud(void)
{
unsigned int temp;
if(freq_d==0)
{ FREQ--; }
else if(freq_u==0)
{ FREQ++; }
temp=0xffff-3906/FREQ; //切換後頻率為50HZ 65336-10^6/(256*FREQ)
// temp=0xffff-1953/FREQ;
TIME0_H=temp/256;
TIME0_L=temp%256;
}
//調節部分——方波的占空比
void ty_ud(void) //方波也採用512次中斷構成一個周期。
{
if(ty_d==0&sqar_num>0)
sqar_num--;
else if(ty_u==0&sqar_num<255)
sqar_num++;
}
//波形發生函數
void sint(void)
{
// char num=0;
// if(!flag)
{
cs=0;P2=sin_num[num++];cs=1;
if(num==255){num=0;}
}
/* else if(flag)
{
cs=0;P2=sin_num[num--];cs=1;
if(num==0){num=0;flag=0;}
} */
}
void square(void)
{
if(i++<sqar_num) {cs=0;P2=0XFF;cs=1;}
else{cs=0;P2=0X00;cs=1;}
}
void triangle(void)
{
cs=0;P2=num++;cs=1;
}
void stw(void)
{
cs=0;P2=sanjiao_num[num++];cs=1;
if(num==255){num=0;flag=1;}
}
//1602顯示開始
void write_command(unsigned char command)
{
rs=0;
P0=command;
lcdcs=1;
lcdcs=0;
}
void write_data(unsigned char data0)
{
rs=1;
P0=data0;
lcdcs=1;
lcdcs=0;
}
void init_1602()
{
delay(1);
write_command(0x38);
delay(1);
write_command(0x0c);
delay(1);
write_command(0x06);
delay(1);
}
//1602顯示結束
/*******************頻率值轉換為字元串**********************/
void temp_to_str()
{
TempBuffer[0]=FREQ/1000+'0'; //千位
TempBuffer[1]=FREQ%1000/100+'0'; //百位
TempBuffer[2]=FREQ%1000%100/10+'0';//十位
TempBuffer[3]=FREQ%1000%100%10+'0';//個位
TempBuffer[4]='H';
TempBuffer[5]='Z';
TempBuffer[6]='\0';
}
void main()
{
TMOD=0X01;
TH0=0xff;
TL0=0xd9;
IT0=1; //設置中斷觸發方式,下降沿
EA=1;
EX0=1;
ET0=1;
IP=0X01; //鍵盤中斷級別高
init_1602();//初始化lcd
write_command(0x80);//液晶顯示位置
delay(1);
for (i=0;i<sizeof(value1)-1;i++)
{
write_data(value1[i]);
delay(1);
}
TR0=1;
while(1)
{
show_frequency();
}
}
❻ 求一個用匯編語言編寫一個8051單片機的時鍾程序(急急急啊)
給你當參缺春祥考...不足功能自己改...有問題再發問..
;P1.4小時調整伏搏 P1.5分種調整
CODE_SEG SEGMENT CODE
DATA_SEG SEGMENT DATA
STACK_SEG SEGMENT IDATA
K1 BIT P1.4
K2 BIT P1.5
RSEG DATA_SEG
KEY_S: DS 1
KEY_V: DS 1
DIS_DIGIT: DS 1
SEC: DS 1
DIS_INDEX: DS 1
HOUR: DS 1
MIN: DS 1
SEC100: DS 1
DIS_BUF: DS 8
BUF_HOUR_H EQU DIS_BUF ; 小時十位
BUF_HOUR_L EQU DIS_BUF+1 ; 小時個森氏位
BUF_MIN_H EQU DIS_BUF+3 ; 分十位
BUF_MIN_L EQU DIS_BUF+4 ; 分個位
BUF_SEC_H EQU DIS_BUF+6 ; 秒十位
BUF_SEC_L EQU DIS_BUF+7 ; 秒個位
RSEG STACK_SEG
STACK: DS 20
;===============================================================================
CSEG AT 0000H
JMP MAIN
CSEG AT 0000BH
LJMP TIMER0
CSEG AT 0001BH
LJMP TIMER1
;===============================================================================
RSEG CODE_SEG
MAIN:
USING 0
MOV SP, #(STACK-1) ;
MOV P0,#0FFH
MOV P2,#0FFH
MOV TMOD,#011H ; 定時器0, 1工作模式1, 16位定時方式
MOV TH0,#0FCH
MOV TL0,#017H
MOV TH1,#0DCH
CLR A
MOV TL1,A
MOV HOUR,#12 ;
CLR A ;
MOV MIN,A
MOV SEC,A
MOV SEC100,A
MOV A,HOUR
MOV B,#10
DIV AB
MOV DPTR,#DIS_CODE
MOVC A,@A+DPTR
MOV BUF_HOUR_H,A ; 時十位
MOV A,HOUR
MOV B,#10
DIV AB
MOV A,B
MOVC A,@A+DPTR
MOV BUF_HOUR_L,A ; 時個位
MOV A,MIN
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV BUF_MIN_H,A ; 分十位
MOV A,MIN
MOV B,#10
DIV AB
MOV A,B
MOVC A,@A+DPTR
MOV BUF_MIN_L,A ; 分個位
MOV A,SEC
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV BUF_SEC_H,A ; 秒十位
MOV A,SEC
MOV B,#10
DIV AB
MOV A,B
MOVC A,@A+DPTR
MOV BUF_SEC_L,A ; 秒個位
MOV BUF_HOUR_H+02H,#0BFH
MOV BUF_HOUR_H+05H,#0BFH
MOV DIS_DIGIT,#0FEH
CLR A
MOV DIS_INDEX,A
MOV IE,#08AH ; 使能timer0,1 中斷
SETB TR0
SETB TR1
MOV KEY_V,#03H
MAIN_LP:
LCALL SCAN_KEY ; 鍵掃描
JZ MAIN_LP ; 無鍵返回
MOV R7,#10 ; 延時10ms
LCALL DELAYMS ; 延時去抖動
LCALL SCAN_KEY ; 再次掃描
JZ MAIN_LP ; 無鍵返回
MOV KEY_V,KEY_S ; 保存鍵值
LCALL PROC_KEY ; 鍵處理
SJMP MAIN_LP ; 調回主循環
;===============================================================================
SCAN_KEY:
; 掃鍵掃描子程序
; 保存按鍵狀態到key_s
; 返回: A --- 按鍵是否按下(BOOL)
CLR A
MOV C,K1 ; 讀按鍵K1
MOV ACC.0,C
MOV C,K2 ; 讀按鍵K2
MOV ACC.1,C
MOV KEY_S,A ; 保存按鍵狀態到key_s
XRL A,KEY_V
RET
;===============================================================================
PROC_KEY:
; 鍵處理子程序
; 傳入參數: KEY_V --- 按鍵值
; 返回值: 無
CLR EA
MOV A,KEY_V
JNB ACC.0,PROC_K1
JNB ACC.1,PROC_K2
SJMP END_PROC_KEY
PROC_K1: ; 按鍵k1處理
LCALL INC_HOUR ; 小時加1
SJMP END_PROC_KEY
PROC_K2: ; 按鍵K2處理
INC MIN ; 分鍾加1
MOV A,MIN ;
SETB C
SUBB A,#59
JC K2_UPDATE_MIN ; 如果分鍾等於60,則分清0,小時加1
CLR A ;
MOV MIN,A
K2_UPDATE_MIN: ; 更新分顯示緩沖區
MOV A,MIN
MOV B,#10
DIV AB ; A = MIN / 10
MOV DPTR,#DIS_CODE
MOVC A,@A+DPTR
MOV BUF_MIN_H,A ; 更新分十位
MOV A,MIN
MOV B,#10
DIV AB
MOV A,B ; A = MIN % 10
MOVC A,@A+DPTR
MOV BUF_MIN_L,A ; 更新分個位
END_PROC_KEY:
SETB EA
RET
;===============================================================================
USING 0
TIMER0:
; 定時器0中斷服程序, 用於數碼管的動態掃描
; DIS_INDEX --- 顯示索引, 用於標識當前顯示的數碼管和緩沖區的偏移量
; DIS_DIGIT --- 位選通值, 傳送到P2口用於選通當前數碼管的數值, 如等於0xfe時,
; 選通P2.0口數碼管
; DIS_BUF --- 顯於緩沖區基地址
PUSH ACC
PUSH PSW
PUSH AR0
MOV TH0,#0FCH
MOV TL0,#017H
MOV P2,#0FFH ; 先關閉所有數碼管
MOV A,#DIS_BUF ; 獲得顯示緩沖區基地址
ADD A,DIS_INDEX ; 獲得偏移量
MOV R0,A ; R0 = 基地址 + 偏移量
MOV A,@R0 ; 獲得顯示代碼
MOV P0,A ; 顯示代碼傳送到P0口
MOV P2,DIS_DIGIT
MOV A,DIS_DIGIT ; 位選通值左移, 下次中斷時選通下一位數碼管
RL A
MOV DIS_DIGIT,A
INC DIS_INDEX ; DIS_INDEX加1, 下次中斷時顯示下一位
ANL DIS_INDEX,#0x07 ; 當DIS_INDEX等於8(0000 1000)時, 清0
POP AR0
POP PSW
POP ACC
RETI
;===============================================================================
USING 0
TIMER1:
; 定時器1中斷服務程序, 產生時基信號10ms
;
;
PUSH PSW
PUSH ACC
PUSH B
PUSH DPH
PUSH DPL
MOV TH1,#0DCH
INC SEC100
MOV A,SEC100
CLR C
SUBB A,#100 ; 是否中斷100次(達到1s)
JC END_TIMER1 ; < 1S
MOV SEC100,#00H ; 達到1s
LCALL INC_SEC ; 秒加1
END_TIMER1:
POP DPL
POP DPH
POP B
POP ACC
POP PSW
RETI ;
;===============================================================================
INC_SEC:
INC SEC
MOV A,SEC
SETB C
SUBB A,#59 ;
JC UPDATE_SEC
CLR A
MOV SEC,A
LCALL INC_MIN
UPDATE_SEC:
MOV A,SEC
MOV B,#10
DIV AB ; A = SEC / 10
MOV DPTR,#DIS_CODE
MOVC A,@A+DPTR ;
MOV BUF_SEC_H,A ;
MOV A,SEC
MOV B,#10
DIV AB
MOV A,B ; A = SEC % 10
MOVC A,@A+DPTR
MOV BUF_SEC_L,A
RET
;===============================================================================
INC_MIN:
INC MIN ; 分鍾加1
MOV A,MIN ;
SETB C
SUBB A,#59
JC UPDATE_MIN ; 如果分鍾等於60,則分清0,小時加1
CLR A ;
MOV MIN,A
LCALL INC_HOUR ; 小時加1
UPDATE_MIN: ; 更新分顯示緩沖區
MOV A,MIN
MOV B,#10
DIV AB ; A = MIN / 10
MOV DPTR,#DIS_CODE
MOVC A,@A+DPTR
MOV BUF_MIN_H,A ; 更新分十位
MOV A,MIN
MOV B,#10
DIV AB
MOV A,B ; A = MIN % 10
MOVC A,@A+DPTR
MOV BUF_MIN_L,A ; 更新分個位
RET
;===============================================================================
INC_HOUR:
INC HOUR ; 小時加1
MOV A,HOUR
SETB C
SUBB A,#24
JC UPDATE_HOUR ; 如果小時等於24,則小時清0
CLR A
MOV HOUR,A ; 小時清0
UPDATE_HOUR:
MOV A,HOUR
SETB C
SUBB A,#10
JC UPDATE_HOUR1 ; 如果小時小於10,則十位0不顯示
MOV A,HOUR
MOV B,#10
DIV AB
MOV DPTR,#DIS_CODE
MOVC A,@A+DPTR ;
MOV BUF_HOUR_H,A
SJMP UPDATE_HOUR2
UPDATE_HOUR1:
MOV BUF_HOUR_H,#0FFH
UPDATE_HOUR2:
MOV A,HOUR
MOV B,#10
DIV AB
MOV A,B
MOV DPTR,#DIS_CODE
MOVC A,@A+DPTR
MOV BUF_HOUR_L,A
RET
;===============================================================================
DELAYMS:
; 延時子程序
; 傳入參數:R7 --- 延時值(MS)
; 返回值:無
MOV A,R7
JZ END_DLYMS
DLY_LP1:
MOV R6,#185
DLY_LP2:
NOP
NOP
NOP
DJNZ R6,DLY_LP2
DJNZ R7,DLY_LP1
END_DLYMS:
RET
; END OF DELAYMS
;===============================================================================
DIS_CODE:
DB 0C0H
DB 0F9H
DB 0A4H
DB 0B0H
DB 099H
DB 092H
DB 082H
DB 0F8H
DB 080H
DB 090H
DB 0FFH
END