導航:首頁 > 編程語言 > 數字時鍾程序c語言

數字時鍾程序c語言

發布時間:2025-01-03 00:38:45

㈠ 用C語言編一個數字電子時鍾的程序

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 procre 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 (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();
(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;
}

㈡ 急求一個用51單片機編的可按鍵調時的數字時鍾程序,數碼管顯示,C語言編寫,謝謝。

#include <reg51.h>
#include <intrins.h>
unsigned char code dis_week[]={"SUN,MON,TUE,WED,THU,FRI,SAT"};
unsigned char code para_month[13]={0,0,3,3,6,1,4,6,2,5,0,3,5};//星期月參變數
unsigned char data dis_buf1[16];//lcd上排顯示緩沖區
unsigned char data dis_buf2[16];//lcd下排顯示緩沖區
unsigned char data year,month,date,week;//年、月、日、星期
unsigned char data armhour,armmin,armsec;//鬧鍾時、分、秒
unsigned char data hour,min,sec,sec100;//時、分、秒、百分之一秒
unsigned char data flag,vkey,skey;//設置狀態計數標志、按鍵先前值、按鍵當前值
bitalarm;//標識是否啟用鬧鍾,1--啟用,0--關閉
sbit rs = P2^0;//LCD數據/命令選擇端(H/L)
sbit rw = P2^1;//LCD讀/寫選擇端(H/L)
sbit ep = P2^2;//LCD使能控制
sbitPRE = P3^3;//調整鍵(AN3)
sbitSET = P3^4;//調整鍵(AN4)
sbitSPK = P3^6;
void delayms(unsigned char ms);//延時程序
bit lcd_busy();//測試LCD忙碌狀態程序
void lcd_wcmd(char cmd);//寫入指令到LCD程序
void lcd_wdat(char dat);//寫入數據到LCD程序
void lcd_pos(char pos);//LCD數據指針位置程序
void lcd_init();//LCD初始化設定程序
void pro_timedate();//時間日期處理程序
void pro_display();//顯示處理程序
void pro_key();//按鍵處理程序
void time_alarm();//定時報警功能(鬧鍾)
unsigned char scan_key();//按鍵掃描程序
unsigned char week_proc();//星期自動計算與顯示函數
bit leap_year();//判斷是否為閏年
void lcd_sef_chr();//LCD自定義字元程序
void update_disbuf(unsigned char t1,unsigned char t2[],unsigned char dis_h,unsigned char dis_m,unsigned char dis_s);
//更新顯示緩沖區函數

// 延時程序
void delay(unsigned char ms)
{while(ms--)
{unsigned char i;
for(i = 0; i< 250; i++)
{
_nop_(); //執行一條_nop_()指令為一個機器周期
_nop_();
_nop_();
_nop_();
}
}
}
//測試LCD忙碌狀態
bit lcd_busy()
{
bit result;
rs = 0;
rw = 1;
ep = 1;
_nop_();
_nop_();
_nop_();
_nop_();
result =(bit)(P0&0x80);//LCD的D0--D7中,D7=1為忙碌,D7=0為空閑
ep = 0;
return result;
}
//寫入指令到LCD
void lcd_wcmd(char cmd)
{
while(lcd_busy());//當lcd_busy為1時,再次檢測LCD忙碌狀態,lcd-busy為0時,開始寫指令
rs = 0;
rw = 0;
ep = 0;
_nop_();
_nop_();
P0 = cmd;
_nop_();
_nop_();
_nop_();
_nop_();
ep = 1;
_nop_();
_nop_();
_nop_();
_nop_();
ep = 0;
}
//寫入數據到LCD
void lcd_wdat(char dat)
{
while(lcd_busy());//當lcd_busy為1時,再次檢測LCD忙碌狀態,lcd-busy為0時,開始寫數據
rs = 1;
rw = 0;
ep = 0;
P0 = dat;
_nop_();
_nop_();
_nop_();
_nop_();
ep = 1;
_nop_();
_nop_();
_nop_();
_nop_();
ep = 0;
}
//LCD數據指針位置程序
void lcd_pos(char pos)
{
lcd_wcmd(pos|0x80);//數據指針=80+地址碼(00H~27H,40H~67H)
}
//設定二個自定義字元,(注意:LCD1602中自定義字元的地址為0x00--0x07,即可定義8個字元)
//這里我們設定把一個自定義字元放在0x00位置(000),另一個放在0x01位子(001)
void lcd_sef_chr()
{//第一個自定義字元
lcd_wcmd(0x40);//"01 000 000" 第1行地址 (D7D6為地址設定命令形式D5D4D3為字元存放位置(0--7),D2D1D0為字元行地址(0--7))
lcd_wdat(0x1f);//"XXX 11111"第1行數據(D7D6D5為XXX,表示為任意數(一般用000),D4D3D2D1D0為字元行數據(1-點亮,0-熄滅)
lcd_wcmd(0x41);//"01 000 001" 第2行地址
lcd_wdat(0x11);//"XXX 10001"第2行數據
lcd_wcmd(0x42);//"01 000 010" 第3行地址
lcd_wdat(0x15);//"XXX 10101"第3行數據
lcd_wcmd(0x43);//"01 000 011" 第4行地址
lcd_wdat(0x11);//"XXX 10001"第4行數據
lcd_wcmd(0x44);//"01 000 100" 第5行地址
lcd_wdat(0x1f);//"XXX 11111"第5行數據
lcd_wcmd(0x45);//"01 000 101" 第6行地址
lcd_wdat(0x0a);//"XXX 01010"第6行數據
lcd_wcmd(0x46);//"01 000 110" 第7行地址
lcd_wdat(0x1f);//"XXX 11111"第7行數據
lcd_wcmd(0x47);//"01 000 111" 第8行地址
lcd_wdat(0x00);//"XXX 00000"第8行數據
//第二個自定義字元
lcd_wcmd(0x48);//"01 001 000" 第1行地址
lcd_wdat(0x01);//"XXX 00001"第1行數據
lcd_wcmd(0x49);//"01 001 001" 第2行地址
lcd_wdat(0x1b);//"XXX 11011"第2行數據
lcd_wcmd(0x4a);//"01 001 010" 第3行地址
lcd_wdat(0x1d);//"XXX 11101"第3行數據
lcd_wcmd(0x4b);//"01 001 011" 第4行地址
lcd_wdat(0x19);//"XXX 11001"第4行數據
lcd_wcmd(0x4c);//"01 001 100" 第5行地址
lcd_wdat(0x1d);//"XXX 11101"第5行數據
lcd_wcmd(0x4d);//"01 001 101" 第6行地址
lcd_wdat(0x1b);//"XXX 11011"第6行數據
lcd_wcmd(0x4e);//"01 001 110" 第7行地址
lcd_wdat(0x01);//"XXX 00001"第7行數據
lcd_wcmd(0x4f);//"01 001 111" 第8行地址
lcd_wdat(0x00);//"XXX 00000"第8行數據

}
//LCD初始化設定
void lcd_init()
{
lcd_wcmd(0x38);//設置LCD為16X2顯示,5X7點陣,八位數據借口
delay(1);
lcd_wcmd(0x0c);//LCD開顯示及游標設置(游標不閃爍,不顯示"-")
delay(1);
lcd_wcmd(0x06);//LCD顯示游標移動設置(游標地址指針加1,整屏顯示不移動)
delay(1);
lcd_wcmd(0x01);//清除LCD的顯示內容
delay(1);
}
//閏年的計算
bit leap_year()
{
bit leap;
if((year%4==0&&year%100!=0)||year%400==0)//閏年的條件
leap=1;
else
leap=0;
return leap;
}
//星期的自動運算和處理
unsigned char week_proc()
{unsigned char num_leap;
unsigned char c;
num_leap=year/4-year/100+year/400;//自00年起到year所經歷的閏年數
if( leap_year()&& month<=2 ) //既是閏年且是1月和2月
c=5;
else
c=6;
week=(year+para_month[month]+date+num_leap+c)%7;//計算對應的星期
return week;
}
//更新顯示緩沖區
void update_disbuf(unsigned char t1,unsigned char t2[],unsigned char dis_h,unsigned char dis_m,unsigned char dis_s)
{dis_buf1[0]=t1; //
dis_buf1[1]=0x20; //空格
dis_buf1[2]=50; //'2'
dis_buf1[3]=48; //'0'
dis_buf1[4]=year/10+48;
dis_buf1[5]=year%10+48;
dis_buf1[6]=0x2d;
dis_buf1[7]=month/10+48;
dis_buf1[8]=month%10+48;
dis_buf1[9]=0x2d; //'-'
dis_buf1[10]=date/10+48;
dis_buf1[11]=date%10+48;
dis_buf1[12]=0x20;
dis_buf1[13]=dis_week[4*week];
dis_buf1[14]=dis_week[4*week+1];
dis_buf1[15]=dis_week[4*week+2];
dis_buf2[0]=t2[0];
dis_buf2[1]=t2[1];
dis_buf2[2]=t2[2];
dis_buf2[3]=t2[3];
dis_buf2[4]=t2[4];
dis_buf2[5]=t2[5];
dis_buf2[6]=t2[6];//空格
if (alarm)
dis_buf2[7]=0x01;//alarm=1,顯示鬧鍾啟用標致(第二個自定義字元)
else
dis_buf2[7]=0x20;//alarm=0,不顯示鬧鍾啟用標致
dis_buf2[8]=dis_h/10+48;
dis_buf2[9]=dis_h%10+48;
dis_buf2[10]=0x3a;//':'
dis_buf2[11]=dis_m/10+48;
dis_buf2[12]=dis_m%10+48;
dis_buf2[13]=0x3a;
dis_buf2[14]=dis_s/10+48;
dis_buf2[15]=dis_s%10+48;
}
//時間和日期處理程序
void pro_timedate()
{
sec++;
if(sec > 59)
{sec = 0;
min++;
if(min>59)
{min=0;
hour++;
if(hour>23)
{hour=0;
date++;
if (month==1||month==3||month==5||month==7||month==8||month==10||month==12)
if (date>31) {date=1;month++;}//大月31天
if (month==4||month==6||month==9||month==11)
if (date>30) {date=1;month++;}//小月30天
if (month==2)
{if( leap_year())//閏年的條件
{if (date>29) {date=1;month++;}}//閏年2月為29天
else
{if (date>28) {date=1;month++;}}//平年2月為28天
}
if (month>12) {month=1;year++;}
if (year>99) year=0;
}
}
}
week_proc();
if (sec==armsec && min==armmin && hour==armhour)
{if (alarm)
TR1=1;//鬧鍾啟用時,報警時間到,啟動Timer1
}
}
//顯示處理程序
void pro_display()
{unsigned char i;
lcd_pos(0x00);
for (i=0;i<=15;i++)
{lcd_wdat(dis_buf1[i]);}
lcd_pos(0x40);
for (i=0;i<=15;i++)
{lcd_wdat(dis_buf2[i]);}
}
//Timer0中斷處理程序,秒的產生
void timer0() interrupt 1
{
TH0=0xD8;
TL0=0xF0;
sec100++;
if(sec100 >= 100)//1秒時間 (100*10ms=1000ms=1s)
{sec100 = 0;
pro_timedate();//調用時間和日期處理程序
}
if (sec&0x01)//"RICHMCU"閃一秒,停一秒
update_disbuf(0x00," ",hour,min,sec); //0x00表示顯示00位置的自定義字元
else
update_disbuf(0x00,"RICHMCU",hour,min,sec);
pro_display(); //調用顯示處理函數
}
//按鍵掃描程序
unsigned char scan_key()
{
skey=0x00;//給變數vkey置初值
skey|=PRE;//讀取PRE鍵的狀態
skey=skey<<1;//將PRE鍵的狀態存於skey的B1位
skey|=SET;//讀取SET鍵的狀態,並存於skey的B0位
return skey;//返回skey的鍵值(即PRE,SET的狀態)
}
//外部中斷INT0中斷處理程序
void int0() interrupt 0
{
TR0=0;//禁止Timer0
IE=0;//禁止中斷
lcd_wcmd(0x0e);//顯示游標"_",整個游標不閃爍
alarm=1;
update_disbuf(0x50,"alarm:",armhour,armmin,armsec);//更新顯示數據,0x50表示要顯示"P"
pro_display();//調用顯示處理程序
lcd_pos(0x47); //使游標位於第一個調整項下
flag=0;
vkey=0x03;
while(flag^0x0a)
{skey = scan_key();//掃描按鍵狀態
if (skey^vkey)//若skey與vkey相同,跳出循環,相異執行循環體
{delay(10);//去按鍵抖動
skey = scan_key();//轉回掃描按鍵狀態
if (skey^vkey)//若skey與vkey相同,跳出循環,相異執行循環體
{vkey=skey;//將skey的值付給vkey
if (skey==0x01)//PRE鍵按下
{ flag++;//調整標志位加1
switch (flag)//將游標置於相應調整位置
{

case 1: lcd_pos(0x49);break;//游標置小時報警設置位置
case 2:lcd_pos(0x4c);break;//游標置分鍾報警設置位置
case 3:lcd_pos(0x4f);break;//游標置秒時報警設置位置
case 4:update_disbuf(0x50,"time: ",hour,min,sec);
pro_display();
lcd_pos(0x05);break;//游標置年調整位置
case 5:lcd_pos(0x08);break;//游標置月調整位置
case 6:lcd_pos(0x0b);break;//游標置日調整位置
case 7: lcd_pos(0x49);break;//游標置時調整位置
case 8:lcd_pos(0x4c);break;//游標置分調整位置
case 9:lcd_pos(0x4f);break;//游標置秒調整位置
default:break;
}
}
if (skey==0x02) //SET鍵按下
{pro_key();//轉設置按鍵處理程序
}
}
}
}
lcd_wcmd(0x0c);//設置LCD開顯示及游標不閃爍,不顯示"-"
lcd_wcmd(0x01); //清除LCD的顯示內容
IE=0x8f; //CPU開中斷,INT0,INT1,開中斷
TR0=1;//Timer0啟動
}
//主程序,初始化及初值設定
void main()
{
lcd_init(); //初始化LCD
lcd_sef_chr();//寫入自定義字元號
hour=0;min=0;sec=0; //開機時的時,分,秒顯示
armhour=0;armmin=0;armsec=0;//開機時的時,分,秒報警初值
year= 5; month=1;date=1; //開機時的年,月,日,星期顯示
week_proc();
alarm=1;//初始開機,啟用鬧鍾
IE = 0x8f;//CPU開中斷,INT0,INT1,Timer0,Timer1開中斷
IP = 0x04;//設置INT0為中斷最高優先順序
IT0=0;IT1=0;//外部INT0,INT1設置為電平觸發方式(注意,觸發不要選邊沿方式,易誤動)
TMOD = 0x11;//Timer0,Timer1工作於模式1, 16位定時方式
TH0 = 0xdc;TL0 = 0x00;//Timer0置10ms定時初值
TH1 = 0xff;TL1 = 0x00;//Timer1置初值
TR0 = 1;//Timer0啟動
TR1 = 0;
while(1);
}
//設置按鍵處理程序
void pro_key()
{
switch (flag)
{
case 0:alarm=!alarm;//啟用或關閉鬧鍾(alarm=1:啟用,alarm=0:關閉)
update_disbuf(0x50,"alarm:",armhour,armmin,armsec); //更新顯示數據
pro_display();//調用顯示處理
lcd_pos(0x47);break;//游標回到原調整位置
case 1:armhour++;
if (armhour>23) armhour=0;
update_disbuf(0x50,"alarm:",armhour,armmin,armsec); //更新顯示數據
pro_display();//調用顯示處理
lcd_pos(0x49);break;//游標回到原調整位置
case 2:armmin++;
if (armmin>59) armmin=0;
update_disbuf(0x50,"alarm:",armhour,armmin,armsec);
pro_display();
lcd_pos(0x4c);break;
case 3:armsec++;
if (armsec>59) armsec=0;
update_disbuf(0x50,"alarm:",armhour,armmin,armsec);
pro_display();
lcd_pos(0x4f);break;
case 4:year++;
if(year> 99) year= 0;
week_proc(); //星期自動運算
update_disbuf(0x50,"time: ",hour,min,sec);
pro_display();
lcd_pos(0x05);break;
case 5:month++;
if (month>12) month=1;
week_proc();//星期自動運算
update_disbuf(0x50,"time: ",hour,min,sec);
pro_display();
lcd_pos(0x08);break;
case 6:date++;
if (month==1||month==3||month==5||month==7||month==8||month==10||month==12)
if (date>31) date=1;//大月31天
if (month==4||month==6||month==9||month==11)
if (date>30) date=1;//小月30天
if (month==2)
{if(leap_year())//閏年的條件
{if (date>29) date=1;}//閏年2月為29天
else
{if (date>28) date=1;}}//平年2月為28天
week_proc(); //星期自動運算
update_disbuf(0x50,"time: ",hour,min,sec);
pro_display();
lcd_pos(0x0b);break;
case 7:hour++;
if (hour>23) hour=0;
update_disbuf(0x50,"time: ",hour,min,sec);
pro_display();
lcd_pos(0x49);break;
case 8:min++;
if (min>59) min=0;
update_disbuf(0x50,"time: ",hour,min,sec);
pro_display();
lcd_pos(0x4c);break;
case 9:sec++;
if (sec>59) sec=0;
update_disbuf(0x50,"time: ",hour,min,sec);
pro_display();
lcd_pos(0x4f);break;
default: break ;
}
}
//Timer1中斷處理程序,產生報警的聲音
void timer1() interrupt 3
{
TH1=0xff;
TL1=0x00;
SPK=~SPK;

}
//外部中斷INT1中斷處理程序,停止報警聲音
void int1() interrupt 2
{
if(TR1)
TR1=0;
}

實驗說明:
按K1按鍵進入設定狀態
按K2,依次進入鬧鍾功能是否啟用,鬧鍾時,分秒,年,月,日及時間時,分,秒的設置,直到退出設置狀態
按K3,調整是否起用鬧鍾和調節鬧鍾時,分,秒,年,月,日,時間的時,分,秒的數字
LCD第二排中間顯示小喇叭,表示啟用鬧鍾功能,無則禁止鬧鍾功能(可在調整狀態進行設置)
正常狀態,LCD上排最前面顯示自定義字元,LCD下排最前面閃動"RICHMCU"
設置狀態,LCD上排最前面顯示"P",下排最前面在設置鬧鍾時間時顯示"alarm:",其它狀態顯示"time"
年代變化2000--2099,星期自動轉換

望採納,謝謝~~

㈢ 用c語言模擬一個數字時鍾,要求延時一秒運行

1、用sleep延時刷新並獲取系統時間來顯示。

2、常式:

#include<graphics.h>
#include<math.h>
#include<dos.h>
#definePI3.1415926
//屏幕中心的坐標(640X480模式下)
#definemid_x320
#definemid_y240
intmain()
{intgraphdriver=DETECT,graphmode;
intend_x,end_y;
structtimecurtime;
floatth_hour,th_min,th_sec;
initgraph(&graphdriver,&graphmode,"C:\TC2");//初始化VGA屏幕模式
setbkcolor(BLACK);//使用黑色的背景色
while(!kbhit(0))//若有鍵盤輸入,則跳出,即是結束程序
{setcolor(GREEN);//把畫筆設為綠色
circle(mid_x,mid_y,180);//鍾的外圓
circle(mid_x,mid_y,150);//鍾的內圓
circle(mid_x,mid_y,1);//畫出鍾的圓心
gettime(&curtime);//取得系統當前時間
th_sec=(float)curtime.ti_sec*0.1047197551;//把秒針的角度化為弧度,為以後繪制時方便,下同
th_min=(float)curtime.ti_min*0.1047197551+th_sec/60.0;//分針的弧度
th_hour=(float)curtime.ti_hour*0.5235987755+th_min/12.0;//時度的弧度,注意整時是12等分的,所時乘的是3.14/180*5
//計算出時針的尾的坐標(時針長70)
end_x=mid_x+70*sin(th_hour);
end_y=mid_y-70*cos(th_hour);
setcolor(RED);
line(mid_x,mid_y,end_x,end_y);//用紅色線畫出時針
//計算出分針坐標(分針長110)
end_x=mid_x+110*sin(th_min);
end_y=mid_y-110*cos(th_min);
setcolor(RED);
line(mid_x,mid_y,end_x,end_y);//用紅色畫出分針
end_x=mid_x+140*sin(th_sec);
end_y=mid_y-140*cos(th_sec);
setcolor(RED);
line(mid_x,mid_y,end_x,end_y);//同上,畫出秒針,長為140
//畫出鍾盤上的刻度,刻度長20
line(140,240,160,240);//9點對應的大刻度
line(320,60,320,80);//12點對應的大刻度
line(500,240,480,240);//3點的刻度
line(320,420,320,400);//6點的刻度
line(410,395.7,400,378.4);//5點
line(475.7,330,458.4,320);//4點
line(475.7,150,458.4,160);//2點
line(410,84.3,400,101.6);//1點
line(230,84.3,240,101.6);//11點
line(164.3,150,181.6,160);//10點
line(164.3,330,181.6,320);//8點
line(230,395.7,240,378.4);//7點
sleep(BLUE);//這里應該是打錯,停止一秒,應為sleep(1000)
cleardevice();//清除屏幕上的顯示
}
closegraph();//關閉VGA屏幕,即返迴文本方式
return0;
}
閱讀全文

與數字時鍾程序c語言相關的資料

熱點內容
小米手機CSV文件轉EXCEL 瀏覽:668
易方達app怎麼解綁銀行卡 瀏覽:931
維度app是哪個國家的 瀏覽:476
阿瓦隆之王快速升級 瀏覽:279
qq會員10元升級超級會員 瀏覽:808
taptap部分iOS聯網教程 瀏覽:563
北京電競數據分析哪個好 瀏覽:397
夢幻西遊手游版本大全 瀏覽:285
文件保險櫃什麼意思 瀏覽:956
javastring轉換成data 瀏覽:817
iphone5se是不是翻新機 瀏覽:367
如何製作磁碟啟動引導文件 瀏覽:979
lsx文件如何轉換成pdf文件 瀏覽:745
金蝶kis標准版升級 瀏覽:560
用拼音編程有什麼用 瀏覽:25
ps什麼文件都打不開嗎 瀏覽:74
微信別人發來的word文件怎麼編輯 瀏覽:628
個性化app有什麼好處 瀏覽:200
linux編譯so文件 瀏覽:911
赤潮數據哪裡找 瀏覽:988

友情鏈接