study51
驱动牛犊
驱动牛犊
  • 注册日期2002-11-25
  • 最后登录2005-09-14
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1160回复:0

各位兄弟,小弟是新手,问题多多,都是PC底层的问题,请指点迷津

楼主#
更多 发布于:2003-06-07 10:00
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语言的演示程序的原码,定时器程序最好可以设定时间间隔,或者推荐书籍文章。
游客

返回顶部