📄 clk_demo.c
字号:
/************************************************************************/
/* lck_demo.c
程序是利用C语言开发环境下的作图函数和时间读取和设置函数编写而成的,实现了
时间的时钟显示。
(Display the time with hands, the time also could be changed.)
Copyright (c) 2006 by Thinta Co.LTD
All rights reserved */
/************************************************************************/
#include "..\inc\Bio_Func.h"
#include "..\inc\key.h"
#include <STDIO.H>
#include <STRING.H>
#include <MATH.H>
#define PI 3.1415926
#define SCALENUM 60 //表盘被划分的精确度
#define INTERVAL (SCALENUM / 12) //每5分钟的表盘格数
#define HOURRADIUS 0.35 //小时指针的长度与表盘半径的比值
#define MINRADIUS 0.65 //分针长度与表盘半径的比值
#define CRDRADIUS 1 //刻度盘半径与表盘半径的比值
#define NORMALCOLOR 1
#define NONECOLOR 0
typedef struct Point
{
U8 pos_x;
U8 pos_y;
}Point;
void _PutString( U8 x,U8 y,U8 *str,U8 color )
{
_setdispcolor(color);
_gotoxy(x,y);
_putstr(str);
}
void Settime(void);
void Clk_help(void);
void drawclk(Point Center, U8 nRadius, U8 LenRect);
S16 drawclkAdvance(Point Center, U8 nRadius, U8 LenRect) ;
void main(void)
{
U8 nRadius, LenRect;
S16 Key_return;
Point Center ;
_sysinit();
Center.pos_x = 80 ;
Center.pos_y = 50 ;
nRadius = 30 ;
LenRect = 80 ;
while(1)
{
_cls();
_gotoxy(0, (U8)(((Center.pos_y + LenRect / 2)/16) +3));
_putstr(" ESC 键: 退出\n“1” 键: 设置时间 ");
Key_return = drawclkAdvance(Center, nRadius, LenRect);
if (Key_return == ESC)
break; //按ESC键退出
else if (Key_return == NUMBER_1) //若按“1”键则进入修改时间
Settime();
else if (Key_return == KEY_HELP) //按HELP键获得帮助
Clk_help();
}
}
void drawclk(Point Center, U8 nRadius, U8 LenRect)
{
U8 i ;
U8 nClk_time[9] = {0} ;
U8 nSeq_hour, nSeq_min; //时间的大小
U8 nRadius_hour, nRadius_min, nRadius_crd ; //指针的半径
float nPos_AngleX[SCALENUM] , nPos_AngleY[SCALENUM] ;
Point CenterPoint, LeftUp , RightBottom ; //时钟的外形尺寸
Point nPos_clk_min[SCALENUM], nPos_clk_hour[SCALENUM], nPos_clk_crd[SCALENUM] ;
//初始化外形尺寸及指针半径
CenterPoint = Center ;
LeftUp.pos_x = (U8)(Center.pos_x - LenRect / 2 + 0.5) ;
LeftUp.pos_y = (U8)(Center.pos_y - LenRect / 2 + 0.5) ;
RightBottom.pos_x = (U8)(Center.pos_x + LenRect / 2 + 0.5) ;
RightBottom.pos_y = (U8)(Center.pos_y + LenRect / 2 + 0.5) ;
nRadius_hour = (U8)(HOURRADIUS * nRadius) ;
nRadius_min = (U8)(MINRADIUS * nRadius) ;
nRadius_crd = (U8)(CRDRADIUS * nRadius) ;
//初始化表盘及指针位置,将360度分为SCALENUM等分,计算相应长度指针
//及表盘的准确位置,当画指针时,只需要在计算得到的数组中取相应的值
//即可,不必再计算
for (i = 0; i < SCALENUM; i++)
{
nPos_AngleX[i] = sin(2 * PI / SCALENUM * i) ;
nPos_AngleY[i] = -cos(2 * PI / SCALENUM * i) ;
nPos_clk_min[i].pos_x = (U8)(nPos_AngleX[i] * nRadius_min + CenterPoint.pos_x) ;
nPos_clk_min[i].pos_y = (U8)(nPos_AngleY[i] * nRadius_min + CenterPoint.pos_y) ; //分针位置
nPos_clk_hour[i].pos_x = (U8)(nPos_AngleX[i] * nRadius_hour + CenterPoint.pos_x) ;
nPos_clk_hour[i].pos_y = (U8)(nPos_AngleY[i] * nRadius_hour + CenterPoint.pos_y) ; //时针位置
nPos_clk_crd[i].pos_x = (U8)(nPos_AngleX[i] * nRadius_crd + CenterPoint.pos_x) ;
nPos_clk_crd[i].pos_y = (U8)(nPos_AngleY[i] * nRadius_crd + CenterPoint.pos_y) ; //坐标位置
if (i % INTERVAL == 0)
_drawdot(nPos_clk_crd[i].pos_x, nPos_clk_crd[i].pos_y, NORMALCOLOR);
}
//初始化刻度线及边框,画外方形边框以及刻钟表盘位置
_drawrect(LeftUp.pos_x, LeftUp.pos_y, RightBottom.pos_x, RightBottom.pos_y, NORMALCOLOR);
_drawline(CenterPoint.pos_x, nPos_clk_crd[0].pos_y, CenterPoint.pos_x, nPos_clk_crd[0].pos_y + 4, NORMALCOLOR);
_drawline(nPos_clk_crd[15].pos_x, CenterPoint.pos_y, nPos_clk_crd[15].pos_x - 4, CenterPoint.pos_y, NORMALCOLOR);
_drawline(nPos_clk_crd[45].pos_x, CenterPoint.pos_y, nPos_clk_crd[45].pos_x + 4, CenterPoint.pos_y, NORMALCOLOR);
_drawline(CenterPoint.pos_x, nPos_clk_crd[30].pos_y, CenterPoint.pos_x, nPos_clk_crd[30].pos_y - 4, NORMALCOLOR);
while(1)
{
//清除上次指针
_drawline(CenterPoint.pos_x, CenterPoint.pos_y, nPos_clk_min[nSeq_min].pos_x, nPos_clk_min[nSeq_min].pos_y, NONECOLOR) ;
_drawline(CenterPoint.pos_x, CenterPoint.pos_y, nPos_clk_hour[nSeq_hour].pos_x, nPos_clk_hour[nSeq_hour].pos_y, NONECOLOR) ;
_gettime(nClk_time);
//计算分钟及时钟对应的指针位置数组中的序号
nSeq_min = (U8) (((nClk_time[3] - '0') * 10 + (nClk_time[4] - '0')) * 60 / SCALENUM) ;
nSeq_hour = (U8) (((nClk_time[0] - '0') * 10 + (nClk_time[1] - '0')) % 12 * INTERVAL + nSeq_min * INTERVAL / SCALENUM ) ;
//画出当前指针
_drawline(CenterPoint.pos_x, CenterPoint.pos_y, nPos_clk_min[nSeq_min].pos_x, nPos_clk_min[nSeq_min].pos_y, NORMALCOLOR) ;
_drawline(CenterPoint.pos_x, CenterPoint.pos_y, nPos_clk_hour[nSeq_hour].pos_x, nPos_clk_hour[nSeq_hour].pos_y, NORMALCOLOR) ;
_gotoxy(1, (U8)(RightBottom.pos_y / 16 + 1));
_putstr("当前时间: ");
_putstr(nClk_time);
if (_bioskey(1) != 0 )
{
if(_bioskey(0) == ESC)
break;
}
_delay(80);
}
}
/************************************************************************/
/* S16 drawclkAdvance(Point Center, U8 nRadius, U8 LenRect)
画指针模式时间函数
输入:时钟的中心点 Center; 时钟表盘半径:nRadius; 时钟外边框长度:LenRect
输出:时钟显示时的按键值
*/
/************************************************************************/
S16 drawclkAdvance(Point Center, U8 nRadius, U8 LenRect)
{
U8 i ;
U8 nClk_time[9] = {0} ;
U8 nSeq_hour, nSeq_min; //时间的大小
U8 nRadius_hour, nRadius_min, nRadius_crd ; //指针的半径
float nPos_AngleX[SCALENUM] , nPos_AngleY[SCALENUM] ;
Point CenterPoint, LeftUp , RightBottom ; //时钟的外形尺寸
Point nPos_clk_min[SCALENUM], nPos_clk_hour[SCALENUM], nPos_clk_crd[SCALENUM] ;
//初始化外形尺寸及指针半径
CenterPoint = Center ;
LeftUp.pos_x = (U8)(Center.pos_x - LenRect / 2 + 0.5) ;
LeftUp.pos_y = (U8)(Center.pos_y - LenRect / 2 + 0.5) ;
RightBottom.pos_x = (U8)(Center.pos_x + LenRect / 2 + 0.5) ;
RightBottom.pos_y = (U8)(Center.pos_y + LenRect / 2 + 0.5) ;
nRadius_hour = (U8)(HOURRADIUS * nRadius) ;
nRadius_min = (U8)(MINRADIUS * nRadius) ;
nRadius_crd = (U8)(CRDRADIUS * nRadius) ;
//初始化表盘及指针位置,将360度分为SCALENUM等分,计算相应长度指针
//及表盘的准确位置,当画指针时,只需要在计算得到的数组中取相应的值
//即可,不必再计算
for (i = 0; i < SCALENUM; i++)
{
nPos_AngleX[i] = sin(2 * PI / SCALENUM * i) ;
nPos_AngleY[i] = -cos(2 * PI / SCALENUM * i) ;
nPos_clk_min[i].pos_x = (U8)(nPos_AngleX[i] * nRadius_min + CenterPoint.pos_x) ;
nPos_clk_min[i].pos_y = (U8)(nPos_AngleY[i] * nRadius_min + CenterPoint.pos_y) ; //分针位置
nPos_clk_hour[i].pos_x = (U8)(nPos_AngleX[i] * nRadius_hour + CenterPoint.pos_x) ;
nPos_clk_hour[i].pos_y = (U8)(nPos_AngleY[i] * nRadius_hour + CenterPoint.pos_y) ; //时针位置
nPos_clk_crd[i].pos_x = (U8)(nPos_AngleX[i] * nRadius_crd + CenterPoint.pos_x) ;
nPos_clk_crd[i].pos_y = (U8)(nPos_AngleY[i] * nRadius_crd + CenterPoint.pos_y) ; //坐标位置
if (i % INTERVAL == 0)
_drawdot(nPos_clk_crd[i].pos_x, nPos_clk_crd[i].pos_y, NORMALCOLOR);
}
//初始化刻度线及边框,画外方形边框以及刻钟表盘位置
_drawrect(LeftUp.pos_x, LeftUp.pos_y, RightBottom.pos_x, RightBottom.pos_y, NORMALCOLOR);
_drawline(CenterPoint.pos_x, nPos_clk_crd[0].pos_y, CenterPoint.pos_x, nPos_clk_crd[0].pos_y + 4, NORMALCOLOR);
_drawline(nPos_clk_crd[15].pos_x, CenterPoint.pos_y, nPos_clk_crd[15].pos_x - 4, CenterPoint.pos_y, NORMALCOLOR);
_drawline(nPos_clk_crd[45].pos_x, CenterPoint.pos_y, nPos_clk_crd[45].pos_x + 4, CenterPoint.pos_y, NORMALCOLOR);
_drawline(CenterPoint.pos_x, nPos_clk_crd[30].pos_y, CenterPoint.pos_x, nPos_clk_crd[30].pos_y - 4, NORMALCOLOR);
while(1)
{
//清除上次指针
_drawline(CenterPoint.pos_x, CenterPoint.pos_y, nPos_clk_min[nSeq_min].pos_x, nPos_clk_min[nSeq_min].pos_y, NONECOLOR) ;
_drawline(CenterPoint.pos_x, CenterPoint.pos_y, nPos_clk_hour[nSeq_hour].pos_x, nPos_clk_hour[nSeq_hour].pos_y, NONECOLOR) ;
_gettime(nClk_time);
////计算分钟及时钟对应的指针位置数组中的序号
nSeq_min = (U8) ((nClk_time[3] - '0') * 10 + (nClk_time[4] - '0')) ;
nSeq_hour = (U8) (((nClk_time[0] - '0') * 10 + (nClk_time[1] - '0')) % 12 * INTERVAL + nSeq_min * INTERVAL / SCALENUM ) ;
//画出当前指针
_drawline(CenterPoint.pos_x, CenterPoint.pos_y, nPos_clk_min[nSeq_min].pos_x, nPos_clk_min[nSeq_min].pos_y, NORMALCOLOR) ;
_drawline(CenterPoint.pos_x, CenterPoint.pos_y, nPos_clk_hour[nSeq_hour].pos_x, nPos_clk_hour[nSeq_hour].pos_y, NORMALCOLOR) ;
_gotoxy(1, (U8)(RightBottom.pos_y / 16 + 1));
_putstr("当前时间: ");
_putstr(nClk_time);
if (_bioskey(1) != 0 )
break;
_delay(80);
}
return _bioskey(0) ;
}
/************************************************************************/
/* 依据输入键值进行时间设置,并判断设置是否成功 */
/************************************************************************/
void Settime(void)
{
U8 i = 0;
U8 nTime[9] = {0};
S16 Key_in;
_cls();
_PutString(0, 1, " 修改时间 ", NORMALCOLOR);
_PutString(0, 3, " 小时: 分: 秒 ", NORMALCOLOR);
_gotoxy(5, 4);
while(1)
{
//使用_gettime ()函数得到的时间字符串中,第3个与第5个字符是“:”
if (2 == i | 5 == i)
{
i++;
_putstr(":");
}
else if(i < 8)
{
Key_in = _bioskey(0);
if (Key_in == ESC || Key_in == ENTER)
break;
_putch((U8)Key_in);
nTime[i] = Key_in;
i++;
}
else
break;
}
if (_settime(nTime) == 0)
_PutString(0, 7, "时间设置成功!",NORMALCOLOR);
else
_PutString(0, 7, "时间设置失败!",NORMALCOLOR);
_bioskey(0);
}
/*帮助信息*/
void Clk_help(void)
{
_cls();
_PutString(0, 0, " -时钟操作帮助- ", NORMALCOLOR);
_PutString(2, 2, "修改时间请按“1”键, 退出时钟显示程序请按“ESC”键", NORMALCOLOR);
_bioskey(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -