基于单片机的带温度显示的电子钟

发布者:BlissfulBliss最新更新时间:2020-12-08 来源: 51hei关键字:单片机  电子钟 手机看文章 扫描二维码
随时随地手机看文章

单片机源程序如下:

/*

*******************************************************************************

*                     《手把手教你学51单片机(C语言版)》

*                    配套 KST-51 单片机开发板 示例源代码

*

* 文件名:main.c

* 描  述:第16章 作业题4 带温度显示的电子钟

* 版本号:v1.0.0

* 备  注:在lesson15_3基础上添加温度,温度显示在第二行右端,原时间位置相应左移

*******************************************************************************

*/


#include


struct sTime {  //日期时间结构体定义

    unsigned int  year;

    unsigned char mon;

    unsigned char day;

    unsigned char hour;

    unsigned char min;

    unsigned char sec;

    unsigned char week;

};


bit flag1s = 0;  //1s定时标志

bit flag200ms = 1;  //200ms定时标志

struct sTime bufTime;  //日期时间缓冲区

unsigned char setIndex = 0;  //时间设置索引

unsigned char T0RH = 0;  //T0重载值的高字节

unsigned char T0RL = 0;  //T0重载值的低字节


void ConfigTimer0(unsigned int ms);

void RefreshTimeShow();

void GetShowTemp();

extern void InitDS1302();

extern void GetRealTime(struct sTime *time);

extern void SetRealTime(struct sTime *time);

extern void KeyScan();

extern void KeyDriver();

extern void InitLcd1602();

extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);

extern void LcdSetCursor(unsigned char x, unsigned char y);

extern void LcdOpenCursor();

extern void LcdCloseCursor();

extern bit Start18B20();

extern bit Get18B20Temp(int *temp);


void main()

{

    unsigned char psec=0xAA;  //秒备份,初值AA确保首次读取时间后会刷新显示


    EA = 1;           //开总中断

    ConfigTimer0(1);  //T0定时1ms

    Start18B20();     //启动DS18B20

    InitDS1302();     //初始化实时时钟

    InitLcd1602();    //初始化液晶

   

    //初始化屏幕上固定不变的内容

    LcdShowStr(3, 0, "20  -  -  ");

    LcdShowStr(1, 1, "  :  :    --`C");

   

    while (1)

    {

        KeyDriver();  //调用按键驱动

        if (flag200ms && (setIndex == 0))

        {                             //每隔200ms且未处于设置状态时,

            flag200ms = 0;

            GetRealTime(&bufTime);    //获取当前时间

            if (psec != bufTime.sec)  //检测到时间有变化时刷新显示

            {

                RefreshTimeShow();

                psec = bufTime.sec;   //用当前值更新上次秒数

            }

        }

        if (flag1s && (setIndex == 0))  //每隔1s读取并显示温度

        {

            flag1s = 0;

            GetShowTemp();

        }

    }

}

/* 将一个BCD码字节显示到屏幕上,(x,y)-屏幕起始坐标,bcd-待显示BCD码 */

void ShowBcdByte(unsigned char x, unsigned char y, unsigned char bcd)

{

    unsigned char str[4];

   

    str[0] = (bcd >> 4) + '0';

    str[1] = (bcd&0x0F) + '0';

    str[2] = '';

    LcdShowStr(x, y, str);

}

/* 获取并显示温度 */

void GetShowTemp()

{

    int temp;

    unsigned char str[4];

   

    if (Get18B20Temp(&temp))  //读取当前温度并判断是否成功

    {   //读取成功时,刷新当前温度显示

        temp >>= 4;  //右移4位以舍弃小数位

        str[0] = temp/10 + '0';  //显示为两位十进制数字

        str[1] = temp%10 + '0';

        str[2] = '';

        LcdShowStr(11, 1, str);

    }

    else

    {   //读取失败时,提示错误信息

        LcdShowStr(11, 1, "--");

    }

    Start18B20();  //重新启动下一次转换

}

/* 刷新日期时间的显示 */

void RefreshTimeShow()

{

    ShowBcdByte(5,  0, bufTime.year);

    ShowBcdByte(8,  0, bufTime.mon);

    ShowBcdByte(11, 0, bufTime.day);

    ShowBcdByte(1,  1, bufTime.hour);

    ShowBcdByte(4,  1, bufTime.min);

    ShowBcdByte(7,  1, bufTime.sec);

}

/* 刷新当前设置位的光标指示 */

void RefreshSetShow()

{

    switch (setIndex)

    {

        case 1:  LcdSetCursor(5,  0); break;

        case 2:  LcdSetCursor(6,  0); break;

        case 3:  LcdSetCursor(8,  0); break;

        case 4:  LcdSetCursor(9,  0); break;

        case 5:  LcdSetCursor(11, 0); break;

        case 6:  LcdSetCursor(12, 0); break;

        case 7:  LcdSetCursor(1,  1); break;

        case 8:  LcdSetCursor(2,  1); break;

        case 9:  LcdSetCursor(4,  1); break;

        case 10: LcdSetCursor(5,  1); break;

        case 11: LcdSetCursor(7,  1); break;

        case 12: LcdSetCursor(8,  1); break;

        default:  break;

    }

}

/* 递增一个BCD码的高位 */

unsigned char IncBcdHigh(unsigned char bcd)

{

    if ((bcd&0xF0) < 0x90)

        bcd += 0x10;

    else

        bcd &= 0x0F;

   

    return bcd;

}

/* 递增一个BCD码的低位 */

unsigned char IncBcdLow(unsigned char bcd)

{

    if ((bcd&0x0F) < 0x09)

        bcd += 0x01;

    else

        bcd &= 0xF0;

   

    return bcd;

}

/* 递减一个BCD码的高位 */

unsigned char DecBcdHigh(unsigned char bcd)

{

    if ((bcd&0xF0) > 0x00)

        bcd -= 0x10;

    else

        bcd |= 0x90;

   

    return bcd;

}

/* 递减一个BCD码的低位 */

unsigned char DecBcdLow(unsigned char bcd)

{

    if ((bcd&0x0F) > 0x00)

        bcd -= 0x01;

    else

        bcd |= 0x09;

   

    return bcd;

}

/* 递增时间当前设置位的值 */

void IncSetTime()

{

    switch (setIndex)

    {

        case 1:  bufTime.year = IncBcdHigh(bufTime.year); break;

        case 2:  bufTime.year = IncBcdLow(bufTime.year);  break;

        case 3:  bufTime.mon  = IncBcdHigh(bufTime.mon);  break;

        case 4:  bufTime.mon  = IncBcdLow(bufTime.mon);   break;

        case 5:  bufTime.day  = IncBcdHigh(bufTime.day);  break;

        case 6:  bufTime.day  = IncBcdLow(bufTime.day);   break;

        case 7:  bufTime.hour = IncBcdHigh(bufTime.hour); break;

        case 8:  bufTime.hour = IncBcdLow(bufTime.hour);  break;

        case 9:  bufTime.min  = IncBcdHigh(bufTime.min);  break;

        case 10: bufTime.min  = IncBcdLow(bufTime.min);   break;

        case 11: bufTime.sec  = IncBcdHigh(bufTime.sec);  break;

        case 12: bufTime.sec  = IncBcdLow(bufTime.sec);   break;

        default:  break;

    }

    RefreshTimeShow();

    RefreshSetShow();

}

/* 递减时间当前设置位的值 */

void DecSetTime()

{

    switch (setIndex)

    {

        case 1:  bufTime.year = DecBcdHigh(bufTime.year); break;

        case 2:  bufTime.year = DecBcdLow(bufTime.year);  break;

        case 3:  bufTime.mon  = DecBcdHigh(bufTime.mon);  break;

        case 4:  bufTime.mon  = DecBcdLow(bufTime.mon);   break;

        case 5:  bufTime.day  = DecBcdHigh(bufTime.day);  break;

        case 6:  bufTime.day  = DecBcdLow(bufTime.day);   break;

        case 7:  bufTime.hour = DecBcdHigh(bufTime.hour); break;

        case 8:  bufTime.hour = DecBcdLow(bufTime.hour);  break;

        case 9:  bufTime.min  = DecBcdHigh(bufTime.min);  break;

        case 10: bufTime.min  = DecBcdLow(bufTime.min);   break;

        case 11: bufTime.sec  = DecBcdHigh(bufTime.sec);  break;

        case 12: bufTime.sec  = DecBcdLow(bufTime.sec);   break;

        default:  break;

    }

    RefreshTimeShow();

    RefreshSetShow();

}

/* 右移时间设置位 */

void RightShiftTimeSet()

{

    if (setIndex != 0)

    {

        if (setIndex < 12)

            setIndex++;

        else

            setIndex = 1;

        RefreshSetShow();

    }

}

/* 左移时间设置位 */

void LeftShiftTimeSet()

{

    if (setIndex != 0)

    {

        if (setIndex > 1)

            setIndex--;

        else

            setIndex = 12;

        RefreshSetShow();

    }

}

/* 进入时间设置状态 */

void EnterTimeSet()

{

    setIndex = 2;       //把设置索引设置为2,即可进入设置状态

[1] [2]
关键字:单片机  电子钟 引用地址:基于单片机的带温度显示的电子钟

上一篇:基于51单片机+12864液晶显示屏的贪吃蛇游戏
下一篇:基于51单片机的可调数字时钟程序

推荐阅读最新更新时间:2024-11-02 08:16

51单片机在晶闸管触发电路中的应用
本文介绍一种由8031单片机组成的触发控制系统,可实现高分辨率的数字触发。在常规控制中,主要是用电子控制装置对可控硅实现触发,这种方法由于受到电子元器件的限制,其分辨率不高,有时还会出现误触发。 在电力拖动系统、电炉控制系统中现已大量采用可控硅(晶闸管)元件作为可调电源向电动机或电炉供电,这种由晶闸管组成的控制系统,主要是利用改变可控硅的控制角θ来调节供电电压。 1 硬件组成及原理    系统硬件组成如图1,只须在8031最小系统上加一块16位的定时/计数器8253和晶振电路,另加一块带一个14位定时/计数器的可编程RAM/IO扩展器8155,即可组成单片机的系统线路。 1.1 θ角定时    控制角θ是滞
[单片机]
51<font color='red'>单片机</font>在晶闸管触发电路中的应用
数码管电子钟
主要元器件:89C52RC,74HL138,四位数码管两个,独立按钮三个,排线,杜邦线 原理:利用定时计数器定时50ms,每20次为一秒,产生一次中断,在中断函数中,对秒数加一,当秒数加满60后清零,分数加一,同理可得分数和时数直接安定关系。数码管的显示采用动态扫描法,至于如何对按键进行实时响应,参考程序部分。 说明:由于本程序软件部分既不是很复杂也不是很简单,故采用C51编写,硬件原理图暂缺。软件部分如下,本程序仅供QQ好友中从事嵌入式工作的叔叔和大哥们参考,修改。 结语:向广大大哥大叔们表示感谢,在此也多谢导师的指引,青见一定不负所望,仰望星空,脚踏实地,五月份本人事情较多,估计没有时间和你们讨论一些问题,期待我们暑假的大飞
[单片机]
STM32 系列MCU 不同型号的移植步骤解析
STM32 系列MCU 不同型号的移植! 第一步 更换启动文件: 第二步 修改宏定义: 图 1 或者修改stm32f10x.h 具体修改如下: 图2 第三步 修改系统主频率: 文件:system_stm32f10x.c 具体修改如下: 图 3 第四步 修改外部晶振源: 文件:stm32f10x.h 具体修改如下: 图 4 第五步 定时器需要根据以上修改的系统主频率进行对应的修改。 其他: 修改 Flash 地址 文件:misc.h 具体修改如下: 图 5 与以下配置一致: IAP 设置步骤 一、 IAP 工程设置 1、修改main 中的按键触发键 2、修改下载串口 二、 下载工程设置 1、修改程序入
[单片机]
STM32 系列<font color='red'>MCU</font> 不同型号的移植步骤解析
一种基于单片机的新型线阵CCD电路
引言   不同厂家、不同型号的CCD的驱动时序是不同的,加之对不同性能、不同应用场合的体积、成本、灵活性要求不同,于是产生了众多的驱动时序的产生方法,主要有直接数字电路驱动、单片机口驱动、EPROM驱动、专用IC驱动等常用的驱动时序的产生方法。但是它们存在着逻辑设计较为复杂、调试困难、柔性较差、驱动时钟低等缺点。   本文在综合各种驱动时序方法的基础上,提出了的一种基于单片机的新型驱动电路。该电路使用独立的时钟源产生精确的时钟脉冲,采用可编程定时计数芯片和单片机控制相结合的方法,使电路产生稳定、精确、高速的驱动脉冲,该电路结构简单、调试方便、CPU占用率低,降低了系统的总体成本,而且具有良好的柔性,只需要改变驱动软件就可以应用于不
[单片机]
51单片机UART通信发送接收数字字母中文,控制LED亮灭
1、发送什么就接收什么 /* 工程创建MCU选取,Atmel 89C55 单片机:STC12C5A60S2 晶振:12M 功能:串口的应用 波特率:4800 8 无 1 无 */ #include REG51.h // 可以使用通用的头文件 //串口中断初始化程序 void UART_init(void){ EA=1; //打开总中断【定时器,ADC,串口,比较,计数,外部】等中断类型 ES=1;//允许串口的中断 TMOD=0x20; // 定时器1 T/C1工作方式,用来产生串口工作频率 SCON=0x50; // 串口工作方式1 TH1=0xF3; // 定时器初始值高8位的设置,查表得频率 TL1=0xF3; //
[单片机]
51<font color='red'>单片机</font>UART通信发送接收数字字母中文,控制LED亮灭
基于单片机的CPLD/FPGA被动串行下载配置的实现
1引言 随着电子技术的发展,当前数字系统的设计正朝着速度快、容量大、体积小、重量轻的方向发展。推动该潮流迅猛发展的引擎就是日趋进步和完善的高密度现场可编程逻辑器件设计技术。高密度现场可编程逻辑器件(CPLD/FPGA)能够将大量逻辑功能集成于一个单片IC之中,对基于E2PROM(或Flash Memory)工艺的器件,配置数据在掉电后不会丢失,可以直接采用ByteBlaster并口下载电缆对他们进行配置,但基于该架构的器件的集成度较低,一般在10万门以下;然而对基于SRAM工艺的器件,配置数据在器件掉电后会丢失,但基于该架构的器件的集成度相对较高,一般在1万门以上。 由于当前项目开发中所需使用的可编程逻辑器件的集成度
[单片机]
基于<font color='red'>单片机</font>的CPLD/FPGA被动串行下载配置的实现
汽车MCU率先成为荣获ISO 26262功能安全标准认证
思卡尔半导体(NYSE:FSL)正致力于帮助汽车电子器件供应商更轻松地开发符合国际标准化组织(ISO)26262标准的功能安全系统。飞思卡尔日前宣布其Qorivva MPC5643L 32位微控制器(MCU)通过了独立的权威认证机构exida的认证,成为业界首个获得该认证的半导体产品。   Qorivva MPC5643L 32位MCU基于Power Architecture技术,专为要求汽车安全完整性等级较高的一系列广泛汽车应用而设计,包括电动助力转向、主动悬挂、防抱死制动系统和基于雷达的高级驾驶辅助系统(ADAS)。它符合所有汽车安全完整性等级(ASIL),达到并满足最严格的等级ASIL D。 MPC5643L MCU
[嵌入式]
日立SH3单片机最小系统的建立
0 引言     SH系列是日本日立公司推出的32位高档的、RISC型单片机系列,到现在为止,已经推出了6种类型的单片机系列:基本型的SH1,改进型的SH2,低功耗的SH3,增强型的SH4,以及和DSP结合的SH2-DSP和SH3-DSP。     SH3系列是低功耗型SH处理器,高性能RISC结构,在时钟133 MHz时,性能可以达到173 MIPS。在2.25 V工作时,功耗为400 mW。SH3的SH7709,其消耗功率每瓦运行的指令数达到315 MIPS,能源利用效率很高。它内部集成了32位乘法器、4路8 KB CHACHE、存储器管理单元MMU、一些通用内部控制模块和外部接口模块。其性能可以与ARM公司的ARM9系列处理器
[单片机]
日立SH3<font color='red'>单片机</font>最小系统的建立
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved