⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timeunit.cpp

📁 一个完整的RTU程序源码,用DOS平台,支持16串口,在天津港用的很多,8个规约103,modbus,cdt,1801,u4f
💻 CPP
字号:
#include "sc_cfg.h"
#include "common.h"
#include "extern.h"

#define TIMER_INTERRUPT 	0x08	 	// 8253 timer0 interrupt number
#define RTC_WRITE_PORT	 	0x70		// RTC write port address
#define RTC_READ_PORT 		0x71    // RTC read port address
#define TIMER_RW_PORT		 	0x40		// timer0 io port address

#define RTC_SECOND_REG	 	0x00		// RTC second register address
#define RTC_MINUTE_REG   	0x02		// RTC minute register address
#define RTC_HOUR_REG  		0x04		// RTC hour register address
#define RTC_WEEK_REG			0x06    // RTC hour register address
#define RTC_DAY_REG   		0x07		// RTC day register address
#define RTC_MONTH_REG   	0x08		// RTC month register address
#define RTC_YEAR_REG  		0x09		// RTC year register address
#define RTC_CENTURY_REG   0x32		// RTC century register address
#define RTC_SET_REG	 			0x0b		// RTC setup register address
#define RTC_STATUS_REG    0x0a		// RTC status register address

#define MS_PER_TICK				5				// the time between two timer interrupt

#define ORINGAL_CNT_H  		0x00		// timer0 orignal const high byte
#define ORINGAL_CNT_L  		0x00		// timer0 orignal const low byte

static INT8U month_tab[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static sclock systemclock;

INT16U port_timeout[MAX_PORT];

static INT16U all_timer = 0;
static INT16U old_isp_count = 0;

static void SoftClock();												// software clock
void ReadTime(sclock *ptr);
void SetTimer();								 				// set 8253 interrupt
void ResetTimer(); 											// reset 8253 interrupt
void interrupt timer_newhand(...);  		// interrupt service
void interrupt (*timer_oldhand)(...); 	// keep old service program
void GetClock(sclock *ptr);             // get time from here
void SetClock(sclock *ptr);							// set time to here

BOOLEAN check_mtimeout(const INT16U timer, const int gap);
INT16U get_mtime(void);

BOOLEAN check_mtimeout(const INT16U timer, const int gap)
{
	INT16U ctimer;

	OS_ENTER_CRITICAL();
	ctimer = all_timer;
	OS_EXIT_CRITICAL();

	if (ctimer >= timer) {
		if ((ctimer - timer) >= gap) return (TRUE);
		else return (FALSE);
	}
	else {
		if ((~(timer - ctimer) + 1) >= gap) return (TRUE);
		else return (FALSE);
	}
}

INT16U get_mtime(void)
{
	INT16U ctimer;

	OS_ENTER_CRITICAL();
	ctimer = all_timer;
	OS_EXIT_CRITICAL();

	return (ctimer);
}

void interrupt timer_newhand(...)
{
	int i;
#ifdef YX_INT_SAM
	INT8U DataonPA0, DataonPB0;
#endif

	disable();

// because YC and YM use the same port to sample
// while timer interrupt comes , we need to keep orignal output
#ifdef YX_INT_SAM
	DataonPA0 = inp(hardwareset[3].address + 1);
	DataonPB0 = inp(hardwareset[3].address + 2);
#endif

	SoftClock();                          // software clock

	memcpy(&systemclock, &systemclock, sizeof(sclock));
																				// get system clock

// now begin to sample yx and restore output
#ifdef YX_INT_SAM
	yx.boardyxget();
	outp(hardwareset[3].address + 1, DataonPA0);
	outp(hardwareset[3].address + 2, DataonPB0);
#endif

	all_timer += MS_PER_TICK;

// 50ms run once
	if (++old_isp_count > (55 / MS_PER_TICK)) {
		old_isp_count = 0;
		ykreg.timer++;

		for (i = 0; i < MAX_PORT; i++)
			if (port_timeout[i] < 6000) port_timeout[i]++;
		timer_oldhand();
	}
	else outp(0x20, 0x20);

	enable();
}

void ReadTime(sclock *ptr)
{
	INT8U clkmask;

	outp(RTC_WRITE_PORT, RTC_SET_REG);
	clkmask = inp(RTC_READ_PORT) | 0x80;
	outp(RTC_WRITE_PORT, RTC_SET_REG);
	outp(RTC_READ_PORT, clkmask);  				// stop RTC for reading

	outp(RTC_WRITE_PORT, RTC_SECOND_REG);
	ptr->second = BcdtoBin(inp(RTC_READ_PORT)); // read RTC second

	outp(RTC_WRITE_PORT, RTC_MINUTE_REG);
	ptr->minute = BcdtoBin(inp(RTC_READ_PORT)); // read RTC minute

	outp(RTC_WRITE_PORT, RTC_HOUR_REG);
	ptr->hour = BcdtoBin(inp(RTC_READ_PORT));   // read RTC hour

	outp(RTC_WRITE_PORT, RTC_WEEK_REG);
	ptr->weekday = BcdtoBin(inp(RTC_READ_PORT));

	outp(RTC_WRITE_PORT, RTC_DAY_REG);
	ptr->day = BcdtoBin(inp(RTC_READ_PORT));    // read RTC day

	outp(RTC_WRITE_PORT, RTC_MONTH_REG);
	ptr->month = BcdtoBin(inp(RTC_READ_PORT));  // read RTC month

	outp(RTC_WRITE_PORT, RTC_CENTURY_REG);
	ptr->year = BcdtoBin(inp(RTC_READ_PORT));
	outp(RTC_WRITE_PORT, RTC_YEAR_REG);                // read RTC year
	ptr->year = ptr->year * 100 + BcdtoBin(inp(RTC_READ_PORT));

	outp(RTC_WRITE_PORT, RTC_SET_REG);
	outp(RTC_READ_PORT, clkmask & 0x7f);  	// reading complete start RTC
}

void SetTimer(void)
{
	INT16U count;

	ReadTime(&systemclock);
	systemclock.msecond = 0;

  count = (INT16U)(((INT32U)2386360L * MS_PER_TICK / 1000 + 1) >> 1); 

	outp(TIMER_RW_PORT, count & 0xff);
	outp(TIMER_RW_PORT, (count >> 8) & 0xff);			// set system timer0 gap

	timer_oldhand = getvect(TIMER_INTERRUPT);          // keep old int service
	setvect(TIMER_INTERRUPT, timer_newhand);          // load new int service
}

void ResetTimer(void)
{
	struct time t;
	struct date d;

	outp(TIMER_RW_PORT, ORINGAL_CNT_L);
	outp(TIMER_RW_PORT, ORINGAL_CNT_H);  // restore orignal timer0 gap
	setvect(TIMER_INTERRUPT, timer_oldhand);		// restore old int service

	OS_ENTER_CRITICAL();

	t.ti_hour = systemclock.hour;
	t.ti_min = systemclock.minute;
	t.ti_sec = systemclock.second;
	t.ti_hund = systemclock.msecond / 10;
	d.da_year = systemclock.year;
	d.da_mon = systemclock.month;
	d.da_day = systemclock.day;

	OS_EXIT_CRITICAL();

	settime(&t);
	setdate(&d);           				// restore system time
}

static void SoftClock(void)
{
	systemclock.msecond += MS_PER_TICK;         // mil second increase
	if (systemclock.msecond < 1000) return; 		// ms clock
	systemclock.msecond = 0;

	if (++systemclock.second < 60) return;    		// s clock
	systemclock.second = 0;

	if (++systemclock.minute < 60) return;  		// minute clock
	systemclock.minute = 0;

	if (++systemclock.hour < 24) return;  			// hour clock
	systemclock.hour = 0;

	if (++systemclock.weekday > 7) systemclock.weekday = 1;

	if ((systemclock.year % 4) == 0 && ((systemclock.year % 100) != 0
		|| (systemclock.year % 400) == 0)) month_tab[2] = 29;
	else month_tab[2] = 28;	   					// feb month set
	if (++systemclock.day <= month_tab[systemclock.month]) return; // day clock
	systemclock.day = 1;

	if (++systemclock.month <= 12) return; 		// month clock
	systemclock.month = 1;

	systemclock.year++;   					// year clock
}

void GetClock(sclock *ptr)
{
	OS_ENTER_CRITICAL();

	memcpy(ptr, &systemclock, sizeof(sclock));		// get system clock

	OS_EXIT_CRITICAL();
}

void SetClock(sclock *ptr)
{
	INT8U clkmask;

	OS_ENTER_CRITICAL();

	memcpy(&systemclock, ptr, sizeof(sclock));	// modify system clock

	OS_EXIT_CRITICAL();

	outp(RTC_WRITE_PORT, RTC_SET_REG);
	clkmask = inp(RTC_READ_PORT) | 0x80;
	outp(RTC_WRITE_PORT, RTC_SET_REG);
	outp(RTC_READ_PORT, clkmask);				// begin setup RTC time

	outp(RTC_WRITE_PORT, RTC_SECOND_REG);
	outp(RTC_READ_PORT, (INT8U)BintoBcd(systemclock.second));// write RTC second

	outp(RTC_WRITE_PORT, RTC_MINUTE_REG);
	outp(RTC_READ_PORT, (INT8U)BintoBcd(systemclock.minute));// write RTC minute

	outp(RTC_WRITE_PORT, RTC_HOUR_REG);
	outp(RTC_READ_PORT, (INT8U)BintoBcd(systemclock.hour));	// write RTC hour

	outp(RTC_WRITE_PORT, RTC_DAY_REG);
	outp(RTC_READ_PORT, (INT8U)BintoBcd(systemclock.day));	// write RTC day

	outp(RTC_WRITE_PORT, RTC_MONTH_REG);
	outp(RTC_READ_PORT, (INT8U)BintoBcd(systemclock.month));	// write RTC month

	outp(RTC_WRITE_PORT, RTC_CENTURY_REG);
	outp(RTC_READ_PORT, (INT8U)(BintoBcd(systemclock.year) >> 8));
	outp(RTC_WRITE_PORT, RTC_YEAR_REG);                      	// write RTC year
	outp(RTC_READ_PORT, (INT8U)(BintoBcd(systemclock.year)));

	outp(RTC_WRITE_PORT, RTC_SET_REG);
	outp(RTC_READ_PORT, clkmask & 0x7f); 		// quit setup mode
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -