请求高手帮忙(懂单片机的)

liming66   2010-3-17 20:45 楼主
(单片机)设计一种适用于家庭的多功能数字钟,要求能显示小时、分;时间显示有两种方式,12小时制和24小时制;能够随时对当前时间进行调整;能够随时输入闹铃时间,闹铃时间到发出闹铃提醒信号;能够显示当前温度;走时准确,使用方便。

回复评论 (10)

基于DS18B20的数字温度计设计

#include "DigThermo.h"

/* 延时t毫秒 */
void delay(uint t)
{
        uint i;
        while(t--)
        {
                /* 对于11.0592M时钟,约延时1ms */
                for (i=0;i<125;i++)
                {}
        }
}

/* 产生复位脉冲初始化DS18B20 */
void TxReset(void)
{
        uint i;
        DQ = 0;

        /* 拉低约900us */
        i = 100;
        while (i>0)        i--;       
       
        DQ = 1;                                // 产生上升沿
        i = 4;
        while (i>0)        i--;
}

/* 等待应答脉冲 */
void RxWait(void)
{
        uint i;
        while(DQ);
        while(~DQ);                        // 检测到应答脉冲
        i = 4;
        while (i>0)        i--;
}

/* 读取数据的一位,满足读时隙要求 */
bit RdBit(void)
{
        uint i;
        bit b;
        DQ = 0;
        i++;
        DQ = 1;
        i++;i++;                        // 延时15us以上,读时隙下降沿后15us,DS18B20输出数据才有效
        b = DQ;
        i = 8;
        while(i>0) i--;
        return (b);
}

/* 读取数据的一个字节 */
uchar RdByte(void)
{
        uchar i,j,b;
        b = 0;
        for (i=1;i<=8;i++)
        {
                j = RdBit();
                b = (j<<7)|(b>>1);
        }
        return(b);
}

/* 写数据的一个字节,满足写1和写0的时隙要求 */
void WrByte(uchar b)
{
        uint i;
        uchar j;
        bit btmp;
        for(j=1;j<=8;j++)
        {
                btmp = b&0x01;
                b = b>>1;                // 取下一位(由低位向高位)
                if (btmp)
                {
                        /* 写1 */
                        DQ = 0;
                        i++;i++;        // 延时,使得15us以内拉高
                        DQ = 1;
                        i = 8;
                        while(i>0) i--;        // 整个写1时隙不低于60us
                   }
                else
                {
                        /* 写0 */
                        DQ = 0;                       
                        i = 8;
                        while(i>0) i--;        // 保持低在60us到120us之间
                        DQ = 1;
                        i++;
                        i++;
                }
        }
}

/* 启动温度转换 */
void convert(void)
{
        TxReset();                        // 产生复位脉冲,初始化DS18B20
        RxWait();                        // 等待DS18B20给出应答脉冲
        delay(1);                        // 延时
        WrByte(0xcc);                // skip rom 命令
        WrByte(0x44);                // convert T 命令
}

/* 读取温度值 */
void RdTemp(void)
{
        TxReset();                        // 产生复位脉冲,初始化DS18B20
        RxWait();                        // 等待DS18B20给出应答脉冲
        delay(1);                        // 延时
        WrByte(0xcc);                // skip rom 命令
        WrByte(0xbe);                // read scratchpad 命令
        tplsb = RdByte();        // 温度值低位字节(其中低4位为二进制的“小数”部分)
        tpmsb = RdByte();        // 高位值高位字节(其中高5位为符号位)               
}

/* 主程序,读取的温度值最终存放在tplsb和tpmsb变量中。
   tplsb其中低4位为二进制的“小数”部分;tpmsb其中高
   5位为符号位。真正通过数码管输出时,需要进行到十进
   制有符号实数(包括小数部分)的转换。              */
void main(void)
{
        do
        {       
                delay(1);                // 延时1ms
                convert();                // 启动温度转换,需要750ms
                delay(1000);        // 延时1s
                RdTemp();                // 读取温度                       
        }
        while(1);
}

基于DS12C887的实时日历时钟显示系统设计
#include "CalendarClk.h"

/* 从串行口获取数据函数,数据包括:year1,month1,dayofweek1,
dayofmonth1,hour1,min1。如果获取到正确数据则返回1,否则返回0 */
uchar getdata()
{
        // 略去
}

/* 设置日历和时钟函数 */
void settime()
{
        REG_B = REG_B|0x80;                        // SET=1,芯片DS12C887处于设置状态

        MIN = min1;
        HOUR = hour1;
        DAYOFWEEK = dayofweek1;
        DAYOFMONTH = dayofmonth1;
        MONTH = month1;
        YEAR = year1;

        REG_B = REG_B&0x7f;                    // SET=0,芯片DS12C887恢复正常数据更新状态
}


/* 获取日历时钟函数 */
void gettime()
{
        while (REG_A&0x80==0x00)        // 直到UIP=0时,才能读取日历时钟信息        {
        {       
                min2 = MIN ;
                hour2 = HOUR;
                dayofweek2 = DAYOFWEEK;
                dayofmonth2 = DAYOFMONTH;
              month2 = MONTH;
                year2 = YEAR;
        }
}

/* 13位数码管显示年、月、日、星期、时、分 */
void display()
{
        // 略去
}

/* 串口初始化函数 */
void init_serial()
{
        TMOD = 0x20;                                // 定时器T1使用工作方式2
        TH1 = 250;
        TL1 = 250;
        TR1 = 1;                                        // 开始计时
        PCON = 0x80;                                // SMOD = 1
        SCON = 0x50;                                // 工作方式1,波特率9600kbit/s,允许接收
}


void main(void)
{
        uchar setflag;
        init_serial();

        /* 设置DV2、DV1、DV0为010,打开芯片DS12C877内部晶振 */
        REG_A = REG_A&0xaf;                        // DV2=DV0=0
        REG_A = REG_A|0x20;                        // DV1=0

        REG_B = REG_B&0x7b;                        // SET=0,时间数据正常更新;DM=0,二进制数据模式
        REG_B = REG_B|0x02;                        // 寄存器B的24/12位置1,24小时时间模式
       
        while (1)
        {
                setflag = getdata();        // 通过查询方式获取串口数据
       
                /* 如果获取到正确数据,则设置时间 */
                if (setflag==0x01)
                        settime();
       
                /* 调用获取日历时钟函数 */
                gettime();
               
                /* 13位数码管显示日历、星期和时间信息 */
                display();
        }               
}


拿去看看改改差不多了吧···
点赞  2010-3-17 21:19
楼上好详细啊,,,呵呵
点赞  2010-3-17 21:28
看样子像是一个毕业设计的题目嘛
点赞  2010-3-17 22:45
楼主去下载我上传的:
单片机的毕业设计礼包--数字电子钟礼包
http://download.eeworld.net/source/2083896

用单片机实现的数字电子钟,是凌阳的毕业设计礼包,里面有非常详细的设计说明以及使用说明以及原理图,还有源代码等资料,非常详细,非常经典,值得参考。

至于能够显示当前温度,一般用DS18B20实现起来更精简,凌阳官网上也对应设计文档,楼主去搜下吧。

点赞  2010-3-18 00:23
非常感谢各位大虾!!
点赞  2010-3-18 09:50
昏了,还有毕业设计专用的,牛呀,老师和公司联合起来骗钱
点赞  2010-3-18 15:12
这么简单也能当毕业设计啊
点赞  2010-3-18 22:46
引用: 引用 6 楼 laorenshen 的回复:
昏了,还有毕业设计专用的,牛呀,老师和公司联合起来骗钱
你不知道现在的社会,哪都能变钱出来嘛!
点赞  2010-3-19 19:31
可怜的还是我们学生,义务劳工啊。
点赞  2010-3-19 19:32
mark
点赞  2010-3-20 11:46
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复