Based on 51 single chip microcomputer + DS1302 perpetual calendar + LCD1602 display + button broadcast time + temperature control fan + button control light

Publisher:悦耳旋律Latest update time:2022-09-20 Source: csdn Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Some time ago, I made a perpetual calendar based on 51 single-chip microcomputer, plus temperature control fan and button time broadcast. Here are some notes.

Preparing the Hardware

1:51 single chip microcomputer (I use STC89C52 here)

2: Voice broadcast module (I use SYN6288 here)

3: DS1302 clock module

4: DS18B20 temperature module

5: LCD1602 display

6: L298N motor driver

7: Buzzer

8: Motor

9: 5 buttons

10: Lights


Features

Function:

1: Modification time

2: Modification date (the software automatically corrects the date)

3: Alarm mode

4: Temperature control fan speed

5: Adjust the light brightness

6: Broadcast time


Main interface settings

The following is a rough flowchart, but the location is not complete. . .

insert image description here

Since there are a lot of codes, I won’t post all of them here.


Change the time

When we enter the time modification interface, our screen should display the time just pressed, and then we should

1: LCD1602 displays time

2: Button operation

Button 1: +1 for hour/minute/second or press button 2 to -1 for hour/minute/second, then press button 3 to switch between hour/minute/second

3: Press button 4 to exit

4: Prompt whether to save the time (1: save, 4: do not save)

If we save it and write it to DS1302, we will complete the function of modifying the time.


/*Time value plus function*/

unsigned char time_add(unsigned char cursor)

{

unsigned char hour_high,hour_low;

unsigned char min_high, min_low;

unsigned char sec_high, sec_low;

switch(cursor)

{

case 0: //modification++

hour_high = temp[2] >> 4;

hour_low = temp[2] & 0x0f;

hour_low = hour_low++;

if(hour_low == 4 && hour_high == 2) //If it is equal to 24, change it to 00

{

hour_low = 0;

hour_high = 0;

}

else if(hour_low == 10)

{

hour_low = 0;

if(hour_high == 2)

hour_high = 0;

else

hour_high = hour_high + 1;

}

hour_high = hour_high << 4;

hour_high = hour_high | hour_low;

temp[2] = hour_high;

lcd_display_byte(5,0,(temp[2]>>4) + 0x30);

lcd_display_byte(6,0,(temp[2]&0x0f) + 0x30);

write_com(0x86);

break;

case 1://Modify points++

min_high = temp[1] >> 4;

min_low = temp[1] & 0x0f;

min_low++;

if(min_low == 10)

{

min_high++;

min_low = 0;

if(min_high == 6 && min_low == 0)

{

min_high = 0;

min_low = 0;

}

}

min_high = min_high << 4;

min_high = min_high | min_low;

temp[1] = min_high;

lcd_display_byte(8,0,(temp[1]>>4) + 0x30);

lcd_display_byte(9,0,(temp[1]&0x0f) + 0x30);

write_com(0x89);

break;

case 2://Modify seconds++

sec_high = temp[0] >> 4;

sec_low = temp[0] & 0x0f;

sec_low++;

if(sec_low == 10)

{

sec_low = 0;

sec_high++;

if(sec_high == 6 && sec_low == 0)

{

sec_low = 0;

sec_high = 0;

}

}

sec_high = sec_high << 4;

sec_high = sec_high | sec_low;

temp[0] = sec_high;

lcd_display_byte(11,0,(temp[0]>>4) + 0x30);

lcd_display_byte(12,0,(temp[0]&0x0f) + 0x30);

write_com(0x8c);

break;

default :

break;

}

return cursor;

}


Modify the date (and correct the day of the week)

When we enter the interface for modifying the date, the screen should display the date just pressed, and then we should

1: LCD1602 displays date

2: Button operation

Button 1: add 1 to year/month/day or press button 2 to subtract 1 from year/month/day, then press button 3 to switch between adjusting year/month/day

3: Press button 4 to exit

4: Prompt whether to save the date (1: save, 4: do not save)

5: Automatic adjustment of the day of the week

Week = (number corresponding to the month + number of the day) / 7 remainder: the day of the week 0 digit Sunday

If we save it and write it to DS1302, the function of modifying the date is completed.

insert image description here

/*Automatically correct the week function*/

void revision_week()

{

unsigned char num;

unsigned char month;

unsigned char day;

unsigned char week;


// Week = (Month number + Date number) / 7 Remainder: the day of the week 0 is Sunday


month = ((temp[4]>>4)*10 + (temp[4]&0x0f)); //Convert the month BCD code to decimal

day = ((temp[3]>>4)*10 + (temp[3]&0x0f)); //Convert the day BCD code to decimal

switch(month)

{

//Month corresponding number

case 5: num = 5; break;

case 6: num = 1; break;

case 8: num = 6; break;

case 1: case 10: num = 4; break;

case 4: case 7: num = 3; break;

case 9: case 12: num = 2; break;

case 2: case 3: case 11: num = 0; break;  

}

week = (num+day)%7;

    if(week == 0) 

temp[5] = 0x07;

else

temp[5] = week;



Alarm mode

Enter the alarm mode, set the alarm time, select the day of the week, and select the ringing duration.

The time setting is exactly the same as the time modification setting. After setting the time, we switch to setting the week. Button 1 is to switch from Monday to Sunday, button 2 is to confirm the selection of the current week, and button 3 is to cancel the selection of the current week.

Button 4: Do you want to save? If you don't save, you will exit. If you save, you will continue to jump to the interface for selecting the alarm time. There is nothing here. Then save and exit. The main interface OFF becomes ON to indicate that it is turned on.


/* Select/cancel the alarm on a certain day of the week*/

/* Day of the week ++ open close exit */  

void lcd_dispaly_chooseClockWeek()

{

unsigned char s = 0;

unsigned char week;

LCD1602_CLS; //Clear screen

lcd_display_str(0,0,"week: 2:ON3:OFF");

lcd_display_str(0,1,"clock:");

week = temp[5];

while(1)

{

lcd_display_byte(5,0,(week & 0x0f) + 0x30); //Display the current week

for(s=0;s<7;s++)

{

if((alarmClockWeek>>s)&0x01 == 1)

lcd_display_byte(s+6,1,(s+1)+0x30);

}

write_com(0x85);

menu = gather_key(); //Collect which button is pressed

switch(menu) 

{

case 1:

week++;

if(week >= 8)

week = 1;

break;

case 2:

switch(week)

{  

case 1: alarmClockWeek |= 0x01; lcd_display_byte(6,1,'1'); break;//0000 0001

case 2: alarmClockWeek |= 0x02; lcd_display_byte(7,1,'2'); break;//0000 0010

case 3: alarmClockWeek |= 0x04; lcd_display_byte(8,1,'3'); break;//0000 0100

case 4: alarmClockWeek |= 0x08; lcd_display_byte(9,1,'4'); break;//0000 1000

case 5: alarmClockWeek |= 0x10; lcd_display_byte(10,1,'5'); break;//0001 0000

case 6: alarmClockWeek |= 0x20; lcd_display_byte(11,1,'6'); break;//0010 0000

case 7: alarmClockWeek |= 0x40; lcd_display_byte(12,1,'7'); break;//0100 0000

}

break;

case 3:

switch(week)

{

case 1: alarmClockWeek &= ~0x01; lcd_display_byte(6,1,' '); break;

case 2: alarmClockWeek &= ~0x02; lcd_display_byte(7,1,' '); break;

case 3: alarmClockWeek &= ~0x04; lcd_display_byte(8,1,' '); break;

case 4: alarmClockWeek &= ~0x08; lcd_display_byte(9,1,' '); break;

case 5: alarmClockWeek &= ~0x10; lcd_display_byte(10,1,' '); break;

case 6: alarmClockWeek &= ~0x20; lcd_display_byte(11,1,' '); break;

case 7: alarmClockWeek &= ~0x40; lcd_display_byte(12,1,' '); break;

}

break;

case 4:

s = lcd_display_saveTimeOrDate_YesOrNo(3);//Save? No: clear to 0. No: do not clear

if(s)

{

ALARM_CLOCK_OFF; //Turn off the alarm

// Clear the alarm date

alarmClockWeek = 0;

LCD1602_CLS; //Clear screen

return;

}

ALARM_CLOCK_ON; //Turn on the alarm

LCD1602_CLS; //Clear screen

return;

}

}


}


Adjust light mode

/*Modify light brightness function*/

void modifLightMode()

{

unsigned char s = 0;

s = lcd_display_light_menu(); //Display the light brightness modification menu

if(s)

{

write_com(CLEAR_SCREEN); //Clear screen

exitFlag = 1;

return;

}

lcd_display_str(0,0,"Light gear:");

TR0 = 1;

while(menu != 4)

{

lcd_display_byte(11,0,light_gear+0x30);//display light gear

menu = gather_key(); //Detect if a key is pressed

switch(menu)

{

case 1:

light_gear++;

if(light_gear>=3)

{

light_gear = 3;

TR0 = 0;

LED = 0;

}

else if(light_gear == 0)

{

TR0 = 0;

LED = 1;

}

else

{

TR0 = 1;

LED = 0;

}

break;

case 2:

if(light_gear>=1)

{

light_gear--;

}

else

{

light_gear = 0;

}


if(light_gear == 3)

{

TR0 = 0;

LED = 0;

}

else if(light_gear == 0)

{

TR0 = 0;

LED = 1;

}

else

{

TR0 = 1;

LED = 0;

}

break;


case 4:

exitFlag = 1;

return;

}

}

}


Adjust fan mode

/*Modify fan speed function*/

void modifFanMode()

{

unsigned char s = 0;

s = lcd_display_fan_menu(); //Display the fan speed modification menu

if(s)

{

write_com(CLEAR_SCREEN); //Clear screen

exitFlag = 1;

return;

}

lcd_display_str(0,0,"Fan gear:");

TR1 = 1;

while(menu != 4)

{

lcd_display_byte(9,0,fan_gear+0x30); //Display fan gear

menu = gather_key(); //Detect if a key is pressed

switch(menu)

{

case 1:

fan_gear++;

if(fan_gear>=3)

{

FAN = 1;

TR1 = 0;

fan_gear = 3;

}

else if(fan_gear == 0)

{

FAN = 0;

TR1 = 0;

}

else

{

FAN = 1;

TR1 = 1;

}

break;

case 2:

if(fan_gear>=1)

{

fan_gear--;

}

if(fan_gear == 0)

{

FAN = 0;

TR1 = 0;

fan_gear = 0;

}

else if(fan_gear == 3)

{

FAN = 1;

TR1 = 0;

}

else

{

TR1 = 1;

FAN = 1;

}

break;

case 4:

exitFlag = 1;

return;

}

}

}


Press button to announce time

Here I use external interrupts.


/*SYN6288 broadcast time*/

void playTime(void)

{

unsigned char syn6288_time[5] = {''};

syn6288_time[0] = (time[2]>>4)+48; //time

syn6288_time[1] = (time[2]&0x0f)+48;

syn6288_time[2] = ':';

syn6288_time[3] = (time[1]>>4)+48; // points

syn6288_time[4] = (time[1]&0x0f)+48;

SYN_FrameInfo(0, "[v16][t5] Current time");

delay(2000);

SYN_FrameInfo(0,syn6288_time);

delay(2000);

}


void key_handler(void) interrupt 0

{

delay(15); //debounce effect

if(kk == 0)

{

EX0 = 0;

playTime(); //play time

EX0 = 1;

}

}


Temperature Control Fan

/*Fan speed control function*/

void fan_speed_control()

{

/*Modify the temperature threshold here to control the speed*/

if(temperature[0] >= 20 && temperature[0] <= 25)

{

fan_gear = 1;

FAN = 1;

TR1 = 1;

}

else if(temperature[0] >= 26 && temperature[0] <= 30)

{

fan_gear = 2;

FAN = 1;

TR1 = 1;

}

else if(temperature[0] > 30)

{

fan_gear = 3;

FAN = 1;

TR1 = 0;

}

else

{

fan_gear = 0;

FAN = 0;

TR1 = 0;

}

}


Main program code

#include

#include "lcd1602.h"

#include "ds1302.h"

#include "key.h"

#include "alarmClock.h"

#include "light.h"

#include "ds18b20.h"

#include "fan.h"

#include "uart.h"

#include "syn6288.h"

#include "delay.h"


void main()

{

lcd_init(); //Initialize LCD1602 

ds1302_init(); // Initialize DS1302

key_init(); //Initialize the button

[1] [2]
Reference address:Based on 51 single chip microcomputer + DS1302 perpetual calendar + LCD1602 display + button broadcast time + temperature control fan + button control light

Previous article:MCU Strategy 2 - I/O Communication Basics
Next article:Based on 51 MCU + DHT11 temperature and humidity module + ESP8266 module + upload oneNET APP display + LCD1602 display

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号