【51单片机】时光钟 - 一寸光阴一寸光

2023-10-09 19:20

本文主要是介绍【51单片机】时光钟 - 一寸光阴一寸光,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

**时间就像光一样,匆匆一撇却已远去,离去的时光怕是连光也望尘莫及。**

1.概要:有别于传统石英钟,内部不使用任何机械结构,而是全部使用电子电路。通过单片机控制发光二极管所形成的光束来指示时间。因为指针全部使用光束代替,所以在深夜也能看得很清楚,也因此可以当作“壁灯”使用。

2.原理:51单片机作为主控芯片,从DS3231时钟得到时间数据,再通过74ls38译码器输出低电平控制60个Led灯的开关。Led发光二极管安装于全透明的聚光杯中,形成的光束作为指针,通过单片机的PWM控制Led的形成长短不一的光束来区分时针、分针和秒针。HC06作为通信芯片,可连接手机的蓝牙实现对本时钟时间的修改,以及指定Led灯的亮灭(作为壁灯使用时),或者显示一些预设的动画效果,比如流水灯等。

PS:楼主由于工具所限(自己在家无聊时做的,纯手工请不要嫌弃),这里只使用12个Led做了个原型,没加蓝牙模块,只实现最核心的时间功能。

3.材料:
1. STC89C52RC
2. DS3231时钟模块
3. 12个高亮5mmLED
4. 3.7v锂电池
5. TP4056锂电池充电模块
6. 奶茶店的透明吸管

PS:根据自己的喜好选择led的颜色即可,但是注意不同波长的led形成的光束有别,有些会比较不明显。

4.51单片机程序:

#include <reg52.h>
#include <intrins.h>  
#define uchar unsigned char
#define uint unsigned int#define DS3231_WriteAddress 0xD0   
#define DS3231_ReadAddress  0xD1   
#define DS3231_SECOND       0x00    
#define DS3231_MINUTE       0x01   
#define DS3231_HOUR         0x02   
#define DS3231_WEEK         0x03   
#define DS3231_DAY          0x04   
#define DS3231_MONTH        0x05   
#define DS3231_YEAR         0x06   bit  ack;         //Ó¦´ð±ê־λ
sbit SDA = P0^6;     //Ä£ÄâI2CÊý¾Ý´«ËÍλSDA        
sbit SCL = P0^7;     //Ä£ÄâI2CʱÖÓ¿ØÖÆλSCL sbit c1 = P2^6;   //Ã룬¸öλ
sbit c2 = P2^5;   //·Ö£¬¸öλ
sbit c3 = P2^7;   //Ã룬¸öλ
sbit c4 = P2^3;   //Ã룬¸öλ
sbit c5 = P2^1;   //Ã룬ʮλ
sbit c6 = P2^0;   //Ã룬¸öλ
sbit c7 = P3^7;   //Ã룬¸öλ
sbit c8 = P3^6;   //Ã룬¸öλ
sbit c9 = P3^2;   //Ã룬ʮλ
sbit c10 = P1^5;   //·Ö£¬Ê®Î»
sbit c11 = P1^3;   //ʱ£¬¸öλ
sbit c12 = P1^2;   //ʱ£¬Ê®Î»unsigned int flag1, flag2, flag3, flag4, flag5, flag6, flag7, flag8, flag9, flag10, flag11, flag12;
unsigned char hour, minute, second;
unsigned char lastHour = 24, lastMinute = 60, lastSecond = 60;void TM1637_start();  
void TM1637_stop();  
void TM1637_write1Bit(unsigned char mBit);  
void TM1637_write1Byte(unsigned char mByte);  
void TM1637_writeCammand(unsigned char mData);  
void TM1637_writeData(unsigned char addr, unsigned char mData);  
void time_set(char hour, char min);  
void time_display();  
void timer0_init();  void setZero();
void delay_140us();  
void delayus(uint us);  uchar BCD2HEX(uchar val)    //BCDÂëת»»ÎªByte
{uchar temp;temp = val & 0x0f;val >>= 4;val &= 0x0f;val *= 10;temp += val;return temp;
}uchar HEX2BCD(uchar val)    //BÂëת»»ÎªBCDÂë
{ return (((val % 100) / 10) << 4) | (val % 10);
}void delayus(uint us) 
{while(us--);
}void Start_I2C()
{SDA = 1;                 delayus(1);SCL = 1;delayus(5);            SDA = 0;             delayus(5);          SCL = 0;                delayus(2);
}void Stop_I2C()
{SDA = 0;                 delayus(1);            SCL = 1;                 delayus(5);SDA = 1;                 delayus(4);
}void SendByte(uchar c)
{uchar BitCnt;for(BitCnt = 0;BitCnt < 8;BitCnt++)       {if((c << BitCnt) & 0x80)SDA = 1;                     else SDA = 0;               delayus(1);SCL = 1;                           delayus(5);                     SCL = 0;}delayus(2);SDA = 1;                              delayus(2);  SCL = 1;delayus(3);if(SDA == 1)ack = 0;    elseack = 1;                             SCL = 0;delayus(2);
}uchar RcvByte()
{uchar retc;uchar BitCnt;retc = 0;SDA = 1;for(BitCnt = 0;BitCnt < 8;BitCnt++){delayus(1);  SCL = 0;                      delayus(5);           SCL = 1;delayus(3);retc = retc << 1;if(SDA == 1)retc = retc + 1;           delayus(2);}SCL = 0;delayus(2);return(retc);
}void Ack_I2C(bit a)
{if(a == 0)SDA = 0;             elseSDA = 1;delayus(3);     SCL = 1;delayus(5);           SCL = 0;         delayus(2);   
}uchar write_byte(uchar addr, uchar write_data)
{Start_I2C();SendByte(DS3231_WriteAddress);if (ack == 0)return 0;SendByte(addr);   if (ack == 0)return 0;SendByte(write_data);if (ack == 0)return 0;Stop_I2C();delayus(10);return 1;
}uchar read_current()
{uchar read_data;Start_I2C();SendByte(DS3231_ReadAddress);if(ack == 0)return(0);read_data = RcvByte();Ack_I2C(1);Stop_I2C();return read_data;
}uchar read_random(uchar random_addr)
{Start_I2C();SendByte(DS3231_WriteAddress);if(ack == 0)return(0);SendByte(random_addr);if(ack == 0)return(0);return(read_current());
}/******************************************************************** 
* Ãû³Æ : delay_140us()
* ¹¦ÄÜ : ÑÓʱ
* ÊäÈë : void
* Êä³ö : ÎÞ 
**************************************************************/  
void delay_140us()  
{  int i;for(i = 0; i < 20; i++)  _nop_();  
}  
/******************************************************************** 
* Ãû³Æ : void ModifyTime(uchar hou,uchar min,uchar sec)
* ¹¦ÄÜ : ÐÞ¸Äʱ¼ä£¨È«£©
* ÊäÈë : void
* Êä³ö : ÎÞ 
**************************************************************/ 
void ModifyTime(uchar hou, uchar min,uchar sec)
{uchar temp = 0;temp = HEX2BCD(hou);write_byte(DS3231_HOUR, temp);   //ÉèÖÃʱtemp = HEX2BCD(min);write_byte(DS3231_MINUTE, temp); //ÉèÖ÷Ötemp = HEX2BCD(sec);write_byte(DS3231_SECOND, temp); //ÉèÖÃÃë
}
/******************************************************************** 
* Ãû³Æ : void ModifyTime(uchar hou,uchar min,uchar sec)
* ¹¦ÄÜ : ÐÞ¸Äʱ¼ä£¨Ê±£©
* ÊäÈë : void
* Êä³ö : ÎÞ 
**************************************************************/ 
void ModifyHour(hour)
{uchar temp = HEX2BCD(hour);write_byte(DS3231_HOUR, temp);   //ÉèÖÃʱ
}
/******************************************************************** 
* Ãû³Æ : void Modifymin(minute)
* ¹¦ÄÜ : ÐÞ¸Äʱ¼ä£¨·Ö£©
* ÊäÈë : void
* Êä³ö : ÎÞ 
**************************************************************/ 
void ModifyMinute(minute)
{   uchar temp = HEX2BCD(minute);write_byte(DS3231_MINUTE, temp); //ÉèÖÃ·Ö  
}
/******************************************************************** 
* Ãû³Æ : void ModifyTime(uchar hou,uchar min,uchar sec)
* ¹¦ÄÜ : ÐÞ¸Äʱ¼ä£¨Ã룩
* ÊäÈë : void
* Êä³ö : ÎÞ 
**************************************************************/ 
void ModifySecond(second)
{uchar temp = HEX2BCD(second);write_byte(DS3231_SECOND, temp); //ÉèÖÃÃë
}
/******************************************************************** 
* Ãû³Æ : void init() 
* ¹¦ÄÜ : ³ÌÐò³õʼ»¯
* ÊäÈë : void
* Êä³ö : ÎÞ 
**************************************************************/  
void init()
{TMOD = 0x02;TH0 = 0x06;TL0 = 0x06;TR0 = 1;ET0 = 1;EA = 1;
}
/******************************************************************** 
* Ãû³Æ : void setZero() 
* ¹¦ÄÜ : È«²¿ÇåÁ㣬ËùÓеƶ¼²»ÁÁ
* ÊäÈë : void
* Êä³ö : ÎÞ 
**************************************************************/  
void setZero()
{flag1 = 0;flag2 = 0;flag3 = 0;flag4 = 0;flag5 = 0;flag6 = 0;flag7 = 0;flag8 = 0;flag9 = 0;flag10 = 0;flag11 = 0;flag12 = 0;
}
/******************************************************************** 
* Ãû³Æ : void light(uint number, uint level)
* ¹¦ÄÜ : Ö¸¶¨µÆÁÁ
* ÊäÈë : uint number, uint level
* Êä³ö : ÎÞ 
**************************************************************/  
void light(uint number, uint level)
{switch(number){case 0:flag12 = level;break;case 1:flag1 = level;break;case 2:flag2 = level;break;case 3:flag3 = level;break;case 4:flag4 = level;break;case 5:flag5 = level;break;case 6:flag6 = level;break;case 7:flag7 = level;break;case 8:flag8 = level;break;case 9:flag9 = level;break;case 10:flag10 = level;break;case 11:flag11 = level;break;default:break;}
}
/******************************************************************** 
* Ãû³Æ : void computer_and_display_time()
* ¹¦ÄÜ : ÏÔʾʱ¼ä
* ÊäÈë : void
* Êä³ö : ÎÞ 
**************************************************************/  
void compute_and_display_time()
{//¼ÆËãʱ¼äuchar Htemp1, Htemp2, Mtemp1, Mtemp2, Stemp1, Stemp2; Htemp1 = read_random(DS3231_HOUR);    //»ñȡʱHtemp1&=0x3f;                   Htemp2 = BCD2HEX(Htemp1);Mtemp1 = read_random(DS3231_MINUTE);  //»ñÈ¡·ÖMtemp2 = BCD2HEX(Mtemp1);Stemp1 = read_random(DS3231_SECOND);  //»ñÈ¡ÃëStemp2 = BCD2HEX(Stemp1);hour = Htemp2 % 12;minute = Mtemp2 / 5;second = Stemp2 / 5;//update hourif(hour != lastHour){light(hour, 40);}//update minuteif(minute != lastMinute){if(minute != hour)light(minute, 30);}//update secondif(second != lastSecond){if(second != hour && second != minute)light(second, 1);}if(lastHour != hour && lastHour != minute && lastHour != second)light(lastHour, 0);if(lastMinute != hour && lastMinute != minute && lastMinute != second)light(lastMinute, 0);if(lastSecond != hour && lastSecond != minute && lastSecond != second)light(lastSecond, 0);lastHour = hour;lastMinute = minute;lastSecond = second;
}
/******************************************************************** 
* Ãû³Æ : timer0()
* ¹¦ÄÜ : PWMµ÷ÕûÕ¼¿Õ±È,0~10, ÁÁ¶ÈµÝ¼õ
* ÊäÈë : void
* Êä³ö : ÎÞ 
**************************************************************/  
void timer0() interrupt 1
{static unsigned int count;count++;if(count == 50){count = 0;c1 = 1;c2 = 1;c3 = 1;c4 = 1;c5 = 1;c6 = 1;c7 = 1;c8 = 1;c9 = 1;c10 = 1;c11 = 1;c12 = 1;}if(flag12 != 0 && flag12 == count)c12 = 0;else if(flag1 != 0 && flag1 == count)c1 = 0;else if(flag2 != 0 && flag2 == count)c2 = 0;else if(flag3 != 0 && flag3 == count)c3 = 0;else if(flag4 != 0 && flag4 == count)c4 = 0;else if(flag5 != 0 && flag5 == count)c5 = 0;else if(flag6 != 0 && flag6 == count)c6 = 0;else if(flag7 != 0 && flag7 == count)c7 = 0;else if(flag8 != 0 && flag8 == count)c8 = 0;else if(flag9 != 0 && flag9 == count)c9 = 0;else if(flag10 != 0 && flag10 == count)c10 = 0;else if(flag11 != 0 && flag11 == count)c11 = 0;
}
/*********************************************************** 
***** 
***** Ö÷º¯Êý
***** 
***********************************************************/
void main()
{init();setZero();
//  ModifyHour(16);
//  ModifyMinute(24);while(1){compute_and_display_time();}
}

5.焊接:(从代码里可以看出怎么接线,所以就不再赘述了。)
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

拆了个旧风扇,搞定外壳。有没有外壳其实无所谓。
这里写图片描述
这里写图片描述
这里写图片描述

6.半成品:
这里写图片描述

7.成品图:(没有工具制作合适的外壳所以只能PS假装一下)
这里写图片描述

这篇关于【51单片机】时光钟 - 一寸光阴一寸光的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/175030

相关文章

day-51 合并零之间的节点

思路 直接遍历链表即可,遇到val=0跳过,val非零则加在一起,最后返回即可 解题过程 返回链表可以有头结点,方便插入,返回head.next Code /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}*

基于51单片机的自动转向修复系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机

单片机毕业设计基于单片机的智能门禁系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍程序代码部分参考 设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订

代码训练营 Day26 | 47.排序II | 51. N-皇后 |

47.排序II 1.跟46题一样只不过加一个树层去重 class Solution(object):def backtracking(self,nums,path,result,used):# recursion stopif len(path) == len(nums):# collect our setresult.append(path[:])return for i in range(

基于stm32的河流检测系统-单片机毕业设计

文章目录 前言资料获取设计介绍功能介绍具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机设计精品

VB和51单片机串口通信讲解(只针对VB部分)

标记:该篇文章全部搬自如下网址:http://www.crystalradio.cn/thread-321839-1-1.html,谢谢啦            里面关于中文接收的部分,大家可以好好学习下,题主也在研究中................... Commport;设置或返回串口号。 SettingS:以字符串的形式设置或返回串口通信参数。 Portopen:设置或返回串口

MCU5.51单片机的最小系统

1.最小系统的组成部分 晶振电路(时钟),复位电路,电源电路(控制电压,保持稳定),下载电路(外加的,用于烧录程序) 烧录: 通过下载电路,把程序下载到单片机中用于运行 2.晶振电路 电路图: 是晶振 是电容 为了防止晶振起振时产生影响,因此加电容 3.复位电路 电路图: 按按钮RSTK1(保持一段时间的高电平)即可实现STC芯片的复位 4.电源电路 电路图:

单片机XTAL引脚引出的晶振分析

51单片机的18,19脚XTAL1,XTAL2用来提供外部振荡源给片内的时钟电路。 XTAL1和XTAL2引脚,该单片机可以使用外部时钟也可以使用内部时钟。 当使用内部时钟时,此二引线端用于外接石英晶体和微调电容; 当使用外部时钟时,用于接外部时钟信号,NMOS接XTAL2,CMOS接XTAL1。 原理: XTAL1和XTAL2分别是一个反相器的输入和输出。NMOS的反相器是

飞凌单片机开发IDE环境

飞凌单片机 资料下载选择芯片类型:MCU->GPIO选择芯片型号:FM8PE53B IDE工具安装: 资料下载 飞凌官网 选择芯片类型:MCU->GPIO 选择芯片型号:FM8PE53B IDE工具安装: 运行Generic ICE 0.02-250.03 setup,一直点击“下一步”即可。 双击运行:Generic ICE

基于51单片机的智能小车转向控制系统设计与实现

文章目录 前言资料获取设计介绍功能介绍具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机设计精品