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

📄 test.c

📁 uCOS电子钟 pc机上模拟ucos实时操作系统上跑电子钟程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
*********************************************************************************************************
*                                                uC/OS-II
*                                          The Real-Time Kernel
*
*                           (c) Copyright 1992-2008, Bucker
*                                           All Rights Reserved
*
*                                               EXAMPLE #1
*********************************************************************************************************
*/

#include "includes.h"
#include "image.h"
#include "led.h"

/*
*********************************************************************************************************
*                                               CONSTANTS
*********************************************************************************************************
*/

#define TASK_STK_SIZE 512								      	/* Size of each task's stacks (# of WORDs)            */
#define VIDEO 0x10															/*BIOS调用中INT10H*/
#define MY_TASK_START_PRIO 4
/*
*********************************************************************************************************
*                                               VARIABLES
*********************************************************************************************************
*/

OS_STK TaskDispStk[TASK_STK_SIZE];        		/* Tasks stacks                                  */
OS_STK TaskMenuStk[TASK_STK_SIZE];        		/* Tasks stacks                                  */
OS_STK TaskClockStk[TASK_STK_SIZE];        		/* Tasks stacks                                  */
OS_STK TaskSetDateStk[TASK_STK_SIZE];        	/* Tasks stacks                                  */
OS_STK TaskSetTimeStk[TASK_STK_SIZE];        	/* Tasks stacks                                  */
OS_STK TaskSetAlertStk[TASK_STK_SIZE];        	/* Tasks stacks                                  */
OS_STK TaskStartStk[TASK_STK_SIZE];				/* Tasks stacks                                  */
OS_EVENT *TimeKey;
void *TimeKeyMsg[10];

FILE *Fr;
INT8U Status = 0;
struct TIME
{
	INT16U Year;
	INT8U Month;
	INT8U Day;
	INT8U Hour;
	INT8U Minute;
	INT8U Second;
	INT8U Week;
} Time;

/*
*********************************************************************************************************
*                                           FUNCTION PROTOTYPES
*********************************************************************************************************
*/

void TaskDisp(void *data);                       /* Function prototypes of tasks                  */
void TaskMenu(void *data);                       /* Function prototypes of tasks                  */
void TaskClock(void *data);                       /* Function prototypes of tasks                  */
void TaskSetDate(void *pdata);									/*设定日期*/
void TaskSetTime(void *pdata);									/*设定时间*/
void TaskSetAlert(void *pdata);									/*设定闹钟*/
void TaskStart(void *data);                  /* Function prototypes of Startup task           */
void PSet(INT16U x,INT16U y,INT16U color);
void InitScr(void);
void CloseScr(void);
void OpenHZK(char *FileName);
void DispChinese(INT16U x,INT16U y,char *Hz,INT8U att);
void DispChineseLine(INT16U x,INT16U y,char *Str,INT8U att);
void DispLED(INT16U x,INT16U y,INT8U led);
void Update(INT8U att);
void ResumeLCD(void);
INT8U GetWeek(INT16U year,INT8U month,INT16U day);
void DispNum(INT16U x,INT16U y,INT8U data,INT8U att);
void DispData(INT16U x,INT16U y,INT16U data,INT8U att);
INT8U EditData(INT16U x,INT16U y,INT16U *data,INT8U att,INT16S min,INT16S max);
/*
*********************************************************************************************************
*                                           模拟在LCD上的指定坐标画一个点
*********************************************************************************************************
*/

void PSet(INT16U x,INT16U y,INT16U color)
{
	union REGS regs;
	regs.h.ah = 0x0c;
	regs.h.al = color;
	regs.x.cx = x + 0x10;
	regs.x.dx = y + 0x18;
	int86(VIDEO,&regs,&regs);
}
/*
*********************************************************************************************************
*                                           产生一个仿真的LCD屏幕
*********************************************************************************************************
*/

void InitScr()
{
	union REGS regs;
	INT16U A;
	regs.x.ax = 0x0013;
	int86(VIDEO,&regs,&regs);
	for (A = 0;A < 130;A++)
	{
		PSet(A - 1,-1,2);
		PSet(A - 1,64,2);
	}
	for (A = 0;A < 66;A++)
	{
		PSet(- 1,A - 1,2);
		PSet(128,A - 1,2);
	}
}
/*
*********************************************************************************************************
*                                           将显示模式改为字符方式
*********************************************************************************************************
*/

void CloseScr()
{
	union REGS regs;
	regs.x.ax = 0x0003;
	int86(VIDEO,&regs,&regs);
}

/*
*********************************************************************************************************
*                                           打开字库文件
*********************************************************************************************************
*/

void OpenHZK(char *FileName)
{
	if (Fr != NULL) fclose(Fr);
	if ((Fr = fopen(FileName,"rb")) == NULL)
		exit(0);
}

/*
*********************************************************************************************************
*                                           模拟在LCD的指定位置显示一个汉字
*********************************************************************************************************
*/

void DispChinese(INT16U x,INT16U y,char *Hz,INT8U att)
{
	INT8U a,b,c,d;
	if (Fr != NULL)
	{
		if (!(att & 0x80))
			fseek(Fr,(long)((INT16U)((INT8U)Hz[0] - 161) * 94 + (INT8U)Hz[1] - 161) * 32,SEEK_SET);
		else
			fseek(Fr,(long)((INT16U)((INT8U)Hz[0] - 161) * 94 + (INT8U)Hz[1] - 161) * 32 + 267616L,SEEK_SET);
		for (a = 0;a < 16;a++)
		{
			for (b = 0;b < 2;b++)
			{
				c = fgetc(Fr);
				for (d = 0;d < 8;d++)
				{
					if (!(att & 0x01))
					{
						if (c & 0x80) PSet(x + b * 8 + d,y + a,30);
						else PSet(x + b * 8 + d,y + a,1);
					}
					else
					{
						if (c & 0x80) PSet(x + b * 8 + d,y + a,1);
						else PSet(x + b * 8 + d,y + a,30);
					}
					c <<= 1;
				}
			}
		}
	}
}

/*
*********************************************************************************************************
*                                           模拟LCD上指定位置显示一行汉字
*********************************************************************************************************
*/

void DispChineseLine(INT16U x,INT16U y,char *Str,INT8U att)
{
	if (x > 320) x = (128 - strlen(Str) * 8) >> 1;
	while (*Str)
	{
		DispChinese(x,y,Str,att);
		Str += 2;
		x += 16;
	}
}
/*
*********************************************************************************************************
*                                           模拟显示数码管数字
*********************************************************************************************************
*/

void DispLED(INT16U x,INT16U y,INT8U led)
{
	INT16U a,b;
    INT8U *P = LED[led];
	INT8U c,d;
	for (a = 0;a < 29;a++)
	{
		for (b = 0;b < 2;b++)
		{
            c = *P++;
			for (d = 0;d < 8;d++)
			{
				if (c & 0x80) PSet(x + b * 8 + d,y + a,30);
				else PSet(x + b * 8 + d,y + a,1);
				c <<= 1;
			}
		}
	}
}

/*
*********************************************************************************************************
*                                           更新显示时间
*********************************************************************************************************
*/
void Update(INT8U att)
{
	static struct TIME oldtime;
	if (att || oldtime.Month != Time.Month)
	{
		oldtime.Month = Time.Month;
		DispLED(0,35,Time.Month / 10);
		DispLED(20,35,Time.Month % 10);
	}
	if (att || oldtime.Day != Time.Day)
	{
		oldtime.Day = Time.Day;
		DispLED(46,35,Time.Day / 10);
		DispLED(66,35,Time.Day % 10);
	}
	if (att || oldtime.Week != Time.Week)
	{
		oldtime.Week = Time.Week;
		if (Time.Week)
			DispLED(112,35,Time.Week);
		else
			DispLED(112,35,8);
	}
	if (att || oldtime.Hour != Time.Hour)
	{
		oldtime.Hour = Time.Hour;
		DispLED(0,0,Time.Hour / 10);
		DispLED(20,0,Time.Hour % 10);
	}
	if (att || oldtime.Minute != Time.Minute)
	{
		oldtime.Minute = Time.Minute;
		DispLED(46,0,Time.Minute / 10);
		DispLED(66,0,Time.Minute % 10);
	}
	if (att || oldtime.Second != Time.Second)
	{
		oldtime.Second = Time.Second;
		DispLED(92,0,Time.Second / 10);
		DispLED(112,0,Time.Second % 10);
	}
}

/*
*********************************************************************************************************
*                                  恢复屏幕
*********************************************************************************************************
*/

void ResumeLCD()
{
	INT16U x,y;
	INT8U c,d;
	for (y = 0;y < 64;y++)
	{
		for (x = 0;x < 16;x++)
		{
			c = Image1[y * 16 + x];
			for (d = 0;d < 8;d++)
			{
				if (c & 0x80) PSet(x * 8 + d,y,30);
				else PSet(x * 8 + d,y,1);
				c <<= 1;
			}
		}
	}
	DispChineseLine(0,96,"按回车键进菜单!!",0);
	DispChineseLine(0,112,"         ",0);
	DispChineseLine(0,128,"         ",0);
}

/*
*********************************************************************************************************
*                                            显示数字
*********************************************************************************************************
*/
void DispNum(INT16U x,INT16U y,INT8U data,INT8U att)
{
	switch (data)
    {
	case 0:
		DispChinese(x,y,"0",att);
		break;
	case 1:
		DispChinese(x,y,"1",att);
		break;
	case 2:
		DispChinese(x,y,"2",att);
		break;
	case 3:
		DispChinese(x,y,"3",att);
		break;
	case 4:
		DispChinese(x,y,"4",att);
		break;
	case 5:
		DispChinese(x,y,"5",att);
		break;
	case 6:
		DispChinese(x,y,"6",att);
		break;
	case 7:
		DispChinese(x,y,"7",att);
		break;
	case 8:
		DispChinese(x,y,"8",att);
		break;
	case 9:
		DispChinese(x,y,"9",att);
		break;
    }
}

/*
*********************************************************************************************************
*                                            显示数值
*********************************************************************************************************
*/
void DispData(INT16U x,INT16U y,INT16U data,INT8U att)
{
	INT8U a,b,c;
	a = att & 0x07;
    b = (att & 0x80);
    if (!b)
		c = (att >> 3) & 0x07;
    else
		c = 100;
	if (a == 4)
    {
        DispNum(x,y,data / 1000,b || (c == 4));
        data %= 1000;
        x += 16;
	}
	if (a >= 3)
    {
        DispNum(x,y,data / 100,b || (c == 3));
        data %= 100;
        x += 16;
	}
	if (a >= 2)
    {
        DispNum(x,y,data / 10,b || (c == 2));
        data %= 10;
        x += 16;
	}
	DispNum(x,y,data,b || (c == 1));
}

/*
*********************************************************************************************************
*                                            编辑数据
*********************************************************************************************************
*/
INT8U EditData(INT16U x,INT16U y,INT16U *data,INT8U att,INT16S min,INT16S max)
{
	INT8U a,b;
	INT8S buff[4];
	INT16U temp;
	INT8U err;
	INT16S *key;
	temp = *data;
	for (a = 0;a < 4;a++)
	{
		buff[a] = temp % 10;
		temp /= 10;
	}
	a = att & 0x07;
	b = (att >> 3) & 0x07;
	while (1)
	{
		DispData(x,y,*data,a | (b << 3));
		key = OSQPend(TimeKey,0,&err);
		if (*key == 0x104B)			/*如果是左移*/
		{
			if (++b > a)
            {
				if (*data >= min && *data <= max)
					return 2;
                else
					b = 1;
            }
		}
		else if (*key == 0x104D)		/*如果是右移*/
		{
			if (--b < 1)
            {
				if (*data >= min && *data <= max)
					return 3;
                else
					b = a;
            }
		}
		else if (*key == 0x1048)		/*如果是“上”*/
		{
			if (++buff[b - 1] > 9)
				buff[b - 1] = 0;
		}
		else if (*key == 0x1050)    /*如果是“下”*/
		{
			if (--buff[b - 1] < 0)
				buff[b - 1] = 9;
		}
		else if (*key == 0x1044)		/*如果是F10*/
			return 1;
		else if (*key == 0x0D)			/*如果是回车*/
        {
           	if (*data >= min && *data <= max)
				return 0;
        }
		*data = buff[3] * 1000 + buff[2] * 100 + buff[1] * 10 + buff[0];
	}
}

/*
*********************************************************************************************************
*                                            计算某年月日是星期几
*********************************************************************************************************
*/
INT8U GetWeek(INT16U year,INT8U month,INT16U day)
{
	INT8U dat[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
	INT8U y;
	if (month > 1)
		for (y = 1;y < month;y++) day += dat[y - 1];
		if (((!(year % 4) && (year % 100)) || !(year % 400)) && month > 2) day++;
		return (year + (year - 1) / 4 - (year - 1) / 100 + (year - 1) / 400 - 1 + day) % 7;
}

/*
*********************************************************************************************************
*                                                MAIN
*********************************************************************************************************
*/

void  main (void)
{
	struct time ti;
	struct date da;

⌨️ 快捷键说明

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