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. . .
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.
/*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
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
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Detailed explanation of intelligent car body perception system
- How to solve the problem that the servo drive is not enabled
- Why does the servo drive not power on?
- What point should I connect to when the servo is turned on?
- How to turn on the internal enable of Panasonic servo drive?
- What is the rigidity setting of Panasonic servo drive?
- How to change the inertia ratio of Panasonic servo drive
- What is the inertia ratio of the servo motor?
- Is it better for the motor to have a large or small moment of inertia?
- What is the difference between low inertia and high inertia of servo motors?
- SPWM wave generation tool
- How to force the switch state of TI TMS320F28335 EPWM by software
- "Intel SoC FPGA Learning Experience" + My Implementation Method of GDBServer in Lesson 5
- EEWORLD University Hall----Live Replay: The Development and Latest Application of TTI TE Sensors in Industrial Motors
- [NUCLEO-WL55JC2 Review] + Development environment establishment and data preparation
- Xiaodanta teaches you the difference between a handheld radio amplifier and a repeater
- Why does the output voltage of the transistor voltage regulator circuit equal the base voltage minus VBE?
- WIFI6 Explained
- Control battery output and prevent battery reverse connection
- 【NXP Rapid IoT Review】 + Kit Modification-External Lithium Battery (Link)