2016年3月23日 星期三

微處理器實作: AT89S52 程式練習(計數器中斷)

        這個程式主要練習設定AT89S52的中斷並啟動,另外還要設計中斷服務程式ISR,當中斷發生時最對應的動作: 主程式先設定timer 0的中斷並啟動,然後就進入無窮迴圈(顯示mynum的值),而timer 0數到12*1024(1ms)時,即發出一個中斷,此時count 減 1,如此經過1024次之後(1秒),mynum加1,這就是一個最簡單的計時器了(以秒為單位)。


執行結果

以下為完整程式碼:

#include <REGX52.h>

#define LED_NUM_0 0xC0
#define LED_NUM_1 0xF9
#define LED_NUM_2 0xA4
#define LED_NUM_3 0xB0
#define LED_NUM_4 0x99
#define LED_NUM_5 0x92
#define LED_NUM_6 0x82
#define LED_NUM_7 0xF8
#define LED_NUM_8 0x80
#define LED_NUM_9 0x98

#define LED_OUT P1

int count = 1024;
int mynum = 0;

unsigned char led_num[10] =
{
LED_NUM_0, LED_NUM_1, LED_NUM_2, LED_NUM_3, LED_NUM_4, 
LED_NUM_5, LED_NUM_6, LED_NUM_7, LED_NUM_8, LED_NUM_9
};

void my_delay(unsigned int n)
{
unsigned int i, j;

for(j=0; j<n; j++)
for(i=0; i<120; i++) ; 

}

void led_write_1c(unsigned char r, unsigned char x)
{
P3 = ~(1 << (3-r)); //enable control bit: active LOW
LED_OUT = x;
my_delay(3);
LED_OUT = 0xFF;


void led_write_1c_nc(unsigned char r, unsigned char x)
{
P3 = ~(1 << (3-r)); //enable control bit: active LOW
LED_OUT = x;
my_delay(3);
//LED_OUT = 0xFF;


void led_write_4c(unsigned short x)
{
led_write_1c(0, led_num[x%10    ]);
led_write_1c(1, led_num[x/10%10 ]);
led_write_1c(2, led_num[x/100%10]);
led_write_1c(3, led_num[x/1000  ]);


void T0_int(void) interrupt 1
{
TL0 = (65535-1024*12) % 256;
TH0 = (65535-1024*12) / 256;

if(count ==0 )
{
count=1024; // 1024*1204*12 => 1 second
mynum++;
}
else 
count--;
}

main()
{
TMOD = 0x00;                                // set timer control register
TL0 = (65535-1024*12) % 256;     // set count number:12K(TL of timer 0)
TH0 = (65535-1024*12) / 256;      // set count number:12K(TH of timer 0)
IE = 0x82;                                       // set interrupt enable register 
TR0 = 1;                                         // enable timer 0
while(1)
{
led_write_4c(mynum);
}
}

沒有留言:

張貼留言