• 我在上一篇文章中焊接了单片机最小系统板,并且成功驱动了LCD1602,我没有在最后展示LCD显示部分,就放到这篇文章在外接DS12C887的情况下和大家分享一下。
  • 需要准备的模块如下:
  • 1.单片机的最小系统板(最好有复位电路)另外20引脚(地)和40引脚vcc要多引出来6个(后面接杜邦线很多地方要用)
  • 2.DS12C887时钟芯片(24脚的)
  • 3.LCD1602模块
    这里的DS12C887买回不能直接用,得像51芯片一样焊接个底座出来,旁边两列焊接两列排针,作为芯片的引脚。焊接好的效果图如下

因为要驱动LCD1602,电位器也是必不可少的,我把电位器单独焊接在了另外一块板子上,这个焊接地方没有要求,合理安排空间即可,焊接电位器也要利用排针引出三个角,对于3296型电位器的各引脚说明如下1脚VCC,3脚GND,2脚接输出。电位器的大小选择位10k,如图


还需要准备4个轻触按键,因为设置时钟时,需要选择功能、增大键、减小键、闹钟查看键(我的板子上没有焊接蜂鸣器,所以闹钟到点后,不会响,蜂鸣器是一个比较简单的模块,代码里面都有定义,我在焊接的时候把他先忽视了,需要的话,外加上蜂鸣器模块,看一下程序里的引脚定义就可以)
4个轻触按键的接法从上到下排列,分别为功能选择、增大、减小、闹钟查看。此处的焊接为选择每个按键的两个对角引脚,每个按键选择的两个引脚要相同,从上到下在板子上安插好,

原理图和实物图引脚一一对应,我们可以选择1脚输出,4脚接地(对角接通)4个按键的4号脚连接在一起并且引出一个插针到时候直接接单片机的GND完成接地,再把每个按键的1号脚用插针引出来,接代码里定义的按键引脚。
在这里我给大家看一下DS12C887的芯片接法

我从左边最上边开始逆时针转一圈来说明各引脚的接法
从第四引脚开始接4-11为数据传输,接单片机的P0口,12脚接单片机20脚的GND。
13脚cs接P1^4
14脚as接P1^5
15脚rw接P1^6
17脚ds接P1^7
18脚RESET接VCC
19脚IRQ接P3^3
24脚接VCC
现在DS12C887模块的准备工作都完成了。只剩下LCD1602的接线部分,原理图如下
1602液晶上都有每个管脚的名称,可以对照着原理图来接线

从左向右,1脚接地,2脚接vcc,3脚接电位器的第二脚,rs接单片机的P3^5,rw接地,E接单片机的P3*4,D0-D7接单片机的P2口,A、K为背光电源,A接vcc,K接gnd。至此所有外接模块安装包括接口对应引脚都完成了。

 /*总体要求*//*在1602上显示年月日星期时分秒,并且按照秒来实时更新显示可以闹钟设定,到点报警功能,报警响起时,任意键可以取消报警四个按键,根据功能可以调节参数,分别为功能键,数值增大键,数值减少键,闹钟查看键,每次按键按下,蜂鸣器都会滴一声,利用DS12C887实现断电后,再次上电,时间仍可以准确显示 *//*另外这个程序中文部分是学习了一个半月C语言的人的理解,难免有错误的地方如果你想移植程序,除了开头的各种脚需要修改,程序里面1602和DS12C887的写指令写数据,读指令读数据的IO口也要修改应该是有4~6处,一定要注意,不然你的程序不会亮起来,然后初始化部分,记得初始化后去掉,但是仿真的时候不要去掉,去掉没法显示*//*非常非常非常重要的一个细节,总线上要加    AD[0..7]     这个名字,如果没有永远也仿真不起来*/
#include<reg52.h>                         //52系列单片机机头文件
#define uchar unsigned char               //宏定义 定义一个无符号字符型数据
#define uint  unsigned int                //宏定义 定义一个无符号整型数据
sbit lcdrs=P3^5;                          //自定义数据/命令选择端口
sbit lcden=P3^4;                          //自定义使能信号
//sbit dula=P2^6;
//sbit wela=P2^7;                                          /*P0口接液晶1602和时钟芯片DS12C887的AD0-AD7*/
sbit beep=P2^3;                           //蜂鸣器。有的按键接rd为低电平,就需要也定义一下rd,我这里面四个按键采用的是接地的结构!
sbit dscs=P1^4;                              //定义地址选通输入端 (读到那里去)
sbit dsas=P1^5;                              //定义芯片片选端    (读哪个芯片)
sbit dsrw=P1^6;                              //定义读数据允许输入脚,这里mot接地   (让不让读的开关)
sbit dsds=P1^7;                          //定义中断请求输出
sbit dsirq=P3^3;                              //定义读允许输入       (让读以后,我来输入数据)
sbit lcdrd=P3^7;                       sbit s1=P1^0;                            //功能键
sbit s2=P1^1;                            //数值增大键
sbit s3=P1^2;                            //数值减少键
sbit s4=P1^3;                            //闹钟查看键//因为功能键要8次才能推出,这里可以加一个直接退出按键,可以放在外部中断上
bit    flag1, flag_ri;                                      //定义两个位变量
uchar  count,s1num,flag,t0_num;                             //定义几个无符号字符型数据,用到时再解释定义干啥用的
char   miao,shi,fen,year,month,day,week,amiao,afen,ashi;    //定义几个字符型数据,这个基本上都能理解。
uchar  code table[]=" 20  -  -      ";                          //让液晶固定显示的内容
uchar  code table1[]="      :  :  ";                         //让液晶固定显示的内容
void   write_ds(uchar, uchar);                              //函数申明     寄存器初始化
void   set_alarm(uchar, uchar, uchar);                      //函数申明     设定闹钟
void   read_alarm();                                        //函数申明     读报警器
void   set_time();                                          //函数申明       寄存器初始化
void   delay(uint z)                                        //延时函数
{                                         uint x,y;                               //定义两个无符号整形数for(x=z;x>0;x--)                        //如果x>0,则y执行110次for(y=110;y>0;y--);                  //本小段为单位是1ms的延时
}
void di()                                 //蜂鸣器报警
{beep=0;                                 //低电平有效,蜂鸣器开始蜂鸣delay(100);                           //延时100毫秒,响0.1秒beep=1;                                  //蜂鸣器停止鸣叫
}
void write_com(uchar com)                  //写液晶命令函数
{lcdrs=0;                                 //rs低电平,表示要写命令lcden=0;                                  //en低电平,表示为了下面送入数据,防止此时还是高电平,无法制造高脉冲P2=com;                                   //D0-D7我接的是P0上面,数据送给它delay(3);                                   //延时3mslcden=1;                                //en高电平,延时三秒  再变成低电平,完成一次高脉冲,使数据送入液晶显示屏delay(3);                                   //表示接下来,液晶显示屏可以过来读数据了lcden=0;
}
void write_date(uchar date)                //写液晶数据函数
{lcdrs=1;                                 //高电平表示要写数据lcden=0;                                //en低电平,表示为了下面送入数据,防止此时还是高电平,无法制造高脉冲P2=date;                                  //D0-D7我接的是P0上面,数据送给它delay(3);                                   //延时3mslcden=1;                                //en高电平,延时三秒  再变成低电平,完成一次高脉冲,使数据送入液晶显示屏delay(3);                                   //表示接下来,液晶显示屏可以过来读数据了lcden=0;
}
void init()                                //液晶初始化
{ uchar  num;                              //定义一个字符EA=1;                                      //打开全局中断控制EX1=1;                                   //打开外部中断1中断IT1=1;                                  //设置负跳变沿触发中断flag=0;                                // 自定义字符全部归零,为了方便实用 flag1=0;s1num=0;                                    //键盘按下的次数week=1;                                  //星期显示最低也是周一的一lcden=0;                                 //使能信号定义为零,表示还没有数据lcdrd=0;
//  dula=0;//关闭数码管显示
//  wela=0;write_ds(0x0A,0x20);                       //首次使用ds12c887时使用,以后不必在写。打开振荡器write_ds(0x0B,0x26);                        // 设置24小时模式,数据二进制格式,开启闹钟中断。//0A,0B表示地址,20,26翻译成二进制是00100000,00100110对应着对着寄存器A和B从D7-D0 set_time();                              //设置默认上电时间write_com(0x38);                          //设置16x2显示,5x7点阵,8位数据接口write_com(0x0c);                           //设置开显示,不显示光标write_com(0x06);                        //写一个字符后,地址指针自动加1write_com(0x01);                        //显示清0,数据指针清0write_com(0x80);                        //设置数据指针位置,此处时数据指针第一行,第一处for(num=0;num<15;num++)                //<15原因是第一行显示的数字或者空格一共14个{write_date(table[num]);                //把要显示的数据送入到液晶的第一行delay(1);                             //延迟一毫秒}write_com(0x80+0x40);                  //设置数据指针位置,此处时数据指针第二行,第一处for(num=0;num<11;num++)                //<11原因是第二行显示的数字或者空格一共10个{write_date(table1[num]);                   //把要显示的数据送入到液晶的第二行delay(1);                             //延迟一毫秒}
}
void write_sfm(uchar add,char date)        //1602液晶刷新时分秒函数4为时,7为分,10为秒      ,4.7.10均是显示位置
{   char shi,ge;                               //定义两个数,来表示十位数和个位数shi=date/10;                              // 要送去显示的十位ge=date%10;                             //要送去显示的个位  write_com(0x80+0x40+add);                 //时间是在第二行显示,所以是加0X40,在add处显示write_date(0x30+shi);                //shi和ge都是整形数值,但是液晶1602是内置ASCII表格,0在第048位write_date(0x30+ge);                    //转成十六进制就是0x30,
}
/*这个地方可能会有人迷糊,设置时分秒,怎么只设置十位和个,好像给人的感觉就是只设置时位,和分位,秒位怎么不设置,
实际上是,这里写入并显示的是  把时的十位和个位,分的十位和个位,秒的十位和个位,分别送去进行运算 ,然后先写命令确定位置,
再写数据,用来显示,下面一个子函数也是同样的道理*/
void write_nyr(uchar add,char date)        //1602液晶刷新年月日函数,3为年,6为月9为天  ,369也分别是位置
{   char shi,ge;                               //定义两个数,来表示十位数和个位数shi=date/10;                              // 要送去显示的十位ge=date%10;                             //要送去显示的个位  write_com(0x80+add);                       //时间是在第二行显示,所以是加0X40,在add处显示write_date(0x30+shi);                //shi和ge都是整形数值,但是液晶1602是内置ASCII表格,0在第048位write_date(0x30+ge);                    //转成十六进制就是0x30,
}   /*实际上到了主函数,时分秒,年月日会有六个子函数进行分别调用,这里用两个子函数来表示,不能用一个的原因是显示的内容不在一行,
主要是写入命令的位置不一样,大家可以观察一下*/
void write_week(char we)                    //写液晶1602星期显示函数
{write_com(0x80+12);                       //让we在0x80+12这个位置显示switch(we)                              //多分支结构的条件选择语句,we等于几就去执行几号分支{case 1:write_date('M');                  //写入M。整个的意思是如果we等于1,则显示MON,即星期一delay(5);                          //延时5毫秒后写入Owrite_date('O');                   //写入Odelay(5);                          //延时5毫秒后写入Nwrite_date('N');                   //写入Nbreak;                         //间断,为了和后面分开case 2:write_date('T');                //写入T。整个的意思是如果we等于2,则显示TUE,即星期二delay(5);                          //延时5毫秒后写入Uwrite_date('U');                   //写入Udelay(5);                          //延时5毫秒后写入Ewrite_date('E');                   //写入Ebreak;                         // 间断,为了和后面分开case 3:write_date('W');                   //写入W。整个的意思是如果we等于3,则显示WED,即星期三delay(5);                          //延时5毫秒后写入Ewrite_date('E');                   //写入Edelay(5);                          //延时5毫秒后写入Dwrite_date('D');                   //写入Dbreak;                         //间断,为了和后面分开case 4:write_date('T');                //写入T。整个的意思是如果we等于4,则显示THU,即星期四delay(5);                          //延时5毫秒后写入Hwrite_date('H');                   //写入Hdelay(5);                          //延时5毫秒后写入Uwrite_date('U');                   //写入Ubreak;                         //间断,为了和后面分开case 5:write_date('F');                //写入F。整个的意思是如果we等于5,则显示FRI,即星期五delay(5);                          //延时5毫秒后写入Rwrite_date('R');                   //写入Rdelay(5);                          //延时5毫秒后写入Iwrite_date('I');                   //写入Ibreak;                         //间断,为了和后面分开case 6:write_date('S');                //写入S。整个的意思是如果we等于6,则显示SAT,即星期六delay(5);                          //延时5毫秒后写入Awrite_date('A');                   //写入Adelay(5);                          //延时5毫秒后写入Twrite_date('T');                   //写入Tbreak;                         //间断,为了和后面分开case 7:write_date('S');                //写入S。整个的意思是如果we等于7,则显示SUN,即星期日delay(5);                          //延时5毫秒后写入Uwrite_date('U');                   //写入Udelay(5);                          //延时5毫秒后写入Nwrite_date('N');                   //写入Nbreak;                         //间断,为了和后面分开}
}
void keyscan()                             //数字时钟按键扫描函数
{if(flag_ri==1)                          //如果标志位,闹钟等于1,则蜂鸣器会响 ,这一句和按键扫描没有关系,主要是为了任意键可以消除//闹钟的报警,可以理解为,为闹钟取消而增加的一个扫描小程序。{if((s1==0)||(s2==0)||(s3==0)||(s4==0))  //如果s1-s4有一个为零,低电平    ||这个符号是关系运算符, 或的意思,有一个是低电平,则进行下一步。{delay(5);                              //延时去抖动if((s1==0)||(s2==0)||(s3==0)||(s4==0))   //再次确认,如果s1-s4有一个为零,低电平{while(!(s1&&s2&&s3&&s4));         /*/如果他们运算的结果为0   ,当闹钟响起,就会进入这个按键扫描程序,这没有按下键盘的时候,就会运行到这里,进行判断循环,一直等在,四个按键,有一个为0,这个语句就会判断为假,进行下一步运算,&&这个符号是关系运算的 与,一个值为零,则整体结果运算为0*/di();                              //则蜂鸣器会响,闹钟有自己的蜂鸣程序,这里有个DI主要原因是,每次按键 都会响,这是事先规定号的flag_ri=0;                           //清除报警标志}}}if(s1==0)                                    //检测按键s1{delay(5);                                  //延时5毫秒,也可叫延时去抖动。if(s1==0)                                 //再次检测按键s1{s1num++;                               //定义为键盘按下的次数if(flag1 == 1)                            //这个是用来闹钟的,如果等予1,说明现在是在设置闹钟值,从下面来看这个只能调节每天的闹钟,不能调节年月if(s1num == 4)                       //因为只能调节时分秒,让他们在里面循环s1num=1;                             //这个地方我卡了几天,大家要综合前后文,明白flag1是闹钟被按下了,flag是为了跳出主程序循环,为了设置时间flag=1;                                   //按键计数以后,则这个位变量变成1,while(!s1);                                /*!s1 的意思是取s1相反的数,是用来测试判断按键按下后有没有松开,松开则计数一次后,电平变成高电平,说明此时已经松开,也确定了s1num的具体数值,也就是按了几下*/di();                                    //每按下一次则响一声switch(s1num)                            //判断是按了几下,则选择什么位置光标点闪烁。{case 1:write_com(0x80+0x40+10);        //很明显这是显示屏第二行的显示指令,10  说明光标调节的是秒write_com(0x0f);             /*/不管你按的再快,光标也会从第一步开始,所以把 开显示,显示光标,光标闪烁  这个lcd的这个指令设置放在这里 */break;                          //会不停的跳出,再去问现在是按了几下了,按了几下,就会进入对应的里面,下面都是一样的不解释了。case 2:write_com(0x80+0x40+7);        /*这个就是光标在分钟上闪烁,(不光时分秒都是在他们的十位闪烁,如果送的是两位数,LCD的指针可以自动加一,把个位也给显示了)*/break;case 3:write_com(0x80+0x40+4);        //这个是在小时的位置显示闪烁break;case 4:write_com(0x80+12);             //这就是进入显示屏第一行了,在显示星期的位置,第十位,最右边,是调节星期的位置。break;case 5:write_com(0x80+9);                //日break;case 6:write_com(0x80+6);                 //月break;case 7:write_com(0x80+3);                  //年break;case 8:s1num=0;                           //把按键数置零,等这个小程序运行完,则光标不在闪缩,一切正常运行。相当于不选择任何位置。write_com(0x0c);                      //设置开显示,不显示光标flag=0;                            //等于0就是回到主程序的正常运行(可以参看以下主程序,更能方便理解)/*下面的几句基本一样,明白一个就全明白了,这个地方主要是查表,查寄存器A,功能列表有时分秒,闹钟的也有时分秒,年月日他们分别对应的寄存器地址,比如秒对应的是00H,分钟对应的是02H,所以0,2,4,6,7,8,9都是地址,往这个里面写,就是写的时分秒,可能有人问,既然是00H,02H,为什么写成0,2等等,其实是因为十六进制和十进制在0~9,书写虽然有区别,但是结果都一样*/write_ds(0,miao);                   write_ds(2,fen);write_ds(4,shi);write_ds(6,week);write_ds(7,day);write_ds(8,month);write_ds(9,year);break;                              //跳出}}}if(s1num!=0)                                     //测试不等于 0,也就是只有当s1按下时才能检测和用来启动s2和s3.{if(s2==0)                                         //问S2按键有没有按下{delay(1);                                      //延时1毫秒if(s2==0)                                      //再次来检测{while(!s2);                                      //给s2取反di();                                            //滴一声switch(s1num)                                  //根据s1按下的次数,来确定调节哪个位置{                                               //下面给大家解释一组,应该可以全部明白case 1:miao++;                                 //按键s2按一下,这里就会加一      设置秒钟if(miao==60)                             //如果加到了60 ,秒就会变成0miao=0;write_sfm(10,miao);                     //把秒的值经过运算,送到LCD相应的位置去显示write_com(0x80+0x40+10);                /*这一句是调用写指令,因为指针把秒显示完毕后,光标就会在秒的个位,所以这一句是把光标在拉回来,因为不能正好一下子就把秒的值设置的正好*/break;                                    //然后跳出,等待按键再次按下case 2:fen++;                               //设置分钟if(fen==60)                             //分,秒都用到60,生活中并没有60,这里也不能设置成59,但是可以改程序为>59.道理是一样的fen=0;write_sfm(7,fen);write_com(0x80+0x40+7);break;case 3:shi++;                               //设置时钟if(shi==24)                              //和上面一样的道理shi=0;write_sfm(4,shi);write_com(0x80+0x40+4);break;case    4:week++;                               //设置星期if(week ==8)                            //当按下第八次的时候,则8就会变成1week=1;write_week(week);write_com(0x80+12);break;case 5:day++;                                      //设置天数if(day==32)           day=1;write_nyr(9,day);write_com(0x80+9);break;case 6:month++;                                   //设置月数if(month==13)month=1;write_nyr(6,month);write_com(0x80+6);break;case 7:year++;                                       //设置年if(year==100)year=0;write_nyr(3,year);write_com(0x80+3);break;   }}}if(s3==0)                                           //上面是增大键,下面就是减少键{delay(1);                                           //延迟1毫秒if(s3==0)                                         //再次判断有没有按下{while(!s3);                                     //取相反数,看看是不是为真di();switch(s1num)                                     //根据按键1,就可以确定光标在什么位置,下面介绍和上面基本上一样,{                                               //只不过没有60了,反而有59,可以好好理解一下,其实很简单这个地方,就不解释了case 1:miao--;                                  //设置秒钟if(miao==-1)miao=59;write_sfm(10,miao);write_com(0x80+0x40+10);break;case 2:fen--;                                  //设置分钟if(fen==-1)fen=59;write_sfm(7,fen);write_com(0x80+0x40+7);break;case 3:shi--;                                //设置小时if(shi==-1)shi=23;write_sfm(4,shi);write_com(0x80+0x40+4);break;case   4:week--;                                 //设置星期if(week==-0)week=7;write_week(week);write_com(0x80+12);break;case 5:day--;                                //设置天数if(day==0)day=31;write_nyr(9,day);write_com(0x80+9);break;case 6:month--;                                  //设置月数if(month==0)month=12;write_nyr(6,month);write_com(0x80+6);break;case 7:year--;                                  //设置年if(year==-1)year=99;write_nyr(3,year);write_com(0x80+3);break;      }}}}if(s4==0)                                                    //这个地方是闹钟设置键{delay(5);                                              //延时5毫秒if(s4==0)                                              //再次判断是否按下{flag1=~flag1;                                            //如果按下,则按键1程序,进入时分秒的循环,这里的讲解和前面相呼应。while(!s4);                                                //取反是不是为真di();                                                  //为真说明,有按键按下,响一声,s1num=0;                                                 /*调试仿真时发现如果按下了按键一  在按闹钟,然后取消闹钟,在按按键一,会不出现光标,为了让闹钟和按键一不冲突,我添加这一句每当我按下按键一,不管按几次,只要按下按键4,都会让光标变成0位 */if(flag1==0)                                             //如果等于0,说明按得第二下,属于退出闹钟设置。{flag=0;                                               //程序运行到这一步,说明运行完这个程序,就要回到主程序了,//把按键1标志指令以后,本程序结束,可以进入主程序,否则还要在去按键1,按几下     write_com(0x80+0x40);                                  //把指针选择第二行,第一位,write_date(' ');                                         //写入两个空的符号,主要是为了区别状态,是调整时间还是设置闹钟write_date(' ');write_com(0x0c);                                         //关闭光标闪烁write_ds(1,miao);                                       //把时分秒送到DS12C887,程序正常运行write_ds(3,fen);                                          //这个时候的135要注意,可以看出是新设置闹钟值write_ds(5,shi);}else                                                    //如果flag不等于0,则进入这个程序,实际上程序都是先运行这个{                                                        //进入闹钟设置read_alarm();                                               //读闹钟原来的数据miao=amiao;                                              //分别送入时分秒fen=afen;shi=ashi;write_com(0x80+0x40);                                     //写指令,把指针,也就是光标位置放在第二排第一位write_date('R');                                           //分别送入R  I送去显示,可以区分现在是在调整时间,还是修改闹钟write_date('I');write_com(0x80+0x40+3);                                 /*这个地方还有一个指针,就会让很多人不理解,其实这个地方设计很巧妙3号位置,正好是时钟前面一位,然后再那边闪烁,接着等待按键1,来选择调整时分秒,按一下变换一个位置,在3号位闪烁还不影响开始时的闹钟值*/write_sfm(4,ashi);                                           //送到液晶去显示write_sfm(7,afen);write_sfm(10,amiao);}}}
}
void write_ds(uchar add,uchar date)                            //写DS12C887函数
{dscs=0;                                                      //根据时序图,把相应的脚变化高低,片选端,低电平有效dsas=1;                                                    //地址选通输入端dsds=1;                                                       //读允许输入脚dsrw=1;                                                     //写输入脚P0=add;                                                      //写地址dsas=0;dsrw=0;P0=date;                                                      //写命令dsrw=1;dsas=1;dscs=1;
}
uchar read_ds(uchar add)                                       //读DS12C887函数    ,这里没有用void要注意
{uchar ds_date;                                                //定义一个无符号函数dsas=1;                                                     //根据时序图,进行高低电平设置dsds=1;dsrw=1;dscs=0;P0=add;                                                     //写地址,确定要读什么位置的值dsas=0;dsds=0;P0=0xff;                                                    //先把P1进行置高,清理数据ds_date=P0;                                                   //把新的得到了  12c887里面的数值,赋值给ds_datedsds=1;                                                     //根据时序图继续设置电平dsas=1;dscs=1;return ds_date;                                               //谁调用它,什么位置调用的,就会把这个新得到的值在返回给他,//看得出来只有读闹钟值是调用了。
}void set_time()                                               //首次操作12c887时给寄存器初始化,完成后,要把这一段用 给屏蔽起来
{write_ds(0,0);                                               //根据寄存器A,相当于   所有的位置,全部显示00。write_ds(1,0);write_ds(2,0);write_ds(3,0);write_ds(4,0);write_ds(5,0);write_ds(6,0);write_ds(7,0);write_ds(8,0);write_ds(9,0);
}
void read_alarm()                                             //读取闹钟值
{amiao=read_ds(1);                                            //根据寄存器A,分别把闹钟值读出来,并且赋值给时分秒afen=read_ds(3);ashi=read_ds(5);
}
void main()                                                  //主程序
{init();                                                      //调用初始化函数while(1)                                                   //为真不断循环,等待闹钟中断{keyscan();                                                    //按键子程序,不断地扫描if(flag_ri==1)                                                //如果有闹钟,则进入这里{di();delay(100);                                                    //一直响 滴滴 di();delay(500);}if((flag==0) && (flag1==0))                                  //如果按键标志位和闹钟标志位都为0,则继续{keyscan();                                                //按键继续扫描year=read_ds(9);                                               //把DS12C887里面的数值不断读取month=read_ds(8);day=read_ds(7);week=read_ds(6);shi=read_ds(4);fen=read_ds(2);miao=read_ds(0);write_sfm(10,miao);                                         //这里把DS12c887的值不断地写入到lcd1602write_sfm(7,fen);write_sfm(4,shi);write_week(week);write_nyr(3,year);write_nyr(6,month);write_nyr(9,day);}}
}
void exter()interrupt 0                                     //中断1程序
{uchar c;                                                       //定义一个无符号数值flag_ri=1;                                                      //闹钟中断时间到了c=read_ds(0x0c);                                             //读取c寄存器的值,表示响应了中断
}
在这里插入代码片

利用单片机最小系统外接DS12C887 在LCD1602上显示实时时钟相关推荐

  1. 焊接单片机最小系统板,驱动lcd1602

    今天分享一些我制作单片机最小系统板的过程以及遇到的问题和解决办法.本人萌新一枚,写文章就是我们大家互相学习交流. 之前学习的是郭天祥的tx-1c单片机,书中的例程都写的差不多了,就想着自己焊接一个最小 ...

  2. 自学笔记:89c51单片机最小系统Protues篇

    什么是单片机最小系统? 单片机最小系统:单片机最小应用系统,使用最少的元件组成单片机能够工作的系统. 单片机最小系统三要素:电源模块,(晶振/时钟)振荡电路模块,复位电路模块 1,电源模块:供电.VC ...

  3. 51单片机 | 数字电路与C语言基础 | 51单片机最小系统

    文章目录 一.数字电路基础 1.电平特性 2.二进制与十六进制 2.1 二进制 2.2 十六进制 3.二进制的逻辑运算 二.C语言基础语法 三.51单片机最小系统 1. 51 单片机最小系统构成 1. ...

  4. 单片机拟真电路图软件_单片机最小系统电路图,以及单片机的应用分类

    单片机是集成电路芯片,它使用超大规模技术通过微处理器,存储器,具有数据处理功能的输入和输出接口电路集成在同一芯片上.接下来就为大家简单介绍一下单片机最小系统电路图. MCS-51单片机是一种集成的电路 ...

  5. 详解单片机最小系统组成

    目录 一.MCU 二.电源 2.1 MCU接口 2.2 补充说明 三.晶振电路 3.1 有源晶振/无源晶振 3.2 高速外部时钟 3.2.1MCU接口 3.2.2高速外部时钟原理图 3.3 低速外部时 ...

  6. 利用c51进行数模转换并在液晶屏上显示_基于C51单片机的智能计算器、矩阵键盘、lcd1602...

    目录 1绪论.............................................................................................. ...

  7. 电子设计入门——单片机最小系统

    写在前面 本文以STM32F401RCT6为例,讲解单片机最小系统的设计方法,以及一些相关的原理. 上图所示即为单片机最小系统电路,我们将其分为三个部分,即电源电路.复位电路.时钟电路.在了解最小电路 ...

  8. 微型计算机典型组成原理图,51单片机最小系统原理图、PCB及组成原理详解

    单片机:单片机(Microcontrollers)是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU.随机存储器RAM.只读存储器ROM.多种I/O口和中断系统.定时器 ...

  9. 51单片机计算机实物焊接,基于51单片机的最小系统焊接图 浅谈单片机最小系统...

    本文主要是关于51单片机的相关介绍,并对基于51单片机的最小系统焊接进行了详尽的阐述. 单片机最小系统 单片机最小系统主要由电源.复位.振荡电路以及扩展部分等部分组成. 对于一个完整的电子设计来讲,首 ...

最新文章

  1. git 创建分支,更改并提交
  2. “MIDI机器狗”的木马正在疯狂传播
  3. qt登录界面跳转_每天10分钟,木辛老师带你实战慕课软件开发:登录界面开发第2课...
  4. 5分钟k线数据 存储_成功率极高的“分时K线战法”:15分钟K线战法+30分钟K线战法...
  5. 7-69 计算圆周率 (15 分)
  6. vue php 加载速度,Vue加载优化,速度提高一倍。
  7. 实现三栏布局的几种方法
  8. Codeforces Global Round 14, C. Phoenix and Towers
  9. kaptcha——谷歌验证码工具
  10. Cp与Cpk了解与计算
  11. 利尔达芯智行智能BMS系统方案,让电池的“大脑”更聪明
  12. Android jetpack DataBinding 与RecyclerView
  13. 计算机网络修复提示DNS服务器,dns的服务器故障怎么办,电脑dns异常修复了没用...
  14. reverse 函数讲解
  15. LTE学习笔记--LTE无线连接过程--UE Attach过程和Detach过程
  16. 怎么把视频转换成音频
  17. 【Flask】response响应
  18. (二)计算机的协议及协议的通信仿真
  19. linux常用命令加实例大全
  20. 实习日记——Day47

热门文章

  1. 计算机整理桌面怎么弄,图文详解如何整理桌面
  2. html读写Mysql数据库
  3. 第三方软件测试z5x电池,5000mAh的vivo Z5x能用多久?三大续航测试摧残,表现出乎意料...
  4. 你的走路姿势正确吗?步态不对牵连多种疾病
  5. Android基础知识【项目实训-实现二级导航“今日活动”及读取数据库】【5】
  6. VUE2.0全局方法注册
  7. 神经网络、结构、权重和矩阵
  8. 发布 | 汉字转拼音工具
  9. 音视频技术开发周刊 | 279
  10. 第一单元 用python学习微积分(五) 隐函数微分法和逆函数导数(上)- 隐函数微分