历史上的今天
返回首页

历史上的今天

今天是:2025年01月04日(星期六)

2021年01月04日 | 基于51单片机的多功能时钟温度计 DS1302+LCD1602

2021-01-04 来源:51hei

本设计是由STC89C52单片机为控制核心,具有在线编程功能,低功耗;时钟电路由DS1302提供,它是一种高性能、低功耗的时钟电路,工作电压为3V~5V;所以采用DS1302作为本设计的日历芯片;显示部份使用LCD1602B液晶模块进行数字显示,1602B液晶模块可以显示2行16个字符,有8位数据总线D0—D7,和RS、R/W、EN三个控制端口,工作电压为5V,并且带有字符对比度调节和背光。该模块也可以只用D4-D7作为四位数据分两次传送,这样就可以节省MCU的I/O口资源,系统主要由晶振电路、复位电路、时钟电路部分、中央处理单元、晶显示部分组成。

电路原理图如下:


制作出来的实物图如下:
 

Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)

单片机源程序如下:

#include

#include

#define uchar unsigned char

#define uint unsigned int

#define     LCDIO      P0

sbit rs=P2^0;  

sbit rd=P2^1;

sbit lcden=P2^2;

sbit acc0=ACC^0;             //移位时的第0位

sbit acc7=ACC^7;             //移位时用的第7位

sbit ct=P2^3;

sbit speaker=P3^5;

sbit DQ=P2^5;//ds18b20与单片机连接口

int djs11=0,js,dsmin=0,dshour=0;


uchar second,minute,hour,day,month,year,week,count=0;   

uchar ReadValue,num,time;   

uint tvalue;//温度值

uchar tflag;

uchar code        table[]={" 2000-00-00 FRI"};

uchar code table1[]={" 00:00:00       "};

uchar code table2[]= "THUFRISATSUNMONTUEWES";

char szdata[8];

char szdata1[8];

uchar data disdata[5];

sbit DATA=P3^3;   //时钟数据接口

sbit RST=P3^4;   

sbit SCLK=P3^2;   

sbit menu=P2^7;              //菜单

sbit add=P2^6;               //加一

sbit dec=P2^4;

sbit set=P2^3 ;              //减一

sbit djs=P3^6;

void miaobiao();

void yx();

void delayms(int x)

{

char i;

while(x--)

{

  for(i=150;i>0;i--);

}

}

void delay(uint z)

{

        uint x,y;

        for(x=z;x>0;x--)

                for(y=110;y>0;y--);

}

void delay1(uint z)

{

        for(;z>0;z--);

}

void write_com(uchar com)

{

        rs=0;

        rd=0;

        lcden=0;

        LCDIO=com;

        delay(5);

        lcden=1;

        delay(5);

        lcden=0;       

}


void write_date(uchar date)

{

        rs=1;

        rd=0;

        lcden=0;

        LCDIO=date;

        delay(5);

        lcden=1;

        delay(5);

        lcden=0;       

}


void init()

{

        uchar num;

        lcden=0;


        write_com(0x38);

        write_com(0x0c);

        write_com(0x06);

        write_com(0x01);

        write_com(0x80);

        delay(5);

        write_com(0x80);

        for(num=0;num<15;num++)

                {

                        write_date(table[num]);

                        delay(5);

                }

        write_com(0x80+0x40);

        for(num=0;num<15;num++)

                {

                        write_date(table1[num]);

                        delay(5);

                }      

       


}


void Write1302(uchar dat)

{

  uchar i;

  SCLK=0;           //拉低SCLK,为脉冲上升沿写入数据做好准备

  delay1(2);       //稍微等待,使硬件做好准备

  for(i=0;i<8;i++)      //连续写8个二进制位数据

    {

     DATA=dat&0x01;    //取出dat的第0位数据写入1302

  delay(2);       //稍微等待,使硬件做好准备

   SCLK=1;           //上升沿写入数据

   delay1(2);      //稍微等待,使硬件做好准备

   SCLK=0;           //重新拉低SCLK,形成脉冲

   dat>>=1;          //将dat的各数据位右移1位,准备写入下一个数据位

   }

}


void WriteSet1302(uchar Cmd,uchar dat)

{

   RST=0;           //禁止数据传递

   SCLK=0;          //确保写数居前SCLK被拉低

   RST=1;           //启动数据传输

   delay1(2);     //稍微等待,使硬件做好准备

   Write1302(Cmd);  //写入命令字

   Write1302(dat);  //写数据

   SCLK=1;          //将时钟电平置于已知状态

   RST=0;           //禁止数据传递

}


uchar Read1302(void)

{

   uchar i,dat;

   delay(2);       //稍微等待,使硬件做好准备

   for(i=0;i<8;i++)   //连续读8个二进制位数据

   {

    dat>>=1;       //将dat的各数据位右移1位,因为先读出的是字节的最低位

    if(DATA==1)    //如果读出的数据是1

    dat|=0x80;    //将1取出,写在dat的最高位

    SCLK=1;       //将SCLK置于高电平,为下降沿读出

    delay1(2);  //稍微等待

    SCLK=0;       //拉低SCLK,形成脉冲下降沿

    delay1(2);  //稍微等待

    }  

  return dat;        //将读出的数据返回

  }


uchar  ReadSet1302(uchar Cmd)

{

  uchar dat;

  RST=0;                 //拉低RST

  SCLK=0;                //确保写数居前SCLK被拉低

  RST=1;                 //启动数据传输

  Write1302(Cmd);       //写入命令字

  dat=Read1302();       //读出数据

  SCLK=1;              //将时钟电平置于已知状态

  RST=0;               //禁止数据传递

  return dat;          //将读出的数据返回

}

void Init_DS1302(void)

{

WriteSet1302(0x8E,0x00);                 //根据写状态寄存器命令字,写入不保护指令

WriteSet1302(0x80,((0/10)<<4|(0%10)));   //根据写秒寄存器命令字,写入秒的初始值

WriteSet1302(0x82,((12/10)<<4|(12%10)));   //根据写分寄存器命令字,写入分的初始值

WriteSet1302(0x84,((11/10)<<4|(11%10))); //根据写小时寄存器命令字,写入小时的初始值

WriteSet1302(0x86,((25/10)<<4|(25%10))); //根据写日寄存器命令字,写入日的初始值

WriteSet1302(0x88,((1/10)<<4|(1%10))); //根据写月寄存器命令字,写入月的初始值

WriteSet1302(0x8c,((13/10)<<4|(13%10)));   //nian

WriteSet1302(0x8a,((1/10)<<4|(1%10)));

}


void DisplaySecond(uchar x)

{

uchar i,j;   

i=x/10;

j=x%10;

write_com(0xc7);   

write_date(0x30+i);   

write_date(0x30+j);      

}

void DisplayMinute(uchar x)

{

uchar i,j;   

i=x/10;

j=x%10;

write_com(0xc4);   

write_date(0x30+i);  

write_date(0x30+j);        

}

void DisplayHour(uchar x)

{

uchar i,j;   

i=x/10;

j=x%10;

write_com(0xc1);   

write_date(0x30+i);  

write_date(0x30+j);        

}


void DisplayDay(uchar x)

{

uchar i,j;   

i=x/10;

j=x%10;   

write_com(0x89);   

write_date(0x30+i);  

write_date(0x30+j);      

}


void DisplayMonth(uchar x)

{

uchar i,j;     

i=x/10;

j=x%10;  

write_com(0x86);   

write_date(0x30+i);  

write_date(0x30+j);  

}


void DisplayYear(uchar x)

{

uchar i,j;  

  i=x/10;

j=x%10;

write_com(0x83);   

write_date(0x30+i);

write_date(0x30+j);  

}   

void DisplayWeek(uchar x)

{ uchar i;

   x=x*3;

write_com(0x8c);   

for(i=0;i<3;i++)

   {

           write_date(table2[x]);

        x++;  

   }

}   


void  read_date(void)

{

     ReadValue = ReadSet1302(0x81);   

     second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);

     ReadValue = ReadSet1302(0x83);  

     minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);

     ReadValue = ReadSet1302(0x85);  

     hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);

     ReadValue = ReadSet1302(0x87);  

     day=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);

     ReadValue = ReadSet1302(0x89);  

     month=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);

     ReadValue = ReadSet1302(0x8d);  

     year=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);

         ReadValue=ReadSet1302(0x8b);                     //读星期

     week=ReadValue&0x07;

         if((year==szdata[1])&&(month==szdata[2])&&(day==szdata[3])&&(week==szdata[4])&&(hour==szdata[5])&&(minute==szdata[6])&&(second==szdata[7]))             speaker=0;

         DisplaySecond(second);           

     DisplayMinute(minute);        

     DisplayHour(hour);            

     DisplayDay(day);               

     DisplayMonth(month);            

     DisplayYear(year);         

推荐阅读

史海拾趣

长园维安(CYGWAYON)公司的发展小趣事

随着产品技术的成熟,长园维安开始积极拓展国际市场。公司与国际知名企业建立合作关系,共同开发新产品,拓展市场份额。同时,长园维安还积极参加国际展览,展示公司最新技术和产品,提高品牌知名度。这些努力使长园维安在全球电子行业中的影响力不断增强。

振宝佳(DMBJ)公司的发展小趣事

随着大陆市场化程度的加深和基础设施的完善,振宝佳公司看到了大陆市场的巨大潜力。为了更好地服务大陆客户,公司于2005年做出了重大战略转移,将总部迁移到塘厦。这一决策不仅使公司能够更贴近市场,也为其后续的发展奠定了坚实的基础。

Henkel公司的发展小趣事

为了提升生产效率和产品品质,振宝佳公司在韩国引进了专业的全制动生产线和智能化的电子监察检查设备。这些先进的生产线和设备使公司的生产能力得到了显著提升,同时也确保了产品的质量和稳定性。这些投入为公司赢得了客户的信赖和好评。

ENSIGN公司的发展小趣事

ENSIGN不仅局限于照明领域,还积极向能源服务领域拓展。近年来,ENSIGN通过技术创新和战略合作,为客户提供定制化的电源解决方案。例如,在2009年,ENSIGN建成了新的工厂,并与多家本地供应、装配和测试组织建立了合作关系,以提供更高质量、更可靠的产品和服务。

恒连电子(EVERCOM)公司的发展小趣事

随着公司实力的不断增强,恒连电子开始积极拓展国内外市场。在国内市场,公司通过与各大电商平台合作,加大品牌宣传力度,提高产品的知名度和美誉度。同时,公司还积极参与各类行业展会和论坛活动,与同行交流学习,提升公司的行业影响力。在国际市场方面,恒连电子通过与国外知名企业的合作,引进先进的技术和管理经验,提升公司的国际化水平。此外,公司还积极开拓海外市场,将产品出口到多个国家和地区。

蜂鸟无线公司的发展小趣事
在PWM调速电路中,需要加入过流保护、过压保护等保护措施,以防止电动机因过载而损坏。

问答坊 | AI 解惑

FPGA趋势

FPGA技术的发展趋势 随着微电子技术、EDA技术、以及应用系统需求的发展,FPGA正在逐渐成为数字系统开发的平台,并将在以下方面继续完善和提高: (1) 高集成度、大容量、低成本、低电压、低功耗; (2) 资源多样化; (3) 适用于片 ...…

查看全部问答>

Keil C中的Double型怎么使用?

由于编程的需要,采用Double型存储数据,可是,在调试的时候,Memory观察窗中发现Double型会自动将后面几位截取,进而用指数来表示,不知道这只是显示的问题,还是它存储的数据就是截掉末尾几位的了?…

查看全部问答>

高频PCB设计中出现的干扰分析及对策

高频PCB设计中出现的干扰分析及对策…

查看全部问答>

Labview超牛运用视频1(弹珠自动筛选)

http://www.tudou.com/programs/view/jxVXi7wTOmY/…

查看全部问答>

用串口转usb接口的模块(一)

用串口转usb接口的模块 数据接收存储技术革新是信号采集处理领域内的一个重要课题。利用这种技术,可以把信号的实时采集和精确处理在时间上分为两个阶段,有利于获得令人更满意的处理结果。在无线数传接收设备中应用数据接收存储方法时,除了要 ...…

查看全部问答>

怎么创建设备节点呢?

写了一个字符设备的驱动,但用的是驱动模型框架,用的是platform_driver_register接口注册的,然后在probe里注册一个字符设备驱动,现在驱动已经加载上了,用lsmod |grep xxx, cat /procmodules | grep xxx, ls /sys/modules/xxx都已经有相关信息, ...…

查看全部问答>

英蓓特STM32开发板(¥680),集成ULINK-ME

产品信息:    STM103V100是英蓓特公司新推出的一款基于ST意法半导体STM32系列处理器(Cortex-M3内核)的全功能评估板。该评估板采用主板与子板组合的工作方式,只需通过换插不同的CPU(现配STM32F103VBT6处理器)子板,即 ...…

查看全部问答>

Altium 对于 Atmel Touch Controls 的支持 (中)

使用 SmallQTouchSlider 器件来实现一个小型slider传感器。这是一个自电容,一维,立体内插式传感器。它有三个独立通道直接连接到Atmel QTouch 感应控制器。相应的sensor模板在PCB中是由简单的矩形电极组成。这个模板包含2个完 ...…

查看全部问答>

DK-LM3S9B96例2按键与LED

KEY-PJ7; LED-PF3; 程序如下:…

查看全部问答>