历史上的今天
返回首页

历史上的今天

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

正在发生

2020年12月08日 | 基于单片机的带温度显示的电子钟

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,即可进入设置状态

推荐阅读

史海拾趣

GSME Electronics公司的发展小趣事

在半导体行业,技术创新是企业持续发展的关键。GSME Electronics深知这一点,不断加大研发投入,提升公司的研发实力。公司拥有一支朝气蓬勃的高素质员工团队,他们致力于新产品的开发和旧产品的升级换代。通过不断的技术创新和研发努力,GSME Electronics在半导体器件领域取得了多项技术突破,为公司的发展注入了新的动力。

Electron Products Inc公司的发展小趣事

随着产品线的不断丰富和市场竞争的加剧,EPI开始积极拓展市场,寻求更广阔的发展空间。公司制定了国际化战略,通过参加国际展会、建立海外销售渠道等方式,成功将产品打入国际市场。同时,EPI还积极与海外企业合作,共同开发新产品,拓展业务领域。

ADTech公司的发展小趣事

随着企业规模的扩大和影响力的提升,AdTech公司开始更加关注自身的社会责任和可持续发展。公司积极参与公益活动,支持教育、环保等事业,为社会的发展做出了积极贡献。同时,公司还注重环境保护和资源利用,通过采用环保材料和节能技术,降低生产过程中的能耗和排放。这些举措不仅提升了公司的社会形象,也为其实现长期可持续发展奠定了坚实基础。

这些故事是基于对AdTech公司可能发展路径的假设和推测而创作的,并不代表该公司的实际发展情况。实际上,每个公司的发展都是独特而复杂的,受到多种因素的影响。如需了解更多关于AdTech公司的真实发展情况,建议查阅相关新闻报道、行业报告或公司年报等权威资料。

动运科技(DONGWOON)公司的发展小趣事

动运科技(DONGWOON)公司,最初成立于1987年(也有资料称为1988年)的韩国首尔,是一家专注于模拟和功率驱动IC研发的半导体公司。在初创阶段,公司凭借对半导体技术的深刻理解和不懈追求,逐渐在模拟IC领域积累了技术和市场经验。通过不断的技术创新和产品优化,动运科技逐步获得了业界的认可,为其后续的发展奠定了坚实的基础。

蓝箭(BLUE ROCKET)公司的发展小趣事

蓝箭电子始终致力于技术创新和产品升级。随着科技的进步,公司不断引进先进的生产线和技术,推出了各种封装的双极型晶体管、晶闸管、集成电路等产品。这些产品广泛应用于家用电器、电源、IT数码、通信等多个领域,满足了市场的多样化需求。

思博科技(Cybermax)公司的发展小趣事

在2005年的一个阳光明媚的春天,思博科技(Cybermax)公司在硅谷正式成立。创始人李明,一位经验丰富的电子工程师,看准了当时电子市场蓬勃发展的机遇,决定创办自己的公司。起初,公司只有几名员工,主要致力于研发和生产高性能的电子元器件。通过不懈的努力和优质的产品,思博科技逐渐在市场上崭露头角。

问答坊 | AI 解惑

LM5070单芯片在太网馈电系统中的应用

以太网馈电(PoE)技术是一种利用同一条标准以太网电缆馈送电力及数据的传输技术。网络(IP)电话、闭路电视保安摄影机、无线局域网节点以至部分乐器都可通过以太网馈电系统获得供电。本文从实际应用的角度介绍以太网馈电回扫转换器的设计。这个转换器 ...…

查看全部问答>

基于数字信号处理器的IGBT驱动电路可靠性分析与设计

摘要:随着半导体技术与大规模集成电路技术的发展,数字信号处理器在交流调速及运动控制领域应用越来越广。数字信号处理器与功率器件接口电路设计的合理完善直接关系到系统长期工作的可靠性。同时,低压供电数字信号处理器也对驱动接口电路设计提出 ...…

查看全部问答>

嵌入式

我的本科专业是电子专业,现在上研学的是计算机应用专业的嵌入式方向。专业知识学得浅,不知何去何从,请问女生在嵌入式方面该往哪方面发展相对会好些呢?实在是很茫然,请各位前辈给点建议,感激不尽!…

查看全部问答>

生成的nb0文件拷到开发板中去,没有效果,

刚开始接触WinCE,很多地方不懂,在这里碰到了一个问题。 手上有一个开发板,S3C2440A,K9F1208U0B的。 然后有一个文档,Installation Manual for S3C2440A(Windows CE 5.0).pdf。 还有一个文件夹PLATFORM,PUBLIC两个文件,里面的文件什么的都 ...…

查看全部问答>

通过DM9000C无法下载NK

平台 6410+CE6.0 用DM9000A网络可以正常NK,用DM9000C不可以,提示如下信息: DM9000 ID is 0x90000a46 INFO: Probe: DM9000 is detected. DM9000: MAC Address: 0:11:22:33:44:55 System ready! Preparing for download... INFO: *** Devic ...…

查看全部问答>

请问谁有LPC2478的小程序,我买的开发板晶振不起振,我不知道怎么办了

请问谁有LPC2478的小程序,我买的开发板晶振不起振,请问谁有小程序吗,我不知道是设置问题还是板子的问题…

查看全部问答>

C64x 网络培训(二) - TMS320C64x+存储系统

TMS320C64x+网络课程2——存储系统,其中包括:存储控制器,缓存特异性, Internal DMA。此网络培训针对C64x+,每次一个专题,此视频由DSP高性能部门技术支持工程师为您全程指导,敬请期待。   $(\'swf_EPZ\').innerHTML=AC_FL_RunContent(\'w ...…

查看全部问答>

紧急求助

哪位大神可以给一个基于magal16的电子密码锁的程序或者频率发生器的程序,多谢了。…

查看全部问答>

使用软件搭环境的一个问题

新手,听人说用单片机先要搭建环境。可是没有明白怎么个搭法。 比如KEIL51的话,会用会建工程不就行了吗?还要懂什么?…

查看全部问答>

JTAG出错了!

前提:测试example_canCommunication.c例程 短路CAN1,CAN2 居然会出现这个错误! 然后想用TMS570LS31USB测试CAN1发送数据,更郁闷的是JTAG就一直不能连接上了! 但是测试TMS570LS3137.ccxml 中“ Test Connection ” 还可以的! [Start] ...…

查看全部问答>