Electronic clock program with adjustable time

Publisher:WhisperingGlowLatest update time:2021-05-25 Source: eefocus Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Introduction: Single-chip open source project of button adjustable electronic clock (matrix button + infrared remote control button for time adjustment)
This program is written based on the 51hei single-chip development board. If you need to transplant it to your own circuit, just modify the corresponding port.


/**

************************************************************************

* @file : main.c

* @author : xr

* @date : 2014-04-21 22:23:12 - 2014-04-26 21:22:29

* @version : V1.2.3

* @brief : Electronic clock with adjustable time by buttons (matrix buttons + infrared remote control buttons for time adjustment) MCU STC89C52RC MCU Crystal oscillator 11.0592MHZ

************************************************************************

*/


#include

#include "main.h"


/*Define a structure to encapsulate the time and date read from DS1302 and the time and date set to DS1302*/

struct Time {

unsigned char year; //DS1302 only stores the lower two bytes of the year

unsigned char month;

unsigned char day;

unsigned char hour;

unsigned char min;

unsigned char sec;

unsigned char week;

};


/*Define a structure time variable to save time and date*/

struct Time timeBuf; //Struct variables must be used here, and structure pointers cannot be used, otherwise the write will fail!


unsigned char setTimeIndex = 0; //Set the time status and set the cursor position and set the index value of the time position (0 is normal operation, 1-12 is the setting time status, 1-12 is the setting position)


bit flag200ms = 0;

unsigned char thr0, tlr0;


//Infrared communication decoding key code and standard PC code mapping table

unsigned char code IrdCodeMap[] = {0x45, 0x46, 0x47, //Switch, Mode, Mute

0x44, 0x40, 0x43, //Play/Pause, Fast Rewind, Fast Forward

0x07, 0x15, 0x09, //EQ, subtraction, addition

0x16, 0x19, 0x0D, //0, return, U/SD

0x0C, 0x18, 0x5E, //1, 2, 3

0x08, 0x1C, 0x5A, //4, 5, 6

0x42, 0x52, 0x4A};//7, 8, 9


// External variable declaration

extern bit flagIrd; //Infrared data code value reception completed flag

extern unsigned char irdCode[4]; //Save the four-byte data code decoded by the NEC protocol (user code + user inverse code, key code + key code inverse code)


extern void InitLCD1602();

extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char * str);

extern void LcdSetCoursor(unsigned char x, unsigned char y);

extern void LcdOpenCoursor();

extern void InitDS1302();

extern void GetTimeFromDS1302(struct Time * time);

extern void SetTimeToDS1302(struct Time * time);

extern void KeyDriver();

extern void KeyScan();


extern void LcdCoursorRight();

extern void LcdCoursorLeft();


void ConfgiTimer0(unsigned int xms);

void RefreshLcdShowTime();

extern void ConfigIrdByTimer1();

void IrdDrive();

void IrdKeyAction();

extern void SetTimeBcdByte(unsigned char keyNum);


/*Main program main()*/

void main()

{

unsigned char psec = 0xFF; //Used to detect whether sec seconds have changed, if changed, refresh the time display


ConfgiTimer0(1); //timing 1ms

ConfigIrdByTimer1(); //Configure infrared communication

InitLCD1602();

InitDS1302();


/*LCD initialization display*/

LcdShowStr(1, 0, "*");

LcdShowStr(2, 0, "20 - - ");

LcdShowStr(12, 0, "*");

LcdShowStr(14, 0, "--");

LcdShowStr(0, 1, "time: --:--:--");


while (1)

{


KeyDriver(); //Detect key action


if (flagIrd)

{

flagIrd = 0;

IrdKeyAction(); //Detect infrared key action

}


if (flag200ms == 1 && (setTimeIndex == 0)) //Refresh the time display every 200ms and when setTimeIndex==0 is not in the set time state

{

flag200ms = 0;

GetTimeFromDS1302(&timeBuf); //Get the time from DS1302 to the member of the timeBuf structure pointer variable

if (timeBuf.sec != psec) //The current second value is not equal to the previous second value

{

RefreshLcdShowTime(); //Refresh time display

psec = timeBuf.sec; //Backup the current second value (second register value)

}

}

}


}


/*Timer T0 configuration*/

void ConfgiTimer0(unsigned int xms)

{

unsigned long tmp;

tmp = 11059200/12; // cycle frequency

tmp = (tmp * xms) / 1000; //The count value required for timing xms

tmp = 65536-tmp; //Initial value loaded at regular intervals

thr0 = (unsigned char)(tmp >> 8);

tlr0 = (unsigned char)tmp;

TMOD &= 0xF0; // Clear T0 control bit

TMOD |= 0x01; //T0 mode 1, 16-bit configurable time mode

TH0 = thr0;

TL0 = tlr0;

TR0 = 1;

ET0 = 1;

EA = 1;

}


/*Decompose a BCD code byte data and display it on the (x, y) coordinates of LCD1602*/

void LcdShowBCDByte(unsigned char x, unsigned char y, unsigned char bcdbyte)

{

unsigned char str[4];


str[0] = (bcdbyte >> 4) + '0'; //Get the high 4 bytes of the BCD code

str[1] = (bcdbyte & 0x0F) + '0'; //Get the fourth byte of the BCD code

str[2] = '';


LcdShowStr(x, y, str);

}


/*Refresh time to display on LCD1602*/

void RefreshLcdShowTime()

{

LcdShowBCDByte(4, 0, timeBuf.year); //Display year

LcdShowBCDByte(7, 0, timeBuf.month);

LcdShowBCDByte(10, 0, timeBuf.day);

LcdShowBCDByte(6, 1, timeBuf.hour);

LcdShowBCDByte(9, 1, timeBuf.min);

LcdShowBCDByte(12, 1, timeBuf.sec);

LcdShowBCDByte(14, 0, timeBuf.week); //Display the week

}


/************The following function is the high and low digits of the BCD code byte +1 and -1**********************/

/*Increment the high digit of the BCD code*/

unsigned char IncrementBCDByteHigh(unsigned char bcdbyte)

{

if ((bcdbyte & 0xF0) < 0x90) //Check if the high 4 bytes of bcdbyte are less than 9

{

bcdbyte += 0x10; //high four bytes + 1

}

else

{

//The high four-bit value returns to zero when it reaches 9

bcdbyte &= 0x0F;//0000 1111

}


return (bcdbyte); //Return the modified BCD code value

}


/*Increment the low byte of the BCD code*/

unsigned char IncrementBCDByteLow(unsigned char bcdbyte)

{

if ((bcdbyte & 0x0F) < 0x09) //Get the lower four digits of bcdbyte

{

bcdbyte += 0x01; //low byte + 1

}

else

{

//Reset to zero at 9

bcdbyte &= 0xF0; //lower four bits cleared

}


return (bcdbyte);

}


/*Decrement the high byte of the BCD data byte*/

unsigned char DescBCDByteHigh(unsigned char bcdbyte)

{

if ((bcdbyte & 0xF0) > 0) //Get the high 4 bytes of the BCD code byte

{

bcdbyte -= 0x10; //high four-bit byte number -1

}

else

{

// Return to 9 from 0

bcdbyte |= 0x90; //或bcdbyte &= 0x9F

}


return (bcdbyte);

}


/*Decrement the low byte of the BCD data byte*/

unsigned char DescBCDByteLow(unsigned char bcdbyte)

{

if ((bcdbyte & 0x0F) > 0)

{

bcdbyte -= 0x01; //low digit -1

}

else

{

// Return to 9 from 0

bcdbyte |= 0x09;

}


return (bcdbyte);

}



/*Set the cursor flashing position according to the value of setTimeIndex*/

void LcdRefreshSetCoursor()

{

switch (setTimeIndex)

{

case 1: LcdSetCoursor(4, 0); break; //Set the ten digits of the year

case 2: LcdSetCoursor(5, 0); break;

case 3: LcdSetCoursor(7, 0); break;

case 4: LcdSetCoursor(8, 0); break;

case 5: LcdSetCoursor(10, 0); break;

case 6: LcdSetCoursor(11, 0); break;

case 7: LcdSetCoursor(6, 1); break;

case 8: LcdSetCoursor(7, 1); break;

case 9: LcdSetCoursor(9, 1); break;

case 10: LcdSetCoursor(10, 1); break;

case 11: LcdSetCoursor(12, 1); break;

case 12: LcdSetCoursor(13, 1); break;

default: break;

}

LcdOpenCoursor();

}


/*Increment the time value of the cursor blinking position*/

void IncTimeBysetTimeIndex()

{

switch (setTimeIndex)

{

case 1: timeBuf.year = IncrementBCDByteHigh(timeBuf.year); break; //year10++ten digits of the year++

case 2: timeBuf.year = IncrementBCDByteLow(timeBuf.year); break;//year digit++

case 3: timeBuf.month = IncrementBCDByteHigh(timeBuf.month); break;//月十位++

case 4: timeBuf.month = IncrementBCDByteLow(timeBuf.month); break;//月个位++

case 5: timeBuf.day = IncrementBCDByteHigh(timeBuf.day); break;

case 6: timeBuf.day = IncrementBCDByteLow(timeBuf.day); break;

case 7: timeBuf.hour = IncrementBCDByteHigh(timeBuf.hour); break;

case 8: timeBuf.hour = IncrementBCDByteLow(timeBuf.hour); break;

case 9: timeBuf.min = IncrementBCDByteHigh(timeBuf.min); break;

case 10: timeBuf.min = IncrementBCDByteLow(timeBuf.min); break;

case 11: timeBuf.sec = IncrementBCDByteHigh(timeBuf.sec); break;

case 12: timeBuf.sec = IncrementBCDByteLow(timeBuf.sec); break;

default: break;

}

RefreshLcdShowTime(); //Refresh time display

LcdRefreshSetCoursor(); //Refresh cursor flashing display

}


/*Decrement the time value of the cursor position*/

void DecTimeBySetTimeIndex()

{

switch (setTimeIndex)

{

case 1: timeBuf.year = DescBCDByteHigh(timeBuf.year); break; //Decrease the ten digits of the year

case 2: timeBuf.year = DescBCDByteLow(timeBuf.year); break; //Decrease the year digit

case 3: timeBuf.month = DescBCDByteHigh(timeBuf.month); break;

case 4: timeBuf.month = DescBCDByteLow(timeBuf.month); break;

case 5: timeBuf.day = DescBCDByteHigh(timeBuf.day); break;

case 6: timeBuf.day = DescBCDByteLow(timeBuf.day); break;

case 7: timeBuf.hour = DescBCDByteHigh(timeBuf.hour); break;

case 8: timeBuf.hour = DescBCDByteLow(timeBuf.hour); break;

case 9: timeBuf.min = DescBCDByteHigh(timeBuf.min); break;

case 10: timeBuf.min = DescBCDByteLow(timeBuf.min); break;

case 11: timeBuf.sec = DescBCDByteHigh(timeBuf.sec); break

case 12: timeBuf.sec = DescBCDByteLow(timeBuf.sec); break;

default: break;

}

/*Refresh the time display first, then refresh the cursor flashing display*/

RefreshLcdShowTime();

LcdRefreshSetCoursor();

}


/*Infrared button action function*/

void IrdKeyAction()

{

if (irdCode[2] == 0x44) // >>||

{

if (setTimeIndex == 0) //Normal operation status

{

setTimeIndex = 1;

LcdRefreshSetCoursor(); //Refresh cursor setting display

}

else

{

SetTimeToDS1302(&timeBuf); //Write time into DS1302

setTimeIndex = 0;

RefreshLcdShowTime();

}

}

else if (irdCode[2] == 0x40) //|<<

{

if (setTimeIndex != 0)

{

LcdCoursorLeft();

}

}

else if (irdCode[2] == 0x43) // >>|

{

if (setTimeIndex != 0)

{

LcdCoursorRight();

}

}

else if (irdCode[2] == 0x15) //-

{

DecTimeBySetTimeIndex();

}

else if (irdCode[2] == 0x09) //+

{

IncTimeBysetTimeIndex();

}

else if (irdCode[2] == 0x19) //EQ

{

setTimeIndex = 0;

RefreshLcdShowTime();

}

else if (irdCode[2] == 0x16) //Number key 0

{

SetTimeBcdByte(0);

}

else if (irdCode[2] == 0x0C) //Number key 1

{

SetTimeBcdByte(1);

}

else if (irdCode[2] == 0x18) //Number key 2

{

SetTimeBcdByte(2);

}

else if (irdCode[2] == 0x5E)

{

SetTimeBcdByte(3);

}

else if (irdCode[2] == 0x08)

{

SetTimeBcdByte(4);

}

else if (irdCode[2] == 0x1C)

{

SetTimeBcdByte(5);

}

else if (irdCode[2] == 0x5A)

[1] [2] [3]
Reference address:Electronic clock program with adjustable time

Previous article:Design of emergency power inverter circuit using single chip microcomputer SPWM
Next article:Circuit structure of P0 port of 51 single chip microcomputer

Recommended ReadingLatest update time:2024-11-16 17:50

STC89c52+DS1302 clock, digital tube displays time and date, adjustable
I have been working on a digital electronic clock recently, and I have summarized some information to share with you. The DS1302 clock chip. The chips needed for computer simulation are AT89C52, 74HC138 resistor array (because the IO port of C52 microcontroller P0 does not have a pull-up resistor), 74HC245. If you nee
[Microcontroller]
STC89c52+DS1302 clock, digital tube displays time and date, adjustable
STC89C52 microcontroller learning (1)----Lighting up the LED
1. Implement LED running lights through arrays  #include reg52.h   int m; unsigned char code leds = {0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe};   void delay(unsigned int i) { unsigned int j; unsigned char k;   for(j=i; j 0; j--) for(k=125; k 0 ;k--); }   int main() { while(1) { for(m = 0; m 8; m
[Microcontroller]
STC89C52 MCU external interrupt 0 experiment
///////////////////////////////////////////////////// /////////////////////////   Function implementation:  Set external interrupt 0, and then light up D1 connected to the first pin of the microcontroller P1 port to                         show that the system has entered external interrupt 0   Experimental board mo
[Microcontroller]
#microcontroller# ------ stc89c52 pin description
STC89C52 function brief description: STC89C52 is a low-power, high-performance CMOS 8-bit microcontroller with 8K in-system programmable Flash memory. Manufactured using high-density non-volatile memory technology, it is fully instruction- and pin-compatible with industrial 80C51 products. On-chip Flash allows the pr
[Microcontroller]
#microcontroller# ------ stc89c52 pin description
Design and simulation of electronic password lock based on STC89C52 single chip microcomputer
0. Introduction Electronic password locks are commonly used encryption tools in modern life. They overcome the shortcomings of mechanical password locks, such as small passwords and poor security performance, especially the intelligent electronic password locks; they not only have the functions of electroni
[Microcontroller]
Design of Multi-channel Pulse Acquisition System Based on STC89C52
0 Introduction Pulse diagnosis is important because the pulse can transmit physiological and pathological information of various parts of the body, and is a window to peek into the functional changes in the body, which can provide an important basis for diagnosing diseases. However, traditional pulse diagnosis mainly
[Test Measurement]
Design of Multi-channel Pulse Acquisition System Based on STC89C52
Detailed explanation of the internal system structure and functions of STC89C52RC microcontroller
power supply In our learning process, many indicators are directly used conceptual indicators. For example, we say +5 V represents 1, GND represents 0, and so on. But the voltage value in the actual circuit is not completely accurate, so what is the allowable range of these indicators? As the content we learn continue
[Microcontroller]
Detailed explanation of the internal system structure and functions of STC89C52RC microcontroller
Analysis of LED dimming system circuit based on STC89C52/MAX1771
The arrangement of the LEDs and the specifications of the LED light source determine the basic driver requirements. The main function of an LED driver is to limit the current flowing through the LED under a certain range of operating conditions, regardless of how the input and output voltages vary. The most com
[Microcontroller]
Analysis of LED dimming system circuit based on STC89C52/MAX1771
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components
Guess you like

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号