180 lines
2.9 KiB
C
180 lines
2.9 KiB
C
// Timer 0 take as interrupt
|
|
// Timer 1 take as delay
|
|
|
|
#include <reg51.h>
|
|
|
|
// 宣告延時函式
|
|
void delay_1500ms(void);
|
|
|
|
unsigned int timer0_counter = 150;
|
|
int seg_pos = 0, seg_num = 0;
|
|
|
|
//LED
|
|
bit lightoff = 1;
|
|
bit lighton = 0;
|
|
|
|
char code LED_light[17] = {
|
|
~0x00,
|
|
~0x01,
|
|
~0x03,
|
|
~0x07,
|
|
~0x0F,
|
|
~0x1F,
|
|
~0x3F,
|
|
~0x7F,
|
|
~0xFF,
|
|
~0x7F,
|
|
~0x3F,
|
|
~0x1F,
|
|
~0x0F,
|
|
~0x07,
|
|
~0x03,
|
|
~0x01
|
|
};
|
|
|
|
//Segment
|
|
// 宣告 D 型正反器街接腳
|
|
sbit P2_6 = P2^6;
|
|
sbit P2_7 = P2^7;
|
|
|
|
// 宣告七段顯示器函式
|
|
void Slect_Seg(unsigned char number);
|
|
void Display_Seg(unsigned char display);
|
|
|
|
//宣告數字的表示
|
|
char code NUM[10] = {
|
|
0x3F, // 0
|
|
0x06, // 1
|
|
0x5B, // 2
|
|
0x4F, // 3
|
|
0x66, // 4
|
|
0x6D, // 5
|
|
0x7D, // 6
|
|
0x07, // 7
|
|
0x7F, // 8
|
|
0x6F // 9
|
|
};
|
|
|
|
char code POS[6] = {
|
|
~0x01, // 0xfe 就是 11111110
|
|
~0x02, // 0000 0010
|
|
~0x04, // 0000 0100
|
|
~0x08, // 0000 1000
|
|
~0x10, // 0001 0000
|
|
~0x20 // 0010 0000
|
|
};
|
|
|
|
|
|
int main(void){
|
|
int i = 0;
|
|
//開啟 Timer0 和 Timer1
|
|
TMOD = 0x11;
|
|
|
|
//interrupt control
|
|
TL0 = (65536 - 9216) % 256;
|
|
TH0 = (65536 - 9216) / 256;
|
|
TF0 = 0;
|
|
TR0 = 1; //開啟計時器 timer0
|
|
ET0 = 1; //開啟 TF0 的中斷模組開關
|
|
EA = 1; //開啟中斷模組總開關
|
|
|
|
|
|
while(1){
|
|
// ********* 實作 LED *********
|
|
for(i = 0; i < 16; i++) {
|
|
P1 = LED_light[i];
|
|
delay_1500ms();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void delay_1500ms(void){
|
|
|
|
int i;
|
|
for (i = 0; i < 150; i++) {
|
|
//設定初始值
|
|
TR1 = 0;
|
|
TF1 = 0;
|
|
TL1 = (65536 - 9216) % 256;
|
|
TH1 = (65536 - 9216) / 256;
|
|
|
|
//開啟計時器 timer1
|
|
TR1 = 1;
|
|
|
|
//當 TF1 沒有溢位
|
|
while(TF1 == 0);
|
|
}
|
|
|
|
//關閉計時器
|
|
TR1 = 0;
|
|
|
|
//將 TF1 歸零
|
|
TF1 = 0;
|
|
}
|
|
|
|
|
|
// timer0 在計時到的時候(TF0 = 1)會呼叫的中斷副函式
|
|
void my_timer0(void) interrupt 1 {
|
|
|
|
//設定初始值
|
|
TL0 = (65536 - 9216) % 256;
|
|
TH0 = (65536 - 9216) / 256;
|
|
TF0 = 0;
|
|
|
|
// timer0_counter 一直遞減
|
|
timer0_counter--;
|
|
|
|
|
|
//當 timer0_counter 為 0 時,實作七段顯示器
|
|
if (timer0_counter == 0){
|
|
|
|
// *********實作七段顯示器*********
|
|
Slect_Seg(POS[seg_pos]); // 設定哪顆亮
|
|
Display_Seg(NUM[seg_num]); // 選數字
|
|
seg_pos = (seg_pos + 1) % 6;
|
|
seg_num = (seg_num + 1) % 10;
|
|
|
|
//將 timer0_counter 的值設回 150
|
|
timer0_counter = 150;
|
|
|
|
}
|
|
}
|
|
|
|
void Slect_Seg(unsigned char number) {
|
|
int j = 0;
|
|
|
|
// 關閉 D 型正反器(預防措施)
|
|
P2_7 = 0;
|
|
|
|
// 指定哪顆亮
|
|
P0 = number;
|
|
|
|
// 開啟控制哪顆亮的 D 型正反器
|
|
P2_7 = 1;
|
|
|
|
// 延時(吃哪顆亮)
|
|
for(j = 0; j < 120; j++);
|
|
|
|
// 關閉 D 型正反器(讓吃進去的那顆固定亮)
|
|
P2_7 = 0;
|
|
}
|
|
|
|
void Display_Seg(unsigned char display) {
|
|
int j = 0;
|
|
// 關閉 D 型正反器(預防措施)
|
|
P2_6 = 0;
|
|
|
|
// 指定號碼
|
|
P0 = display;
|
|
|
|
// 開啟控制哪顆亮的 D 型正反器
|
|
P2_6 = 1;
|
|
|
|
// 延時(吃號碼)
|
|
for(j = 0; j < 120; j++);
|
|
|
|
// 關閉 D 型正反器(讓吃進去的號碼固定住)
|
|
P2_6 = 0;
|
|
}
|