阅读:1162回复:0
各位兄弟,小弟是新手,问题多多,都是PC底层的问题,请指点迷津
1. 应用系统需要经常读取系统时间(包括年月日和时分秒),同时要用定时器每隔10ms产一次中断。目前用IRQ0做计时器中断,程序如下。问题是:如果没有调用InitialTimer(),程序能够显示时间;如果调用InitialTimer(),设定计时器中断,那么程序不能显示时间,分析程序,应该是gettime()读到的时间不对;另外一方面:如果在“if (ti_sec_temp != (*TimeNow).ti_sec )”处设定断点调试,则可以正常显示时间(目前是在PC上面试验)。程序如下:
#include <dos.h> /*********** Define Interrupt Vector Entry ************/ #define TIMER_VECT 0x08 #define COMM1_VECT 0x0C #define COMM2_VECT 0x0B /******** Define intterrupt mask bit for IMR ********/ #define TIMER_IMR 0xFE /* Timer use IRQ0 1111 1110 */ #define PORT1_IMR 0xEF /* COMM1 use IRQ4 1110 1111 */ #define PORT2_IMR 0xF7 /* COMM2 use IRQ3 1111 0111 */ #define PORT3_IMR 0xEF /* COMM3 use IRQ4 1110 1111 */ #define PORT4_IMR 0xF7 /* COMM4 use IRQ3 1111 0111 */ /********** Defines Serial Ports Base Address **********/ #define COMM1 0x3F8 #define COMM2 0x2F8 #define COMM3 0x3E8 #define COMM4 0x2E8 /*************** Define BaudRate Table *****************/ #define BAUD_115200 0x01 #define BAUD_57600 0x02 #define BAUD_38400 0x03 #define BAUD_19200 0x06 #define BAUD_9600 0x0C #define BAUD_4800 0x18 #define BAUD_2400 0x30 /******************************************************/ #define SendEOI outportb(0x20,0x20) #define BUF_SIZE 8 /******************************************************/ #define TICKCNT_BEGIN 100 #define TICKCNT10mS 200 /* from 20 to 40 for comm1ISR, 0.2Sec = 20 x 10mS */ struct time *TimeNow; struct date *DateNow; unsigned int TimerTick10mS = TICKCNT_BEGIN; unsigned int TimeSecCnt = 0, TimerFlag = 0; void interrupt (*OldTimerISR)(), interrupt NewTimerISR(void); void interrupt (*OldComm1ISR)(), interrupt NewComm1ISR(void); void SetBackISR(void) { outportb(0x21,inportb(0x21) | (~TIMER_IMR)); setvect(TIMER_VECT, OldTimerISR); /* set back the timer_vect to old ISR */ } void interrupt NewTimerISR(void) { if(++TimerTick10mS >= TICKCNT10mS ) { TimerFlag = 1; TimeSecCnt++; /* display in main() just for debug */ TimerTick10mS = TICKCNT_BEGIN; } SendEOI; } /************************************************************* Initial Timer for 10ms per interrupt *************************************************************/ void InitialTimer() { TimerFlag = 0; OldTimerISR = getvect(TIMER_VECT); setvect(TIMER_VECT, NewTimerISR); /* 0x3000 for 10mS */ outportb(0x43, 0x34); outportb(0x40, 0x00); outportb(0x40, 0x30); outportb(0x21, inportb(0x21) & TIMER_IMR); } void main(void) { unsigned int Flag = 1; unsigned char ti_sec_temp; /* InitialTimer(); */ gettime(TimeNow); ti_sec_temp =(*TimeNow).ti_sec; printf(\"\\n%dH : %dM : %dS\",(*TimeNow).ti_hour,(*TimeNow).ti_min,(*TimeNow).ti_sec); while(Flag) { gettime(TimeNow); /* if(TimerFlag)*/ if (ti_sec_temp != (*TimeNow).ti_sec ) /*每秒一次*/ /* 如果使用计时中断产生信号,则不用此判断 */ { TimerFlag = 0; ti_sec_temp = (*TimeNow).ti_sec; printf(\"\\n%dH : %dM : %dS\",(*TimeNow).ti_hour,(*TimeNow).ti_min,(*TimeNow).ti_sec); getdate(DateNow); printf(\"\\n%dY - %dM - %dD\",(*DateNow).da_year,(*DateNow).da_mon,(*DateNow).da_day); } else { /* printf(\"\\nno\");*/ } /* delay(10000);*/ if(kbhit()) { if(getch() == 0x1b) Flag =0; } } SetBackISR(); } 2. 计时器中断计时不准确,例如设定10mS(0x3000)的中断累计100次为1秒,实际超过1秒,大约偏慢10%,请问什么原因 3. Gettime()和getdate()函数会互相影响,比如先gettime(TimeNow),再getdate(DateNow),发现TimeNow的成员的值被改变,请问什么原因?调换“getdate(DateNow);”和“printf(\"\\n%dH : %dM : %dS\",(*TimeNow).ti_hour,(*TimeNow).ti_min,(*TimeNow).ti_sec);”两句的顺序可以看到结果。 4. 此外,能否提供系统时中断(IRQ0),键盘中断(IRQ1),实时时钟中断(IRQ8)的简单的C语言的演示程序的原码,定时器程序最好可以设定时间间隔,或者推荐书籍文章。 |
|