2008年10月15日 星期三

C語言練習(8051)



















對我來說 相對的C語言較不熟 所以特別準備板子(muc是笙泉的89E58) 要練習C語 哈哈






PROGRAM_1
// FILE: timer.c
// Function:Init_IRQ()
// Description:
// Date:2008_10_15
#include "REG_MPC89E58.H"
// io port Description
#define _ONE P24
#define _TWO P27
#define _THREE P26
#define _FOUR P25
#define BIBI P20
//const
_7_seg[10]={0x09,0xED,0x2A,0x68,0xCC,0x58,0x18,0xC9,0x08,0xC8};
int time_cnt;
unsigned char _1_sec_cnt=0x14 ;
unsigned char scan_cnt=0X00 ;
unsigned char disp ;
void Init_IRQ(){
// ET0 = 0x01; //Enable Timer Interrupt 0
ET1 = 0x01; //Enable Timer Interrupt 1
ET2 = 0x01; //Enable Timer Interrupt 2

TMOD = 0X10 ;
TH1 = 0X3C ;
TL1 = 0XB0 ;
T2CON = 0X00 ;
RCAP2H = 0XFA ;
RCAP2L = 0X00 ;
EA = 0x01 ; //Enable All Interrupt
TR1 = 0X01 ; //START TIMER1
T2CON = 0X04 ; //START TIMER2 }

void Timer_Interrupt_1() interrupt 3
{ _1_sec_cnt -- ;
if (_1_sec_cnt==0)
{ time_cnt ++ ;
_1_sec_cnt=0x14 ;}
// BIBI = !BIBI ;
TH1 = 0X3C ;
TL1 = 0XB0 ; }
void Timer_Interrupt_2() interrupt 5{
T2CON = T2CON & 0X7F; //CLEAR TIMER2 INT_FLAG
// BIBI = !BIBI ;
if (scan_cnt>3)
{scan_cnt=0x00;}
// 注意 基本上 以下4個IF會依順序 ,往下執行且每次都是如此
// 但程式本意 是希望進入timer2後,馬上去執行,要顯示的位數就馬上離開
// 所以多了每次依順序比較scan_cnt等於多執行了些指令
if (scan_cnt==3)
{ P0=0XFF;
_ONE=0x01;
_TWO=0x01;
_THREE=0X01;
_FOUR=0X00;
disp = time_cnt / 1000 ;
P0= _7_seg[disp] ;
scan_cnt ++ ;
}
if (scan_cnt==2)
{ P0=0XFF;
_ONE=0x01;
_TWO=0x01;
_THREE=0X00;
_FOUR=0X01;
disp = (time_cnt%1000)/100 ;
P0= _7_seg[disp] ;
scan_cnt ++ ;
}
if (scan_cnt==1)
{ P0=0XFF;
_ONE=0x01;
_TWO=0x00;
_THREE=0X01;
_FOUR=0X01;
disp = (time_cnt/10)%10 ;
P0= _7_seg[disp] ;
scan_cnt ++ ;
}
if (scan_cnt==0)
{ P0=0XFF;
_ONE=0x00;
_TWO=0x01;
_THREE=0X01;
_FOUR=0X01;
disp = time_cnt % 10 ;
P0= _7_seg[disp] ;
scan_cnt ++ ;
}
}
void Main()
{ Init_IRQ();
while (1) {}
}



另一種寫法
PROGRAM_2
// FILE: timer.c// Function:
// Description:timer IRQ TEST
// Date:2008_10_15
#include "REG_MPC89E58.H"
// io port Description
#define _ONE P24
#define _TWO P27
#define _THREE P26
#define _FOUR P25
#define BIBI P20
//const
_7_seg[10]={0x09,0xED,0x2A,0x68,0xCC,0x58,0x18,0xC9,0x08,0xC8};
int time_cnt;
unsigned char _1_sec_cnt=0x14 ;
unsigned char scan_cnt=0X00 ;
unsigned char disp ;
void Init_IRQ()
{
// ET0 = 0x01; //Enable Timer Interrupt 0
ET1 = 0x01; //Enable Timer Interrupt 1
ET2 = 0x01; //Enable Timer Interrupt 2
TMOD = 0X10 ;
TH1 = 0X3C ;
TL1 = 0XB0 ;
T2CON = 0X00 ;
RCAP2H = 0XFA ;
RCAP2L = 0X00 ;
EA = 0x01 ; //Enable All Interrupt
TR1 = 0X01 ; //START TIMER1
T2CON = 0X04 ; //START TIMER2
}

void Timer_Interrupt_1() interrupt 3
{
_1_sec_cnt -- ;
if (_1_sec_cnt==0)
{ time_cnt ++ ;
_1_sec_cnt=0x14 ;}
// BIBI = !BIBI ;
TH1 = 0X3C ;
TL1 = 0XB0 ; }
void Timer_Interrupt_2() interrupt 5
{
T2CON = T2CON & 0X7F; //CLEAR TIMER2 INT_FLAG
// BIBI = !BIBI ;
if (scan_cnt>3)
{scan_cnt=0x00;}
// 用 switch 就可直接跳到所要執行的部分,且執行完,馬上break跳出
// 和用 if 有明顯不同 須注意
switch(scan_cnt)
{case 0:




P0=0XFF;
_ONE=0x00;
_TWO=0x01;
_THREE=0X01;
_FOUR=0X01;
disp = time_cnt % 10 ;
P0= _7_seg[disp] ;
scan_cnt ++ ;
break;
case 1:




P0=0XFF;
_ONE=0x01;
_TWO=0x00;
_THREE=0X01;
_FOUR=0X01;
disp = (time_cnt/10)%10 ;
P0= _7_seg[disp] ;
scan_cnt ++ ;
break;
case 2:




P0=0XFF;
_ONE=0x01;
_TWO=0x01;
_THREE=0X00;
_FOUR=0X01;
disp = (time_cnt%1000)/100 ;
P0= _7_seg[disp] ;
scan_cnt ++ ;
break;
case 3:




P0=0XFF;
_ONE=0x01;
_TWO=0x01;
_THREE=0X01;
_FOUR=0X00;
disp = time_cnt / 1000 ;
P0= _7_seg[disp] ;
scan_cnt ++ ;
break;
}



}
void Main(void)
{ Init_IRQ();
while (1) {}
}



PROGRAM_3



這支程式和PROGRAM_1一樣,但它在TIMER_2的地方不一樣,這樣的結果,在實際執行上會造成

什麼樣的結果呢?

"程式其他部分一樣,省略 參照PROGRAM_1

void Timer_Interrupt_2() interrupt 5

{
T2CON = T2CON & 0X7F; //CLEAR TIMER2 INT_FLAG

// BIBI = !BIBI ;

if (scan_cnt>3) {scan_cnt=0x00;}
// 注意 基本上 以下4個IF會依順序 ,往下執行且每次都是如此

// 但程式本意 是希望進入timer2後,馬上去執行,要顯示的位數就馬上離開

// 所以多了每次依順序比較scan_cnt等於多執行了些指令

if (scan_cnt==0)

{ P0=0XFF;

_ONE=0x00;

_TWO=0x01;

_THREE=0X01;

_FOUR=0X01;

disp = time_cnt % 10 ;

P0= _7_seg[disp] ;

scan_cnt ++ ;
}

if (scan_cnt==1)

{ P0=0XFF;

_ONE=0x01;

_TWO=0x00;

_THREE=0X01;

_FOUR=0X01;

disp = (time_cnt/10)%10 ;

P0= _7_seg[disp] ;

scan_cnt ++ ;
}

if (scan_cnt==2)

{ P0=0XFF;

_ONE=0x01;

_TWO=0x01;

_THREE=0X00;

_FOUR=0X01;

disp = (time_cnt%1000)/100 ;

P0= _7_seg[disp] ;

scan_cnt ++ ;
}

if (scan_cnt==3)

{ P0=0XFF;

_ONE=0x01;

_TWO=0x01;

_THREE=0X01;

_FOUR=0X00;

disp = time_cnt / 1000 ;

P0= _7_seg[disp] ;

scan_cnt ++ ;
}

看出來了嗎 ? 可看下圖 PROGRAM_3執行結果會變成這樣
但PROGRAM_1沒有這問題,而PROGRAM_2才是決解之道

再來 PROGRAM_2可以把TIMER_2裡的以下幾行移到MAIN內,這樣才不會浪費MCU執行效能

disp = time_cnt % 10 ;

disp = (time_cnt/10)%10 ;

disp = (time_cnt%1000)/100 ;

disp = time_cnt / 1000 ;

移到main中並且改為如下,

disp_0 = time_cnt % 10 ;

disp_1 = (time_cnt/10)%10 ;

disp_2 = (time_cnt%1000)/100 ;

disp_3 = time_cnt / 1000 ;

timer_2中的P0= _7_seg[disp] 也要跟著改,還有要宣告disp_0,disp_1,disp_2,disp_3喔

沒有留言:

張貼留言