Implementation of perpetual calendar (including alarm clock and stopwatch) based on 51 single chip microcomputer

Publisher:qinghongLatest update time:2020-06-23 Source: eefocus Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

}

 

/*******************************************************************************

Function name: TimeToStr(SYSTEMTIME *Time)

Function: Convert the read time into characters that are easy to display

Input parameter: *Time structure to store characters

Return value: None 

*******************************************************************************/

void TimeToStr(SYSTEMTIME *Time)

{

Time->TimeString[0] = Time->Hour/10+0x30;

Time->TimeString[1] = Time->Hour%10+0x30;

Time->TimeString[2] = ':';

Time->TimeString[3] = Time->Minute/10+0x30;

Time->TimeString[4] = Time->Minute%10+0x30;

Time->TimeString[5] = ':';

Time->TimeString[6] = Time->Second/10+0x30;

Time->TimeString[7] = Time->Second%10+0x30 ; //When using LCD to display, it needs to be converted into ASCII code, so 0x30 is added. If it is displayed with a digital tube, it is not necessary to add

Time->DateString[8] = '';

}

 

/*******************************************************************************

Function name: Initial_DS1302(void)

Function: Initialize ds1302

Input parameters: None

Return value: None 

*******************************************************************************/

void Initial_DS1302(void)

{

unsigned char Second = Read1302(DS1302_SECOND);

if(Second&0x80)   

DS1302_SetTime(DS1302_SECOND,0);

}

   

/********************************************************************************

void BurstWrite1302(unsigned char *pWClock) //Write clock data to ds1302 (multi-byte mode)

{

    unsigned char i;

    Write1302(0x8e,0x00); // control command, WP=0, write operation

    DS1302_RST = 0;

    DS1302_CLK = 0;

    DS1302_RST = 1;

    DS1302InputByte(0xbe); // 0xbe: clock multi-byte write command

    for (i = 8; i>0; i--) //8Byte = 7Byte clock data + 1Byte control

    {

        DS1302InputByte(*pWClock); // Write 1Byte data

        pWClock++;

    }

    DS1302_CLK = 1;

    DS1302_RST = 0;

void BurstRead1302(unsigned char *pRClock) //Read ds1302 clock data (clock multi-byte mode)

{

    unsigned char i;

    DS1302_RST = 0;

    DS1302_CLK = 0;

    DS1302_RST = 1;

    DS1302InputByte(0xbf); // 0xbf: clock multi-byte read command 

    for (i=8; i>0; i--) 

    {

       *pRClock = DS1302OutputByte(); // Read 1 Byte data 

       pRClock++;

    }

    DS1302_CLK = 1;

    DS1302_RST = 0;

}

void DS1302_TimeStop(bit flag) // Whether to stop the clock

{

unsigned char Data;

Data = Read1302 (DS1302_SECOND);

DS1302_SetProtect(0);

if(flag)

Write1302(DS1302_SECOND, Data|0x80);

else

Write1302(DS1302_SECOND, Data&0x7F);

}

************************************************************************************/


 

#ifndef _DS1302_H #define _DS1302_H

 

#include #include "delay.h" #include

 

#ifndef uchar #define uchar unsigned char#endifsbit DS1302_CLK = P3^6; //Real-time clock clock line pin sbit DS1302_IO = P3^5; //Real-time clock data line pin sbit DS1302_RST = P3^4; //Real-time clock reset line pin//sbit DS1302_CLK = P3^6; //Real-time clock clock line pin//sbit DS1302_IO = P3^4; //Real-time clock data line pin//sbit DS1302_RST = P3^5; //Real-time clock reset line pin

 

sbit ACC0 = ACC^0;sbit ACC7 = ACC^7;

 

typedef struct __SYSTEMTIME__{ unsigned int Second; unsigned char Minute; unsigned char Hour; unsigned char Week; unsigned char Day; unsigned char Month; unsigned char Year; unsigned char DateString[9]; unsigned char TimeString[9];

 

}SYSTEMTIME; //Defined time type

 

#define AM(X) X#define PM(X) (X+12) //Convert to 24 hour system#define DS1302_SECOND 0x80#define DS1302_MINUTE 0x82#define DS1302_HOUR 0x84 #define DS1302_WEEK 0x8A#define DS1302_DAY 0x86#define DS1302_MONTH 0x88#define DS1302_YEAR 0x8C#define DS1302_RAM(X) (0xC0+(X)*2) //Macro for calculating ds1302 RAM address

 

void DS1302InputByte(unsigned char d);unsigned char DS1302OutputByte(void);void Write1302(unsigned char ucAddr, unsigned char ucDa);void DS1302_SetProtect(bit flag);unsigned char Read1302(unsigned char ucAddr);void DS1302_SetTime(unsigned char Address, unsigned char Value);void DS1302_GetTime(SYSTEMTIME *Time);void DateToStr(SYSTEMTIME *Time);void TimeToStr(SYSTEMTIME *Time);void Initial_DS1302(void);#end

 


   The main program modules are basically ready here. I will compress the complete program and upload it to the resource (I can't help but want to earn some points, understand). In fact, at this step, it should not be a problem for everyone to write the complete program.


   Let's talk about other things. When using the Keil software, it always reports this error *** ERROR L107: ADDRESS SPACE OVERFLOW. It took a lot of searching to find the problem. The variables we defined are defined in the RAM of 51, and there are only 256 or 128 bytes (depending on the model) for variable storage. I saw on the Internet that adding idata in front of the variable does not work. Try to save RAM as much as possible. Add code in front of the read-only array definition, and use as few global variables as possible. If it doesn't work, you can only change the microcontroller. After all, 51 is a microcontroller with very few resources and is not suitable for some large projects. Finally, add a rendering


 


Forget it, I'll just post all the programs here. I don't care about those points.


The following is the key processing program (this is the core program) and the main function. When I copied it from KEIL, I changed the Encode in ANSI in the edit configuration to Chinese GB2312. Otherwise, the Chinese characters will be garbled when copied. You should change it back when you copy it to your own project.


#include "keyProcess.h"

void array2show(ARRAY2SHOW *arrayshow0,uchar wch); //Function declaration//

void sec2show(SYSTEMTIME *secshow);

SYSTEMTIME showtime;  

extern SYSTEMTIME CurrentTime;

extern ARRAY2SHOW Alarmandshow;

/****************************************************************************************************

Function name: key_process(uchar mode)

Function: key processing function (adjust date, time, stopwatch, alarm clock)

Input parameter: mode is used to select the mode, whether to modify the date, time or alarm

Return value: None

************************************************************************************************************/

void key_process(uchar mode)

{

uchar Wch=0;

uchar flag=0;

uchar AlarmWch=0;

uchar HourSecWch=0;

uchar temp=0;

switch(mode) //Detect the key in the outermost loop to determine what to set

{

DS1302_GetTime(&CurrentTime);

case MODE0: //Set time

showtime=CurrentTime;

while(1)

{

DateToStr(&CurrentTime);

zifu_dis(1,0,&CurrentTime.DateString[0]); //Modifying the time does not affect the date displayed when reading from 1302

//(Troublesome idea) TArray3=show2array3(&CurrentTime.TimeString[0]); //Change the displayed character format to a format that can be directly added by 1

if(key_scan()==K1||key_scan()==K2||key_scan()==K3||key_scan()==K4)//Check if any key is pressed, and only perform the operation if a key is pressed

{

switch(key_scan()) //Detect the key again

{   

case K3: //Press K3 to select which digit of the time is changed

 

Wch++;

if(Wch==3)

Wch=0;

break;

case K1: //K1 is pressed, the number increases by one

   //(Troublesome thoughts) TArray3[TimeWch]++; //Convert to single character form for display 

if(Wch==0)

{

showtime.Hour++;

if(showtime.Hour==24)

showtime.Hour=0;

}

else if(Wch==1)

{

showtime.Minute++;

if(showtime.Minute==60)

showtime.Minute=0;

}

else if(Wch==2)

{

showtime.Second++;

if(showtime.Second==60)

showtime.Second=0;

}

TimeToStr(&showtime);

zifu_dis(0,0,&showtime.TimeString[0]); 

break;

case K2: //K2 is pressed, the number decreases by one

//(troublesome thoughts) TArray3[TimeWch]--;

//(troublesome thoughts)zifu_dis(1,0,array32show(TArray3)); 

if(Wch==0)

{

showtime.Hour--;

if(showtime.Hour==0xff)

showtime.Hour=0;

}

else if(Wch==1)

{

showtime.Minute--;

if(showtime.Minute==0xff)

showtime.Minute=0;

}

else if(Wch==2)

{

showtime.Second--;

if(showtime.Second==0xff)

showtime.Second=0;

}

TimeToStr(&showtime);

zifu_dis(0,0,&showtime.TimeString[0]); 

break;

case K4: //Press K4 to confirm the modification.

flag=1;break;

}

}

if(flag==1) //When flag is 1, confirm the modification, reset the time in 1302, and return to the initial mode detection

{

DS1302_SetTime(DS1302_HOUR,showtime.Hour);

DS1302_SetTime(DS1302_MINUTE,showtime.Minute);

DS1302_SetTime(DS1302_SECOND,showtime.Second);

Wch=0;

flag=0;

break;

}

}

break;

case MODE1: //Set date

showtime=CurrentTime;

while(1)

{

DS1302_GetTime(&CurrentTime);

TimeToStr(&CurrentTime);

zifu_dis(0,0,&CurrentTime.TimeString[0]); //Modify the date, does not affect the time displayed when reading from 1302

//(Troublesome Thoughts) DArray3=show2array3(&CurrentTime.DateString); //Change the displayed character format to a format that can be directly added by 1

if(key_scan()==K1||key_scan()==K2||key_scan()==K3||key_scan()==K4)//Check if any key is pressed, and only perform the operation if a key is pressed

{

switch(key_scan()) //Detect the key again

{

case K3: //K3 is pressed to select which digit of the date is changed

Wch++;

if(Wch==3)

Wch=0;

break;

case K1: //K1 is pressed, the number increases by one

    //(troublesome thought)DArray3[DateWch]=DArray3[DateWch]+1;

//(troublesome thoughts)zifu_dis(0,0,array32show(DArray3)); 

if(Wch==0)

showtime.Year++;

else if(Wch==1)

{

showtime.Month++;

if(showtime.Month==13)

showtime.Month=1;

}

else if(Wch==2)

[1] [2] [3] [4] [5]
Reference address:Implementation of perpetual calendar (including alarm clock and stopwatch) based on 51 single chip microcomputer

Previous article:51 MCU (Part 9). 51 MCU simple project - perpetual calendar and temperature acquisition
Next article:51 single chip perpetual calendar

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号