Graduation Project | Sharing a Basic Version of the Eternal Calendar

If you don’t want to miss my updates, remember to check the public account in the upper right corner and set it as a star, I would appreciate it.

Graduation Project | Sharing a Basic Version of the Eternal Calendar
Graduation Project | Sharing a Basic Version of the Eternal Calendar

The graduation project shared this time is a relatively low-difficulty 51 single-chip microcontroller clock eternal calendar. If you are a beginner, it is very suitable to get started. If it is used as a graduation project, it may be difficult to pass in some schools, but more functions can be added based on this, which will increase the difficulty of the work and improve its functionality.

Let’s take a look at the features:

1. Can display the current time, day of the week, and date

2. Can modify the current time, day of the week, and date

3. Can obtain the ambient temperature and display it on the LCD

4. Can set an alarm, when the time arrives, the buzzer sounds, and it stops ringing after pressing the button

Main control selection: STC89C52RC

STC89C52 is a low-power, high-performance CMOS 8-bit microcontroller with 8K in-system programmable Flash memory. It has a clever 8-bit CPU and in-system programmable Flash on a single chip, making STC89C52 provide highly flexible and efficient solutions for many embedded control application systems. Currently, STC89C52 still has some market share.

Display selection: LCD1602

LCD1602 goes without saying, it is the most common hardware graduation project. It consists of a character liquid crystal display (LCD), control driver main circuit HD44780 and its extended driver circuit HD44100, as well as a small number of resistors, capacitors, and structural components assembled on a PCB. The LCD1602 chips produced by different manufacturers may vary, but the usage is the same. To reduce costs, most manufacturers directly mount the bare chips onto the board.

Clock chip selection: DS1302

DS1302 is a low-power real-time clock chip launched by DALLAS in the United States, which has the ability to charge with a tiny current. It can keep track of the year, month, day, week, hour, minute, and second, and has various functions such as leap year compensation.

Temperature sensor selection: DS18B20

DS18B20 is a commonly used digital temperature sensor that outputs a digital signal, characterized by small size, low hardware overhead, strong anti-interference ability, and high precision. [1] The DS18B20 digital temperature sensor is easy to wire, and after packaging, it can be applied in various occasions, such as pipe type, threaded type, magnetic adsorption type, stainless steel packaged type, and various models, including LTM8877, LTM8874, etc.

Peripheral devices: buttons, buzzers, switches, button batteries, potentiometers, transistors, etc.

In terms of schematic design, the first is the minimum system of the microcontroller, including power supply, crystal oscillator, and reset circuit.

Graduation Project | Sharing a Basic Version of the Eternal Calendar

Graduation Project | Sharing a Basic Version of the Eternal Calendar

Display circuit: the data line connects to P0, be careful to connect a 1K pull-up resistor
Graduation Project | Sharing a Basic Version of the Eternal Calendar

Clock chip circuit: 3 pins connect to the microcontroller IO port for control

Graduation Project | Sharing a Basic Version of the Eternal Calendar

PCB design:

Graduation Project | Sharing a Basic Version of the Eternal Calendar

Here is the complete code for reference and learning:

#include "reg52.h"       // This file defines some special function registers of the microcontroller#include "ds1302.h"#include "temp.h"#include "lcd.h"#include "eeprom.h"
sbit k1 = P1^0;        // Button
sbit k2 = P1^1;       
sbit k3 = P1^2;
sbit k4 = P1^3;
sbit lcdled = P2^4;        // LCD backlight
sbit beep = P1^4;      // Buzzer
unsigned int ti=0,alarm=0;       // Modify which time parameter, modify which alarm parameter
unsigned char alarm_hour=0x12,alarm_min=0x00;   // Alarm hour, minute parameters
enum Mode        // Define enumeration, three modes
{  DISPLAYDATA,MODIFYDATA,SETALARMCLOCK,NONE,ALARMCLOCK}mode;
enum Alarmswitch   // Define alarm switch
{  OFF,ON}alarmswitch;
/********* Delay function ***********/      void delay(unsigned int t)   // Short delay
{   while(t--);}
void delay_ms(unsigned int t)  // Millisecond delay
{  unsigned int a,b;  for(a=0;a<t;a++)  for(b=0;b<120;b++);}
/******** Display date, time, week ***********/void display_data(void){  LcdWriteCom(0x80);  LcdWritestr("20");    LcdWriteData(TIME[6]/16+0x30);    // Year  LcdWriteData(TIME[6]%16+0x30);  LcdWriteData('-');  LcdWriteData(TIME[4]/16+0x30);    // Month  LcdWriteData(TIME[4]%16+0x30);  LcdWriteData('-');  LcdWriteData(TIME[3]/16+0x30);    // Day  LcdWriteData(TIME[3]%16+0x30);
  LcdWritestr("  ");  switch(TIME[5])             // Display week  {
        case 0:LcdWritestr("Mon"); break;    case 1:LcdWritestr("Tue"); break;    case 2:LcdWritestr("Wed"); break;    case 3:LcdWritestr("Thu"); break;    case 4:LcdWritestr("Fri"); break;    case 5:LcdWritestr("Sat"); break;    case 6:LcdWritestr("Sun"); break;  }  if(alarmswitch==ON)LcdWriteData('.');  else LcdWriteData(' ');
  LcdWriteCom(0xC0);  LcdWriteData(' ');  LcdWriteData(TIME[2]/16+0x30);    // Hour  LcdWriteData(TIME[2]%16+0x30);  LcdWriteData(':');  LcdWriteData(TIME[1]/16+0x30);    // Minute  LcdWriteData(TIME[1]%16+0x30);  LcdWriteData(':');  LcdWriteData(TIME[0]/16+0x30);    // Second  LcdWriteData(TIME[0]%16+0x30);  LcdWritestr(" ");}
/********* Display temperature ***********/void displaytemp(int temp)    // Display temperature
{     float tp;    static char flag = 1;  if(temp< 0)          {
    LcdWriteCom(0xca);    LcdWriteData('-');     temp=temp-1;    temp=~temp;    tp=temp;    temp=tp*0.0625*100+0.5;       }   else    {          LcdWriteCom(0xca);    LcdWriteData('+');     tp=temp;    temp=tp*0.0625*100+0.5;    }    if(flag)    {      flag =0;      temp = 2600;    }  if(temp==8500)    return ;  LcdWriteData(temp % 10000 / 1000 + 0x30);  LcdWriteData(temp % 1000 / 100  + 0x30);  LcdWriteData('.');  LcdWriteData(temp % 100 / 10 + 0x30);  LcdWriteData(temp % 10 + 0x30);}
/******************************************************************************** 函 数 名         : keypros* 函数功能       : Button processing function, judge whether button K1 is pressed*******************************************************************************/void keypros()       // Initial page button detection
{  if(k1 == 0)         // Switch mode  {
    delay(1000);   // Eliminate jitter, generally about 10ms    if(k1==0)   // Re-judge whether the button is pressed    {
      mode+= 1;if(mode == 3)mode = DISPLAYDATA;    }
    while(k1 == 0);  }  else if(k2 == 0)        // Buzzer test  {
    delay(1000);   // Eliminate jitter, generally about 10ms    if(k2==0)   // Re-judge whether the button is pressed    {
      beep = !beep;      }
    while(k2 == 0);  }  else if(k3 == 0)       // Backlight test  {
    delay(1000);   // Eliminate jitter, generally about 10ms    if(k3==0)   // Re-judge whether the button is pressed    {
      lcdled = !lcdled;      }
    while(k3 == 0);  }  else if(k4 == 0)      // Backlight test  {
    delay(1000);   // Eliminate jitter, generally about 10ms    if(k4==0)   // Re-judge whether the button is pressed    {
      alarmswitch=!alarmswitch;      }
    while(k4 == 0);  }    }
/************* Modify time ************/void modify(void){  static int time=0;  time++;  if(k1 == 0)      // Switch mode  {
    delay(1000);   // Eliminate jitter, generally about 10ms    if(k1==0)   // Re-judge whether the button is pressed    {
      mode+= 1;if(mode == 3)mode = DISPLAYDATA;    }
    while(k1 == 0);  }  else if(k2 == 0)       // Select modification parameter  {
    delay(1000);   // Eliminate jitter, generally about 10ms    if(k2==0)   // Re-judge whether the button is pressed    {
      ti++;       if(ti == 8)ti=0;     }
    while(k2 == 0);  }  else if(k3 == 0 ||k4 == 0)  switch(ti)           // Select to enter modification parameters  {
    case 0:            if(k4==0 | k3==0)            {
      delay(1000);   // Eliminate jitter, generally about 10ms              if(k4==0 | k3 ==0)   // Re-judge whether the button is pressed              {
        TIME[0]=0;              }
      while(k4 == 0 | k3==0);            }
                        break;    //?    case 1:            if(k3==0)            {
              delay(1000);   // Eliminate jitter, generally about 10ms              if(k3 ==0)   // Re-judge whether the button is pressed              {
                TIME[1]++;
                if(TIME[1]%16 == 0x0a)                 {
                    TIME[1] += 16;                  TIME[1] &= 0xf0;                 }
if(TIME[1]==0x60)TIME[1]=0;              }
              while(k3==0);            }
            if(k4==0)            {
              delay(1000);   // Eliminate jitter, generally about 10ms              if(k4 ==0)   // Re-judge whether the button is pressed              {
                TIME[1]--;
                if(TIME[1]%16==0x0f && TIME[1]!=0xff)                 {
                  TIME[1] &= 0xf9;                 }
                 if(TIME[1]==0xff)TIME[1]=0x59;              }
              while(k4==0);            }
            break;    //?    case 2:            if(k3==0)            {
              delay(1000);   // Eliminate jitter, generally about 10ms              if(k3 ==0)   // Re-judge whether the button is pressed              {
                TIME[2]++;
                if(TIME[2]%16 == 0x0a)                 {
                    TIME[2] += 16;                  TIME[2] &= 0xf0;                 }
if(TIME[2]==0x24)TIME[2]=0;              }
              while(k3==0);            }
            if(k4==0)            {
              delay(1000);   // Eliminate jitter, generally about 10ms              if(k4 ==0)   // Re-judge whether the button is pressed              {
                TIME[2]--;
                if(TIME[2]%16==0x0f && TIME[2]!=0xff)                 {
                  TIME[2] &= 0xf9;                 }
                 if(TIME[2]==0xff)TIME[2]=0x23;              }
              while(k4==0);            }
            break;    //?    case 3:            if(k3==0)            {
              delay(1000);   // Eliminate jitter, generally about 10ms              if(k3 ==0)   // Re-judge whether the button is pressed              {
                TIME[3]++;
                if(TIME[3]%16 == 0x0a)                 {
                    TIME[3] += 16;                  TIME[3] &= 0xf0;                 }
if(TIME[3]==0x32)TIME[3]=0;              }
              while(k3==0);            }
            if(k4==0)            {
              delay(1000);   // Eliminate jitter, generally about 10ms              if(k4 ==0)   // Re-judge whether the button is pressed              {
                TIME[3]--;
                if(TIME[3]%16==0x0f && TIME[3]!=0xff)                 {
                  TIME[3] &= 0xf9;                 }
                 if(TIME[3]==0xff)TIME[3]=0x31;              }
              while(k4==0);            }
            break;   // Day    case 4:                      if(k3==0)            {
              delay(1000);   // Eliminate jitter, generally about 10ms              if(k3 ==0)   // Re-judge whether the button is pressed              {
                TIME[4]++;
                if(TIME[4]%16 == 0x0a)                 {
                    TIME[4] += 16;                  TIME[4] &= 0xf0;                 }
if(TIME[4]==0x13)TIME[4]=0;              }
              while(k3==0);            }
            if(k4==0)            {
              delay(1000);   // Eliminate jitter, generally about 10ms              if(k4 ==0)   // Re-judge whether the button is pressed              {
                TIME[4]--;
                if(TIME[4]%16==0x0f && TIME[4]!=0xff)                 {
                  TIME[4] &= 0xf9;                 }
                 if(TIME[4]==0xff)TIME[4]=0x12;              }
              while(k4==0);            }
            break;   // Month    case 5:                        if(k3==0)            {
              delay(1000);   // Eliminate jitter, generally about 10ms              if(k3 ==0)   // Re-judge whether the button is pressed              {
                TIME[5]++;if(TIME[5]==7)TIME[5]=0;              }
              while(k3==0);            }
            if(k4==0)            {
              delay(1000);   // Eliminate jitter, generally about 10ms              if(k4 ==0)   // Re-judge whether the button is pressed              {
                TIME[5]--;
                if(TIME[5]==0xff)TIME[5]=6;              }
              while(k4==0);            }
            break;   // Week    case 6:                        if(k3==0)            {
              delay(1000);   // Eliminate jitter, generally about 10ms              if(k3 ==0)   // Re-judge whether the button is pressed              {
                TIME[6]++;
                if(TIME[6]%16 == 0x0a)                 {
                    TIME[6] += 16;                  TIME[6] &= 0xf0;                 }
if(TIME[6]==0xa0)TIME[6]=0;              }
              while(k3==0);            }
            if(k4==0)            {
              delay(1000);   // Eliminate jitter, generally about 10ms              if(k4 ==0)   // Re-judge whether the button is pressed              {
                TIME[6]--;
                if(TIME[6]%16==0x0f && TIME[6]!=0xff)                 {
                  TIME[6] &= 0xf9;                 }
                 if(TIME[6]==0xff)TIME[6]=0x99;              }
              while(k4==0);            }
            break;   // Year    case 7:             if(k3==0)            {
              delay(1000);   // Eliminate jitter, generally about 10ms              if(k3 ==0)   // Re-judge whether the button is pressed              {
                mode=DISPLAYDATA;                ti=0;              }
              while(k3==0);            }
            if(k4==0)            {
              delay(1000);   // Eliminate jitter, generally about 10ms              if(k4 ==0)   // Re-judge whether the button is pressed              {
                   Ds1302Init();      // Clock initialization                mode = DISPLAYDATA;    // Return to date                ti = 0;        // Restore initial modification              }
              while(k4==0);            }
            break;   // Year  }
  if(time == 200)  {    display_data();    if(ti == 7){            LcdWriteCom(0xca);            LcdWritestr(" <- OK");    }        }  else if(time == 400)  switch(ti)           // Select to enter modification parameters  {
    case 0:             LcdWriteCom(0xc7);            LcdWritestr("  ");      break;    case 1:                         LcdWriteCom(0xc4);            LcdWritestr("  ");    break;    case 2:             LcdWriteCom(0xc1);            LcdWritestr("  ");                  break;    case 3:             LcdWriteCom(0x88);            LcdWritestr("  ");      break;    case 4:             LcdWriteCom(0x85);            LcdWritestr("  ");      break;    case 5:             LcdWriteCom(0x8c);            LcdWritestr("   ");      break;    case 6:             LcdWriteCom(0x80);            LcdWritestr("    ");    break;    case 7:             LcdWriteCom(0xca);            LcdWritestr("      ");      break;  }else if(time>400) time=0;    delay_ms(1);  }
void setalarmclock(void)  // Set alarm mode{  static int time=0;  time++;    if(k1 == 0)       // Switch mode  {
    delay(1000);   // Eliminate jitter, generally about 10ms    if(k1==0)   // Re-judge whether the button is pressed    {
      mode+= 1;if(mode == 3)mode = DISPLAYDATA;    }
    while(k1 == 0);  }  if(k2 == 0)       // Select alarm modification parameter  {
    delay(1000);   // Eliminate jitter, generally about 10ms    if(k2==0)   // Re-judge whether the button is pressed    {
      alarm++;       if(alarm == 3)alarm=0;     }
    while(k2 == 0);  }    switch(alarm)      // Select to enter modification parameters  {
    case 0:        if(k3 == 0)        // Control alarm on        {
          delay(1000);   // Eliminate jitter, generally about 10ms          if(k3==0)   // Re-judge whether the button is pressed          {
            alarmswitch = ON;            SectorErase(0x2401);            byte_write(0x2401,alarmswitch);          }
          while(k3 == 0);        }        if(k4 == 0)       // Control alarm off        {
          delay(1000);   // Eliminate jitter, generally about 10ms          if(k4==0)   // Re-judge whether the button is pressed          {
            alarmswitch = OFF;            SectorErase(0x2401);            byte_write(0x2401,alarmswitch);          }
          while(k4 == 0);        }        break;    case 1:                                      if(k3==0)      // Control alarm hour increase            {
              delay(1000);   // Eliminate jitter, generally about 10ms              if(k3 ==0)   // Re-judge whether the button is pressed              {
                 alarm_hour++;
                 if(alarm_hour%16 == 0x0a)                 {
                     alarm_hour += 16;                  alarm_hour &= 0xf0;                 }
if(alarm_hour==0x24)alarm_hour=0;                  SectorErase(0x2601);                byte_write(0x2601,alarm_hour);              }
              while(k3==0);            }            if(k4==0)        // Control alarm hour decrease            {
              delay(1000);   // Eliminate jitter, generally about 10ms              if(k4 ==0)   // Re-judge whether the button is pressed              {
                 alarm_hour--;
                 if(alarm_hour%16==0x0f && alarm_hour!=0xff)                 {
                  alarm_hour &= 0xf9;                 }
                 if(alarm_hour==0xff)alarm_hour=0x23;                 SectorErase(0x2601);                 byte_write(0x2601,alarm_hour);              }
              while(k4==0);            }        break;    case 2:                    if(k3==0)            {
              delay(1000);   // Eliminate jitter, generally about 10ms              if(k3 ==0)   // Re-judge whether the button is pressed              {
                 alarm_min++;
                 if(alarm_min%16 == 0x0a)                 {
                     alarm_min += 16;                  alarm_min &= 0xf0;                 }
if(alarm_min==0x60)alarm_min=0;                 SectorErase(0x2201);                 byte_write(0x2201,alarm_min);              }
              while(k3==0);            }
            if(k4==0)            {
              delay(1000);   // Eliminate jitter, generally about 10ms              if(k4 ==0)   // Re-judge whether the button is pressed              {
                 alarm_min--;
                 if(alarm_min%16==0x0f && alarm_min!=0xff)                 {
                  alarm_min &= 0xf9;                 }
                 if(alarm_min==0xff)alarm_min=0x59;                 SectorErase(0x2201);                 byte_write(0x2201,alarm_min);              }
              while(k4==0);            }        break;  }
  if(time == 200)  {    alarm_hour=byte_read(0x2601);    alarm_min=byte_read(0x2201);    alarmswitch=byte_read(0x2401);    LcdWriteCom(0x80);       // Display    LcdWritestr("alarm clock:    ");    LcdWriteCom(0xc0);     if(alarmswitch == OFF)LcdWritestr("  OFF    ");    else LcdWritestr("  ON     ");    LcdWriteCom(0xc9);     LcdWriteData(alarm_hour/16+0x30);    LcdWriteData(alarm_hour%16+0x30);    LcdWriteData(':');     LcdWriteData(alarm_min/16+0x30);    LcdWriteData(alarm_min%16+0x30);    LcdWritestr("    ");  }  else if(time == 400)  switch(alarm)           // Select to enter modification parameters  {
    case 0:         LcdWriteCom(0xc0);        LcdWritestr("      ");      break;    case 1:         LcdWriteCom(0xc9);        LcdWritestr("  ");    break;    case 2:         LcdWriteCom(0xcc);        LcdWritestr("  ");                  break;      }else if(time>400) time=0;     delay_ms(1);}
/************ Alarm mode *****************/void alarmclock(void){    if(alarmswitch==ON && alarm_hour==TIME[2] && alarm_min==TIME[1])  // Alarm  {          beep=1;    delay_ms(100);    beep=0;    delay_ms(100);      beep=1;    delay_ms(100);    beep=0;    LcdWriteCom(0x80);    LcdWritestr("   time out!    ");    LcdWriteCom(0xc0);    LcdWritestr("now time: ");    LcdWriteData(alarm_hour/16+0x30);    LcdWriteData(alarm_hour%16+0x30);    LcdWriteData(':');     LcdWriteData(alarm_min/16+0x30);    LcdWriteData(alarm_min%16+0x30);    LcdWritestr("    ");    delay_ms(500);    LcdClean();    }  else mode=DISPLAYDATA;  if(k4==0)  {
    delay(1000);   // Eliminate jitter, generally about 10ms    if(k4 ==0)   // Re-judge whether the button is pressed    {
       alarmswitch=OFF;    }
    while(k4==0);  }       }
/******************************************************************************** 函 数 名         : main*******************************************************************************/void main(void){  int ucount=0;  unsigned char lastSec;  beep= 0;  LcdInit();       // LCD initialization  //Ds1302Init();      // Clock initialization  Ds18b20Init();      // Temperature sensor initialization  SectorErase(0x2001);//  byte_write(0x2001,0x08);     // Execute initialization//  byte_write(0x2201,0x00);//  byte_write(0x2401,0x00);  alarm_hour=byte_read(0x2601);  alarm_min=byte_read(0x2201);  alarmswitch=byte_read(0x2401);
  while(1)      {    switch(mode)  // Mode selection    {      case DISPLAYDATA:    // Time display mode        Ds1302ReadTime(); // Update time        if(TIME[0] !=  lastSec)        {          lastSec = TIME[0];          display_data();      // Display time    Seconds, minutes, hours, days, months, years          displaytemp(Ds18b20ReadTemp());// Display temperature          if(alarmswitch==ON && alarm_hour==TIME[2] && alarm_min==TIME[1])  // Alarm          {            mode = ALARMCLOCK;           }        }         keypros();         // Button detection        break;      case MODIFYDATA:        // Time modification mode        modify();        break;      case SETALARMCLOCK:         // Set alarm mode        setalarmclock();        break;      case ALARMCLOCK:         // Alarm mode        alarmclock();        break;    }  }        }

This sharing comes from Huazuo Chen, if you are interested in the project, you can go to Huazuo Chen’s CSDN blog for communication, or you can add his QQ: 2809786963.

END
Graduation Project | Sharing a Basic Version of the Eternal Calendar

Graduation Project Series:

1. Temperature/Heart Rate/Step Count Design Based on STM32

2. Intelligent Automatic Light Seeking Fire Extinguishing Car

3. Simple Electronic Scale Realized with 51 Single Chip Microcontroller + HX711

4. Low-Cost STM32 IoT Portable Power Meter

5. STM32 + OV7670 Design License Plate Recognition System

6. Self-Made Mobile App with Arduino for Intelligent Monitoring and Control System

7. STM32F103 + NB Module + MQTT Implement IoT Data Collection System

8. Complete Gesture-Controlled ESP32 WIFI Electronic Photo Album in 7 Days

9. Self-Made Universal Meter, Beats 500 Yuan Regular Brand

10. Simple Blood Oxygen Heart Rate Monitor Made with STM32 + MAX30100

11. STM32 + Zigbee Networked Ordering System

12. STM32 Intelligent Trash Can Automatically Identifies Various Types of Trash

13. “Artificial” Parking Assistant Implemented Based on MCU Development Board + Camera

14. Body Sensing Gimbal Design Implemented with STM32 and MPU6050

15. A Smarter “Xiao Ai”?

16. Bionic Robot Dog Realized with STM32F4 + H7

17. Low-Cost 360° Monitoring System

18. STM32 Version RFID Medical Order Special Wristband

19. Intelligent Home System Design Controlled by STM32 Single Chip Microcontroller

20. STM32F4 Electronic Reader Production Tutorial

21. Graduation Project | Intelligent Infusion Monitoring System

22. Raspberry Pi 3B+ and OpenCV3 + PyQt5 Implement Face Recognition Access Control

23. Gesture-Controlled Dot Matrix Display Design Based on STM32

24. Learn and Apply Immediately, Share the Whole Process of Building a Fingerprint Recognition System

25. Self-Made Six-Legged Robot, Difficult, Enter with Caution

26. True Human-Machine Interaction, Cloud Intelligent Butler (My Graduation Project, My Efforts)

27. STM32 Bluetooth Smart Car (Share Code and Android APK)

28. STM32 + TI BQ76940 Design 48V BMS Scheme (Data Sharing)

29. STM32 Slope Driving Line Following Car Production Tutorial

30. Simple Fatigue Driving Detection Under 100 Yuan

31. STM32 + OneNET Implement NB-IOT Power Collection System

32. Using ARM Platform to Design Parking Lot Management System (With Tutorial & Data)

33. Intelligent WIFI LED Light Design

33. LCD Digital BOOST Circuit Design

34. STM32 Intelligent Baby Bed Monitoring (Basic Version)

35. STM32 + UART HMI, Play Minesweeper Game

36. Two-Wheeled Self-Balancing Car, Including Source Code, Schematic/PCB Source Files

37. STM32 Logistics Handling Car

38. STM32F407 Smart Car: Most Complete Functions Online, Open Source Code

39. Microcontroller Automatic Sorting Car (Loading/Unloading/WIFI Recognition)

40. Self-Balancing Robot on a Ball

41. Multifunctional IoT Smart Home Design

42. Self-Made Yogurt Machine

43. STM32F103 Full-Color FFT Music Spectrum + LED Calendar Alarm Clock Display

44. Voice Recognition Smart Home Production

45. [Open Source] Self-Made Push-Type Magnetic Levitation
46. STM32 Family Health Monitoring System
47. Wireless Smart Home System Design
48. Step-by-Step Guide to Making a Smart Home System
49. STM32 Multifunctional Atmosphere Light, Mobile APP Wireless Control WS2812, MCU Wireless Upgrade Program
Recommended Reading:

Project Sharing | Electric Competition Series | Artificial Intelligence | Postgraduate Entrance Examination

Must-Know Knowledge Points | Graduation Project | Switching Power Supply | Job Hunting

We are Nimo, the founder of Darwin, who only talks about technology and not flirting. Darwin Online Education Platform aims to serve professionals in the electronics industry, providing skill training videos covering hot topics in various subfields, such as embedded systems, FPGA, artificial intelligence, etc. It customizes hierarchical learning content for different groups, such as commonly used knowledge points, disassembly assessments, electric competitions/intelligent cars/postgraduate entrance examinations, etc. Welcome to follow.

Official website: www.darwinlearns.com
Bilibili: Darwin
QQ Group: Group 1: 786258064 (Full)
Group 2: 1057755357 (Full)
Group 3: 871373286

Graduation Project | Sharing a Basic Version of the Eternal Calendar

Leave a Comment

×