
#define uint unsigned int
#define uchar unsigned char
sbit QB1=P1^0
sbit QB2=P1^1 //数码管段选
sbit QB3=P1^2
sbit QB4=P1^3
sbit QB5=P1^4
sbit QB6=P1^5
sbit fm=P1^6//蜂鸣器
sbit s1=P2^4//s5按键,切换显示
sbit s2=P2^3//s2按键,设置调时
sbit s3=P2^2//s3按键,加1
sbit s4=P2^1//s4按键,减1
sbit led1=P0^0
sbit led2=P0^1
sbit led3=P0^2
uchar count
uchar sec,minu,hour,day,week,mon
uchar n_sec,n_minu,n_hour
uint year
uchar set_2=1,set_1=1
uchar hs,hg,mis,mig,ss,sg
uchar nhs,nhg,nms,nmg,nss=0,nsg=0
uchar ms,mg,ds,dg,w
uchar code table[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,
0X90,0X88,0X83,0XC6,0XA1,0X8E,0X86,0xbf}//0~F,-,共阳
//uchar code tableyi[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
//0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40}//0-F,-,共阴
uchar code table_d[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,
0x87,0xff,0xef}//0~9数组,带小数点
uchar table1[]={31,31,29,31,30,31,30,31,31,30,31,30,31}//闰年
uchar table2[]={31,31,28,31,30,31,30,31,31,30,31,30,31}//非闰年
void delay(uint)//延时函数
void timer0()//走时中断函数
void jishi()//计时函数
void key_change()//切换显示按键函数
void key_set()//设置时间按键函数
void disp(uchar,uchar,uchar,uchar,uchar,uchar)//显示函数
void zd_clock()//整点报时函数
void nz_clock()//闹钟函数
uchar incone(uchar)//加1函数
uchar decone(uchar)//减1函数
void set_time()//设置时间函数
void set_clock()//设置闹钟函数
void set_mdw()//设置月日星期函数
void main() //主函数
{
EA=1
ET0=1
TR0=1
TMOD=0x01
TH0=0x4c//50ms初值 晶振11.0592
TL0=0x00
hour=23minu=59sec=49//赋初值:11点59分0秒
n_hour=12n_minu=56n_sec=0//闹钟赋初值12点1分0秒
year=2008mon=5day=14week=3//年月日星期赋初值2008年5月11日星期天;祝天下所有母亲节日快乐
while(1)
{
hs=hour/10//时分秒HH.MM.SS
hg=hour%10
mis=minu/10
mig=minu%10
ss=sec/10
sg=sec%10
ms=mon/10//月日-星期MM.DD.-W
mg=mon%10
ds=day/10
dg=day%10
w=week
nhs=n_hour/10//闹钟定时HH.MM.SS
nhg=n_hour%10
nms=n_minu/10
nmg=n_minu%10
nss=n_sec/10
nsg=n_sec%10
key_change()//s4按键扫描
key_set()//s2按键扫描
set_time()//设置时间
set_mdw()//设置月日星期
set_clock()//设置闹钟
if(set_1==1) //正常走时显示
{
disp(hs,hg,mis,mig,ss,sg)
}
if(set_1==2) //设置时间,LED1闪亮
{
disp(hs,hg,mis,mig,ss,sg)
if(sec%2==0)
{led2=1led3=1led1=~led1}
// else
// {led1=1}
}
if(set_1==3) //正常显示月日-星期
{
disp(ms,mg,ds,dg,16,w)
}
if(set_1==4) //设置月日-星期,LED2闪亮
{
disp(ms,mg,ds,dg,16,w)
if(sec%2==0)
{led1=1led3=1led2=~led2}
// else
// {led2=1}
}
if(set_1==5) //正常显示定时
{
disp(nhs,nhg,nms,nmg,nss,nsg)
}
if(set_1==6) //设置闹钟定时,LED3闪亮
{
disp(nhs,nhg,nms,nmg,nss,nsg)
if(sec%2==0)
{led1=1led2=1led3=~led3}
// else
// {led3=1}
}
zd_clock()//整点报时
nz_clock()//闹钟
}
}
void timer0() interrupt 1 //50ms中断函数
{
TMOD=0x01
TH0=0x4c//50ms初值 晶振11.0592
TL0=0x00
count++
if(count==20)
{
count=0
sec++
jishi()//调计时函数
}
}
void jishi() //计时函数
{
if(sec==60)
{
sec=0
minu++
if(minu==60)
{
minu=0
hour++
if(hour==24)
{ hour=0
day++
week++
if(week==8)
{week=0}
if(year%4==0&&year%100!=0||year%400==0) //闰年
{
if(day==table1[mon]+1)
{
day=0
mon++
if(mon==13)
{mon=0year++}
}
}
else //非闰年
{
if(day==table2[mon]+1)
{
day=0
mon++
if(mon==13)
{mon=0year++}
}
}
}
}
}
}
void key_change() //s1按键扫描
{
if(s1==0)
{
delay(200)
if(s1==0)
{
set_1++
while(!s1)
if(set_1==7)
{set_1=1}
}
}
}
void key_set() //s2按键扫描
{
if(s2==0)
{
delay(10)
if(s2==0)
{
set_2++
while(!s2)
if(set_2==4)
{set_2=1}
}
}
}
void disp(uchar a1,uchar a2,uchar a3,uchar a4,uchar a5,uchar a6) //显示函数
{
QB1=1
QB2=0
QB3=0
QB4=0
QB5=0
QB6=0
P3=table[a1]//段码送P0口
delay(10)//延时一小会
QB1=0
QB2=1
QB3=0
QB4=0
QB5=0
QB6=0
P3=table[a2]//第2个数码管显示,带小数点
delay(10)
QB1=0
QB2=0
QB3=1
QB4=0
QB5=0
QB6=0
P3=table[a3]//第3个数码管显示
delay(10)
QB1=0
QB2=0
QB3=0
QB4=1
QB5=0
QB6=0
P3=table[a4]//第4个数码管显示,带小数点
delay(10)
QB1=0
QB2=0
QB3=0
QB4=0
QB5=1
QB6=0
//第5个数码管显示
P3=table[a5]
delay(10)
QB1=0
QB2=0
QB3=0
QB4=0
QB5=0
QB6=1
P3=table[a6]//第6个数码管显示
delay(10)
QB1=0
QB2=0
QB3=0
QB4=0
QB5=0
QB6=0
}
void zd_clock() //整点报时函数
{
if(minu==59&&(sec==53||sec==55||sec==57))
{
fm=0
delay(5)
fm=1
delay(5)
}
fm=0
if(minu==59&&sec==59)
{
fm=0
delay(5)
fm=1
delay(5)
fm=0
}
}
void nz_clock() //闹钟函数
{
if(hour==n_hour&&minu==n_minu&&sec==n_sec)
//if((sec%2==0)&&sec<30)
{
fm=0
delay(1)
fm=1
delay(1)
}
}
void set_time() //设置时间函数
{
if(set_1==2)
{
if(set_2==1)
{
hour=incone(hour)
if(hour==24)
{hour=0}
// if(hour<0)
// {hour=23}
hour=decone(hour)
}
if(set_2==2)
{
minu=incone(minu)
if(minu==60)
{minu=0}
// if(minu<0)
// {minu=59}
minu=decone(minu)
}
}
}
void set_mdw() //设置月日星期函数
{
if(set_1==4)
{
if(set_2==1)
{
mon=incone(mon)
if(mon==13)
{mon=1}
mon=decone(mon)
// if(mon==0)
// {mon=12}
}
if(set_2==2)
{
day=incone(day)
if(day==32)
{day=0}
day=decone(day)
// if(day==0)
// {day=0}
}
if(set_2==3)
{
week=incone(week)
if(week==8)
{week=0}
week=decone(week)
// if(week==0)
// {week=7}
}
}
}
void set_clock() //设置闹钟函数
{
if(set_1==6)
{
if(set_2==1)
{
n_hour=incone(n_hour)
if(n_hour==24)
{n_hour=0}
n_hour=decone(n_hour)
if(n_hour==0)
{n_hour=0}
}
if(set_2==2)
{
n_minu=incone(n_minu)
if(n_minu==60)
{n_minu=0}
n_minu=decone(n_minu)
if(n_minu==0)
{n_minu=0}
}
}
}
uchar incone(uchar n) //加1函数
{
if(s3==0)
{ delay(200)
if(s3==0)
{
n++
while(!s3)
}
}
return(n)
}
uchar decone(uchar m) //减1函数
{
if(s4==0)
{
delay(200)
if(s4==0)
{
m--
while(!s4)
if(m<0)
{m=0}
}
}
return(m)
}
void delay(uint k) //延时函数
{
uint i,j
for(i=ki>0i--)
for(j=80j>0j--)
}
1.这是用windows api写的程序。所以要求是纯c的话就没有办法了2.其中定时用了两种方法。一种是用取消息。另一种是延时队列。这里只使用了取消息的方法。延时队列由于我机器上是vc6.0,CreateTimerQueue在本人机器上无法使用,需要新的sdk,所以没有加以验证,但取消息的方式是可行的。
3.稍稍验证了下,基本满足要求。
-------------------------------------------
程序如下:
// DigitalClock.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <winbase.h>
typedef struct _st_time{
int hour
int min
int sec
}ST_TIME
ST_TIME g_Time // The struct contain the hour,min and sec.
HANDLE g_hStdout //
WORD g_cxCenter, g_cyCenter // Center of the screen.
HANDLE g_DoneEvent// The program could be over.
BOOL g_ThreadTerminated // The Thread should be terminated.
#define SECOND_CIRCLE 60
#define MINUTE_CIRCLE 60
#define HOUR_CIRCLE 24
void TimeIncreaseSecond(ST_TIME &st)
{
st.sec ++
if (st.sec >= SECOND_CIRCLE)
{
st.sec -= SECOND_CIRCLE
st.min++
if (st.min >= MINUTE_CIRCLE)
{
st.min -= MINUTE_CIRCLE
st.hour++
if (st.hour >= HOUR_CIRCLE)
{
st.hour -= HOUR_CIRCLE
}
}
}
}
void PrintTimeToScreen(HANDLE hStdout, short cxCenter, short cyCenter, ST_TIME st)
{
char buf[64] = {0}
COORD crdPos
// make it format to output.
sprintf (buf, "%02d:%02d:%02d", st.hour, st.min, st.sec)
crdPos.X = cxCenter - 4
crdPos.Y = cyCenter
SetConsoleCursorPosition(hStdout, crdPos)
printf(buf)
}
#ifdef USE_TIMERQUEUE
// if we use the timer queue function.
// Its procdure is in this.
void CALLBACK TimerRoutine (LPVOID lpParam, BOOL TimerOrWaitFired)
{
if (lpParam == NULL)
{
printf ("NULL parameters.\n")
}
else
{
ST_TIME *st = (ST_TIME *)lpParam
TimeIncreaseSecond(st)
PrintTimeToScreen(g_hStdout, g_cxCenter, g_cyCenter, *st)
}
}
#else
DWORD WINAPI TimerThreadProc(LPVOID lpParam)
{
#define ID_TIMER_SECOND 1
MSG msg
BOOL ret
ST_TIME *st = (ST_TIME *)lpParam
SetTimer(NULL, ID_TIMER_SECOND, 1000, NULL)
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE)
while (!g_ThreadTerminated &&(ret = GetMessage (&msg, NULL, 0, 0)) != 0)
{
if (ret == -1)
{
//process fatal event.
}
else if (msg.message == WM_TIMER)
{
TimeIncreaseSecond(*st)
PrintTimeToScreen(g_hStdout, g_cxCenter, g_cyCenter, *st)
}
else
{
TranslateMessage (&msg)
DispatchMessage (&msg)
}
}
return 1
}
#endif
// If the ctrl+break combined key pressed. call this function.
// It set the g_DoneEvent. this terminate the program.
BOOL WINAPI CtrlHandler(DWORD fdwCtrlType)
{
switch (fdwCtrlType)
{
case CTRL_BREAK_EVENT:
// Terminate the program.
printf ("Terminate.\n")
SetEvent(g_DoneEvent)
return TRUE
default:
return FALSE
}
}
BOOL InitApplication()
{
// Get the stdin and stdout handle.
HANDLE hStdIn
hStdIn = GetStdHandle(STD_INPUT_HANDLE)
if (hStdIn == INVALID_HANDLE_VALUE)
return FALSE
g_hStdout = GetStdHandle(STD_OUTPUT_HANDLE)
// Set the mode, make the input echo.
DWORD fOldMode
GetConsoleMode(hStdIn, &fOldMode)
fOldMode |= ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT
SetConsoleMode(hStdIn, fOldMode)
// Set the window buffer.
// make a line 40 columns.
CONSOLE_SCREEN_BUFFER_INFO csbiInfo
GetConsoleScreenBufferInfo(g_hStdout, &csbiInfo)
csbiInfo.srWindow.Right = 40
// get the center point.
g_cxCenter = csbiInfo.srWindow.Right / 2
g_cyCenter = csbiInfo.srWindow.Bottom / 2
// Set the window.
SetConsoleWindowInfo(g_hStdout, TRUE, &csbiInfo.srWindow)
return TRUE
}
BOOL PrintTheInitalStateAndGetInput(HANDLE hStdout, WORD cxCenter, WORD cyCenter, ST_TIME &time)
{
#define GAPS_LEFT_COLON (-2)
#define GAPS_RIGHT_COLON (1)
#define GAPS_LEFT_UNDERLINE_START (-4)
#define GAPS_MIDDLE_UNDERLINE_START (-1)
#define GAPS_RIGHT_UNDERLINE_START (2)
// __:__:__
// So the left ":" center -2
// so the right ":" center + 1
// so the left "_" center - 4
// so the lfet "_" center - 1
// so the right "_" center + 2
COORD crdPos
crdPos.X = cxCenter + GAPS_LEFT_COLON
crdPos.Y = cyCenter
SetConsoleCursorPosition(hStdout, crdPos)
printf (":")
crdPos.X = cxCenter + GAPS_RIGHT_COLON
SetConsoleCursorPosition(hStdout, crdPos)
printf (":")
crdPos.X = cxCenter + GAPS_LEFT_UNDERLINE_START
SetConsoleCursorPosition(hStdout, crdPos)
scanf ("%d", &time.hour)
crdPos.X = cxCenter + GAPS_MIDDLE_UNDERLINE_START
SetConsoleCursorPosition(hStdout, crdPos)
scanf ("%d", &time.min)
crdPos.X = cxCenter + GAPS_RIGHT_UNDERLINE_START
SetConsoleCursorPosition(hStdout, crdPos)
scanf ("%d", &time.sec)
if (time.hour <0 || time.hour >HOUR_CIRCLE ||
time.min <0 || time.min >MINUTE_CIRCLE ||
time.sec <0 || time.sec >SECOND_CIRCLE)
return FALSE
return TRUE
}
int main(int argc, char* argv[])
{
InitApplication()
PrintTheInitalStateAndGetInput(g_hStdout, g_cxCenter, g_cyCenter, g_Time)
// create a event to tell the program to terminate.
g_DoneEvent = CreateEvent(NULL, TRUE, FALSE, NULL)
#ifdef USE_TIMERQUEUE
HANDLE hTimerQueue, hTimer
hTimerQueue = CreateTimerQueue()
if (!CreateTimerQueueTimer(&hTimer,
hTimerQueue, TimerRoutine, &g_Time, 1000, 0, 0))
{
printf("CreateTimerQueueTimer failed (%d)\\n", GetLastError())
return 3
}
#else
// create the thread.
HANDLE hThreadTimer
DWORD dwThreadId
g_ThreadTerminated = FALSE
hThreadTimer = CreateThread(NULL, 0,
TimerThreadProc, &g_Time, 0, &dwThreadId)
if (hThreadTimer == NULL)
{
}
#endif
SetConsoleCtrlHandler(CtrlHandler, TRUE)
if (WaitForSingleObject(g_DoneEvent, INFINITE) != WAIT_OBJECT_0)
printf("WaitForSingleObject failed (%d)\\n", GetLastError())
#ifdef USE_TIMERQUEUE
if (!DeleteTimerQueue(hTimerQueue))
printf("DeleteTimerQueue failed(%d) \\n", GetLastError())
#else
g_ThreadTerminated = TRUE
if (WaitForSingleObject(hThreadTimer, INFINITE) != WAIT_OBJECT_0)
printf("WaitForSingleObject failed (%d)\\n", GetLastError())
#endif
return 0
}
--------------------------------------------
下面是纯c的。
有几个问题:
1.textmode函数在turboc中没有办法使用,不知道是什么问题,而borland c就可以。
2.无论怎么设置,自己的ctrlbreak函数在上述两个环境中都不能被调用,非常遗憾。所以不能够优雅的退出。只能按两次ctrlbreak。
下面是程序。
------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <dos.h>
#define ABORT 0
int jump_out_loop = -1
int jump_out(void)
{
jump_out_loop = 1
printf("Abort ..\n")
return ABORT
}
int main(void)
{
struct text_info ti
int center_x, center_y
int hour, min, sec
char str_out[64] = {0}
clrscr()
/*textmode(BW40)*/
/*textmode在turbo c下设置会出问题*/
gettextinfo(&ti)
center_x = ti.winright / 2
center_y = ti.winbottom / 2
gotoxy(center_x - 4, center_y)
cprintf(" : : ")
gotoxy(center_x - 4, center_y)
cscanf("%d", &hour)
gotoxy(center_x - 1, center_y)
cscanf("%d", &min)
gotoxy(center_x + 2, center_y)
cscanf("%d", &sec)
/* check input valid or not */
{}
setcbrk(1)
ctrlbrk(jump_out)
/*jump_out没有起到作用,实在不好意思.*/
/*
if (getcbrk())
printf("crtl break is on\n")
else
printf("is off\n")
*/
while (1)
{
delay(1000)
sec++
if (sec >= 60)
{
sec -= 60
min++
if (min >= 60)
{
min -= 60
hour++
if (hour >= 24)
{
hour -= 24
}
}
}
sprintf(str_out, "%02d:%02d:%02d", hour, min, sec)
gotoxy(center_x - 4, center_y)
cprintf(str_out)
}
/* getch()*/
return 0
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)