历史上的今天
返回首页

历史上的今天

今天是:2024年08月27日(星期二)

正在发生

2020年08月27日 | 用普中开发板做的51单片机的智能时钟具有闹钟功能

2020-08-27 来源:51hei

本贴针对学完单片机并且有读懂代码的非新手同学。本人目前放寒假,这个是本人在上个学期的单片机课上要求做的综合实验,现在重新修改了下增加了菜单目前测试毫无问题可以完美使用。有志向做闹钟的同学可以参考一下,原码上由本人写的大量注释可以方便看懂。

使用了LCD1602、DS1302、DS18B20用来测试温度、内部含闹钟系统但本人没有做EEPROM有需要的同学可以自行添加。


单片机源程序如下:

#include

#include

#include

#include

#include

#include


#define normal 0//正常显示时钟界面

#define settime 1//设定时钟界面

#define setalarm 2//设定闹钟界面

#define displayalarm 3//显示闹钟界面

#define normal_12 4//显示十二小时制界面

#define caidan 5


unsigned char system=normal;//我一开始就把界面切换为正常显示时钟界面


extern unsigned char i,k;


extern unsigned int code song[3][300];


unsigned char code *week[8]={"NO ","Mon ","Tue ","Wed ","Thu ","Fri ","Sat ","Sun "};


unsigned char code *clockzifu[4]={"ON ","OFF ","REP ","NRE "};


struct Time timeset={0x18,0x01,0x16,0x14,0x30,0x50,0x03};


//第一个闹钟

//第二个闹钟

//第三个闹钟

//第四个闹钟

//第五个闹钟

struct alarmtime xdata clock[5]={{1,16,14,31,0,1,0,1},{1,8,14,32,3,0,0,0},{1,7,18,49,1,1,1,0},{0,0,0,0,0,0,1,0},{1,25,0,0,0,0,1,2}};


unsigned char alarmnum;//闹钟


unsigned char a;


unsigned char flag=0;


unsigned char xinghao=0;


unsigned char tentoBCD(unsigned char dat)//十进制转换为BCD码函数

{

        unsigned char dat1,dat2;

        dat1=dat/10;

        dat2=dat%10;

        dat2=dat2+dat1*16;

        return dat2;

}


unsigned char BCDtoten(unsigned char dat)//BCD码转为十进制函数

{

        unsigned char dat1,dat2;

        dat1=dat/16;

        dat2=dat%16;

        dat2=dat2+dat1*10;

        return dat2;

}


void DS18B20deal(int temp)//DS18B20数据处理函数 显示温度更新温度         

{

    //先判断温度值是否大于0或小于0等于0

           float tp;//保存的数据可能带小数  

        if(temp<0)//当温度值为负数

          {

                LCD1602_writechar(9,1,0x2D);//ASCII码中的-符号

                temp=temp-1;//因为读取的温度是实际温度的补码,所以减1,再取反求出原码

                temp=~temp;//还原读取的数据

                tp=temp;//保存到变量里面

                temp=tp*0.0625*100+0.5;//强制转换成一个整形的数据.留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就算加上0.5,还是在小数点后面。       

          }

        else//当温度值为正数

          {                       

                LCD1602_writechar(9,1,0x20);//ASCII码中的空格

                tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量。如果温度是正的那么,那么正数的原码就是补码它本身

                temp=tp*0.0625*100+0.5;//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点。后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就算加上0.5,还是在小数点后面。       

        }

        LCD1602_writechar(10,1,temp/10000+'0');//温度百位

        LCD1602_writechar(11,1,temp%10000/1000+'0');//温度十位

        LCD1602_writechar(12,1,temp%1000/100+'0');//温度个位

    LCD1602_writechar(13,1,0x2E);//ASCII码小数点

        LCD1602_writechar(14,1,temp%100/10+'0');//小数点后一位

        LCD1602_writechar(15,1,temp%10+'0');//小数点后两位

}


void updatetime()//更新时钟上的时间

{

        unsigned char time[9];//存储变量

        DS1302_gettime(×et);//读取时间

        time[0]=BCDtoten(timeset.hour)/10+'0';//小时的十位

        time[1]=BCDtoten(timeset.hour)%10+'0';//小时的个位

        time[2]=':';

        time[3]=BCDtoten(timeset.min)/10+'0';//分的十位

        time[4]=BCDtoten(timeset.min)%10+'0';//分的个位

        time[5]=':';

        time[6]=BCDtoten(timeset.sec)/10+'0';//秒的十位

        time[7]=BCDtoten(timeset.sec)%10+'0';//秒的个位

        time[8]='';//字符串结束标志


        LCD1602_writestr(0,1,time);//在LCD上面打印时间

}


void updatetime_12()//更新十二小时制界面的时间

{

        unsigned char time[9];

        DS1302_gettime(×et);//读取时间

        time[0]= BCDtoten(timeset.hour)%12/10+'0';//小时的十位

        time[1]= BCDtoten(timeset.hour)%12%10+'0';//小时的个位

        time[2]=':';

        time[3]= BCDtoten(timeset.min)/10+'0';//分的十位

        time[4]= BCDtoten(timeset.min)%10+'0';//分的个位

        time[5]=':';

        time[6]= BCDtoten(timeset.sec)/10+'0';//秒的十位

        time[7]= BCDtoten(timeset.sec)%10+'0';//秒的个位

        time[8]='';//字符串结束标志                                                                                                                                                                                                               

        LCD1602_writestr(3,1,"TIME:");//打印出TIME的字符串

        LCD1602_writestr(8,1,time);//在第二行第四列显示时间

        if(BCDtoten(timeset.hour)>12)//要是小时大于12时

        {

          LCD1602_writestr(0,1,"PM");//则显示PM

        }

        else//小时不大于12

        {

          LCD1602_writestr(0,1,"AM");//则显示AM

        }  

}


void updatedate()//更新日历

{

        unsigned char date[12];

        date[0]= '2';

        date[1]= '0';

        date[2]= BCDtoten(timeset.year)/10%10+'0';//年的十位

        date[3]= BCDtoten(timeset.year)%10+'0';//年的个位

        date[4]='.';

        date[5]= BCDtoten(timeset.mon)/10+'0';//月的十位

        date[6]= BCDtoten(timeset.mon)%10+'0';//月的个位

        date[7]='.';

        date[8]= BCDtoten(timeset.day)/10+'0';//日的十位

        date[9]= BCDtoten(timeset.day)%10+'0';//日的个位

        date[10]='';

        LCD1602_writestr(0,0,date);//显示年月日

        LCD1602_writestr(11,0,week[timeset.week]);//显示星期

}


void updatealarm()//更新闹钟设定值

{

        unsigned char str0[14];

        unsigned char str1[2];


        str0[0]=alarmnum+'0';

        str0[1]=' ';

        str0[2]=clock[alarmnum].mon/10+'0';//月份十位

        str0[3]=clock[alarmnum].mon%10+'0';//月份个位

        str0[4]='-';

        str0[5]=clock[alarmnum].day/10+'0';//日期十位

        str0[6]=clock[alarmnum].day%10+'0';//日期个位

        str0[7]=' ';

        str0[8]=clock[alarmnum].hour/10+'0';//小时十位

        str0[9]=clock[alarmnum].hour%10+'0';//小时个位

        str0[10]=':';

        str0[11]=clock[alarmnum].min/10+'0';//分钟十位

        str0[12]=clock[alarmnum].min%10+'0';//分钟个位

        str0[13]='';


        LCD1602_writestr(0,1,str0);


        str1[0]=clock[alarmnum].music+'0';//铃声

        str1[1]='';


        LCD1602_writestr(0,0,"U");

        LCD1602_writestr(1,0,str1);//显示铃声

        LCD1602_writestr(3,0,clockzifu[clock[alarmnum].alarmre+2]);//显示重不重复

        LCD1602_writestr(7,0,week[clock[alarmnum].week]);//显示星期

        LCD1602_writestr(11,0,clockzifu[clock[alarmnum].alarmon]);//显示开关       

}


void anjian4();


void anjian1()

{

  if(system==normal)

  {

    system=caidan;

        xinghao=0;

        LCD1602_clear();

        LCD1602_writechar(0,0,'*');

        LCD1602_writestr(1,0,"12");

        LCD1602_writestr(1,1,"alarm");

        LCD1602_writestr(8,0,"setclock");

        LCD1602_writestr(8,1,"setalarm");

  }

  else if(system==caidan&&xinghao==0)

  {

    system=normal_12;//切换到12小时制

        LCD1602_clear();//清屏

        updatetime_12();//显示12小时制的时间

        updatedate();//显示日期

  }

  else if(system==caidan&&xinghao==1)

  {

推荐阅读

史海拾趣

AKM [Asahi Kasei Microsystems]公司的发展小趣事
  1. 成立与发展: Asahi Kasei Microsystems(AKM)成立于1983年,是日本旭化成集团旗下的一家子公司,总部位于东京。该公司主要致力于集成电路和半导体解决方案的研发和生产。AKM的创始目标是为市场提供高质量、高性能的模拟芯片和数字芯片,以满足消费电子、通信、汽车和工业等行业的需求。

  2. 产品创新: AKM在模拟和数字领域取得了一系列创新成果。其中,其声音处理技术尤为突出,涵盖了高保真音频、语音识别和声音传感器等领域。AKM的音频解决方案在高端音响、耳机、智能手机和汽车音响系统中得到广泛应用,为用户带来出色的听觉体验。

  3. 市场扩展: 随着技术的不断创新和产品线的拓展,AKM逐渐在全球范围内建立了广泛的客户群体。除了日本市场外,其产品远销亚洲、欧洲和美洲等地区。AKM的产品在全球范围内备受认可,并赢得了众多合作伙伴的信任与支持。

  4. 技术合作: 为了保持在市场上的竞争优势,AKM积极寻求与其他公司和机构的技术合作。通过与声学专家、电子设备制造商和汽车制造商等行业领先企业的合作,AKM不断吸收和借鉴先进的技术理念,推动产品创新和技术进步。

  5. 未来展望: 面对日益激烈的市场竞争和技术变革,AKM将继续加强研发投入,不断提升产品质量和技术水平。同时,AKM将积极应对全球经济形势和市场需求的变化,拓展新的业务领域,为客户提供更加全面和专业的解决方案。

Antelec公司的发展小趣事

在电子行业竞争日益激烈的环境下,Antelec公司深知持续创新的重要性。公司不断加大研发投入,引进先进的研发设备和人才,推动技术升级和产品创新。同时,公司还积极关注行业发展趋势和客户需求变化,及时调整产品策略和市场布局,保持了在市场中的领先地位。

BOCA公司的发展小趣事

为了进一步提升竞争力,BOCA公司开始尝试产业链整合。公司不仅加强了对上游原材料供应商的控制,还通过并购和合作的方式,将下游的组装、销售等环节也纳入自己的体系。这一举措使得BOCA能够更好地控制产品质量和交货期,同时也降低了成本,提高了整体运营效率。

Cantec Electronic Co Ltd公司的发展小趣事

为了进一步提升自身的竞争力,Cantec Electronic Co Ltd积极寻求与国际知名企业的合作。经过多次洽谈,公司成功与一家国际电子巨头签订了战略合作协议。通过技术共享和市场互通,公司的产品线得到了极大的丰富,同时也打开了国际市场的大门。这一合作不仅提升了公司的品牌知名度,也为公司的长远发展奠定了坚实的基础。

Gravitech公司的发展小趣事

为了进一步提升自身的竞争力,Cantec Electronic Co Ltd积极寻求与国际知名企业的合作。经过多次洽谈,公司成功与一家国际电子巨头签订了战略合作协议。通过技术共享和市场互通,公司的产品线得到了极大的丰富,同时也打开了国际市场的大门。这一合作不仅提升了公司的品牌知名度,也为公司的长远发展奠定了坚实的基础。

超霸(GP)公司的发展小趣事

绿索超容深知品质是企业生存的根本。因此,公司从原材料采购到生产制造,再到成品检验,都实施了严格的质量控制措施。此外,公司还通过了ISO9001体系认证,进一步提升了其产品质量管理水平。这些努力不仅保证了绿索超容产品的优良品质,也为其赢得了客户的信任和好评。

问答坊 | AI 解惑

PB安装后定制内核出现得问题,请教高人!

请问我得PB装好了后,安装了2440的BSP包,为什么定制内核时没有sysgen选项啊。build os里都没白色。但我用x86定制内核却有sysgen选项。高手请指导下啊…

查看全部问答>

电气专业学嵌入式开发适合么?

我是电气工程及其自动化专业的,今年大三,现在想学嵌入式开发,以后搞硬件层或驱动层,请问电气专业学嵌入式是不是偏离了本专业的发展方向?能将嵌入式学好么?请各位前辈和高手指导。…

查看全部问答>

关于STC12C5A60S2的AD基准电压怎么设置?

手册上面说在P1.7口接一个1.25V的电压,然后可以计算出其他口的电压,不怎么明白…

查看全部问答>

【转帖】详述linux-2.6.33内核在飞凌2440开发板的移植

本文转引自飞凌BBS:http://bbs.witech.com.cn/thread-468-1-1.html 宿主机:ubuntu9.04 目标机:飞凌OK2440开发板 交叉编译器:arm-linux-gcc-3.4.1 交叉编译器路径:/usr/local/arm/3.4.1 要移植的内核版本:linux-2.6.33 文件系统类型: y ...…

查看全部问答>

关于sim卡的基本问题!

有两个问题要请教: 1 sim卡都用到了哪些gsm协议规范? 2 我现在做的项目是读sim卡的信息,就是给sim发送ADPU命令包,但是我不知道sim卡的存储格式,比如我要读电话本,应当怎么做?这方面的资料去哪里找?…

查看全部问答>

请教 chenbing 长老,关于写到 Flash中运行的程序

本帖最后由 dontium 于 2015-1-23 13:20 编辑 Chenbing 长老: 我用 DSP 2407A  也有一段时间了.但是由于以前手中只有孤零零的一块开发板,生怕弄坏了,断了炊,所以自己写的程序都是 Load 到扩展RAM 中运行,没有写入Flash.做过几次写 Fla ...…

查看全部问答>

有人做过MCU51单片机uIP协议栈+ENC28J60网卡实现tcp协议通讯的大大吗?

如题    在淘宝店家买回ENC28J60 以太网模块http://item.taobao.com/item.htm?scm=1007.77.0.0&id=10390385522&ad_id=&am_id=&cm_id=&pm_id=想做tcp协议的温湿度的传递,采集方面已完成。买回模块以后,对这个uIP协议栈不了解 ...…

查看全部问答>

F1232串口中断接收

通过串口接收一包数据(5字节),结果总出差,如果一个一个接收就正常,代码:1.485初始化void init485(void){ UCTL0 = CHAR;                         // 8-bit character  ...…

查看全部问答>

怎样计量ADE7753有用功的能量

用ADE7753来计量有用功,即负载消耗的能量,但不知怎么才能获得,负载消耗的能量。非常感谢大家的帮助!…

查看全部问答>

晒WEBENCH设计的过程+LED 台灯电路设计

1,打开webench 2,注意参数,提交设计 3,方案生成 4,查看原理图 …

查看全部问答>