找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3733|回复: 9
收起左侧

分享第一个成品STC12C5A60S2单片机+DS1302+DS18B20+LCD1602 附程序

  [复制链接]
ID:889094 发表于 2021-3-24 19:12 | 显示全部楼层 |阅读模式
STC12C5A60S2+DS1302+DS18B20+LCD1602,晶振11.0592M
主要功能:时间温度显示,设置一个闹表
温度大于30度LED亮起,闹表时间时分对应LED闪烁
4个按键分别对应设置、时间+、时间—、退出设置
闹表时间保存于DS1302的RAM区。
开发中间遇到的主要问题:
一、STC12C5A60S2是1T的芯片,运行速度比89C52快,延时函数需要调整
二、DS1302模块与STC12的连接线不能过长,调试过程开始线路过长,读取模块的结果会是0xff,各种找原因也不能解决,程序改得乱七八糟。各种百度各种改,最后看到一条有说线路过长可能是原因。最终对线路测量,两段线电阻分别为0.4欧和0.5欧,长度分别为7cm和15cm,最终理论解决希望有大佬能够帮忙解释。

电路原理图如下:


上图是初始电路图,图中芯片为89C52,后改为STC12C5A60S2,个别细节
11.jpg
1.jpg 1.jpg
上图为最终结果

上图上面箭头为原来DS1302用排线连接位置,下面是最终位置
显示全是????

单片机源程序如下:
  1. #include  "STC12C5A60S2.H"
  2. #include  <intrins.h>
  3. #include "delay.h"
  4. #include "lcd1602.h"
  5. #include "ds18b20.h"
  6. #include "ds1302.h"

  7. sbit led= P3^7;//led灯,替代蜂鸣器
  8. uchar count=0;                                //计时器计数
  9. uint temperature=0;                //温度,取实际温度的10倍,输出时最后一位前加小数点
  10. float ftempp;                                        //浮点型温度

  11. uchar *p1,*p2,*p3,*p4;//定义指针,分别对应日期,时间,芯片格式数据,设置光标位置
  12. uchar mdate[16];//用于显示日期"20xx-xx-xx Mon."
  13. uchar mtime[9],ntime[6];//用于显示时间"xx:xx:xx"和闹表时间"XX:XX"末位写0用于结束字符串输出
  14. uchar stime[2];//用于保存闹钟时间
  15. uchar ttime[7];//={0x48,0x48,0x22,0x028,0x05,0x06,0x18};//用于初始化DS1302,和读取时间

  16. sbit key1=P2^7;//时间调整按键,1设置
  17. sbit key2=P2^6;//2加
  18. sbit key3=P2^5;//3减
  19. sbit key4=P2^4;//4退出
  20. uchar n,stat=0;//设置状态标志,0为正常显示状态
  21.                                                                 //1-9为设置状态1-年、2-月、3-日、4-周、5-时、6-分、7-秒、8-闹表时、9-闹表分
  22. uchar isryear(uchar year1)
  23. {
  24.         int year,isrun;

  25.         //判断是否闰年,1为闰年,0为平年
  26.         year=2000+year1/16*10+year1%16;
  27.         if(year%4==0)
  28.         {
  29.                 if(year%100!=0)
  30.                 {
  31.                         isrun=1;
  32.                 }
  33.                 else if(year%400)
  34.                 {
  35.                         isrun=1;
  36.                 }
  37.                 else
  38.                 {
  39.                         isrun=0;
  40.                 }
  41.          }
  42.         else
  43.         {
  44.                  isrun=0;
  45.          }
  46.         return isrun;
  47. }
  48. void keyscan(uchar *tempt,uchar *stime)
  49. {
  50.         uchar isrun;
  51.         if(key1==0)//设置
  52.         {
  53.                 delayms(30);
  54.                 if(key1==0)
  55.                 {
  56.                         stat++;//设置标志在0--9之间变化,0为正常显示状态,1--7打开光标闪烁并在7个时间选项中移动,8、9闹表时间
  57.                         if(stat>9)
  58.                                 stat=1;
  59.                 }
  60.                 while(!key1);
  61.         }
  62.         if(key2==0)//选中位置+1
  63.         {
  64.                 delayms(30);
  65.                 if(key2==0)
  66.                 {
  67.                         switch(stat)
  68.                         {
  69.                                 case 1://年
  70.                                 {
  71.                                         tempt[6]++;
  72.                                         if((tempt[6]&0x0f)==0x0a)//逢10进1
  73.                                         {
  74.                                                 tempt[6]+=0x10;
  75.                                                 tempt[6]=tempt[6]&0xf0;
  76.                                                 if(tempt[6]==0xa0)//逢100变0
  77.                                                         tempt[6]=0x00;
  78.                                         }
  79.                                         //判断平年闰年2月是否溢出
  80.                                         isrun=isryear(tempt[6]);
  81.                                         if((tempt[4]==0x02)&&(tempt[3]>0x29)&&(isrun==1))
  82.                                                 tempt[3]=0x29;
  83.                                         else if((tempt[4]==0x02)&&(tempt[3]>0x28)&&(isrun==0))
  84.                                                 tempt[3]=0x28;
  85.                                         break;
  86.                                 }
  87.                                 case 2://月
  88.                                 {
  89.                                         tempt[4]+=0x01;
  90.                                         if((tempt[4]&0x0f)==0x0a)//逢10进1
  91.                                         {
  92.                                                 tempt[4]+=0x10;//前4位进位
  93.                                                 tempt[4]=tempt[4]&0xf0;//后4位置0
  94.                                         }
  95.                                         if(((tempt[4]&0x0f)==0x03)&((tempt[4]&0xf0)==0x10))//逢13变1
  96.                                                 tempt[4]=0x01;
  97.                                         //检查调整月之后的日期有没有溢出
  98.                                         isrun=isryear(tempt[6]);
  99.                                         if((tempt[4]==0x02)&&(tempt[3]>0x29)&&(isrun==1))//29天月
  100.                                                 tempt[3]=0x29;
  101.                                         else if((tempt[4]==0x02)&&(tempt[3]>0x28)&&(isrun==0))//28天月
  102.                                                 tempt[3]=0x28;
  103.                                         else if(((tempt[4]==0x01)||(tempt[4]==0x03)||(tempt[4]==0x05)//31天月
  104.                                                 ||(tempt[4]==0x07)||(tempt[4]==0x08)||(tempt[4]==0x10)
  105.                                                 ||(tempt[4]==0x12))&&(tempt[3]>0x31))
  106.                                                 tempt[3]=0x31;
  107.                                         else if(((tempt[4]==0x04)||(tempt[4]==0x06)||(tempt[4]==0x09)//30天月
  108.                                                 ||(tempt[4]==0x11))&&(tempt[3]>0x30))
  109.                                                 tempt[3]=0x30;
  110.                                         break;
  111.                                 }
  112.                                 case 3://日
  113.                                 {
  114.                                         tempt[3]+=0x01;
  115.                                         if((tempt[3]&0x0f)==0x0a)//逢10进1
  116.                                         {
  117.                                                 tempt[3]+=0x10;
  118.                                                 tempt[3]=tempt[3]&0xf0;
  119.                                         }
  120.                                         //检查调整月之后的日期有没有溢出
  121.                                         isrun=isryear(tempt[6]);
  122.                                         if((tempt[4]==0x02)&&(tempt[3]>0x29)&&(isrun==1))
  123.                                                 tempt[3]=0x01;
  124.                                         else if((tempt[4]==0x02)&&(tempt[3]>0x28)&&(isrun==0))
  125.                                                 tempt[3]=0x01;
  126.                                         if(((tempt[4]==0x01)||(tempt[4]==0x03)||(tempt[4]==0x05)
  127.                                                 ||(tempt[4]==0x07)||(tempt[4]==0x08)||(tempt[4]==0x10)
  128.                                                 ||(tempt[4]==0x12))&&(tempt[3]==0x32))
  129.                                                 tempt[3]=0x01;
  130.                                         if(((tempt[4]==0x04)||(tempt[4]==0x06)||(tempt[4]==0x09)
  131.                                                 ||(tempt[4]==0x11))&&(tempt[3]==0x31))
  132.                                                 tempt[3]=0x01;
  133.                                         break;
  134.                                 }
  135.                                 case 4://星期
  136.                                 {
  137.                                         tempt[5]+=0x01;
  138.                                         if(tempt[5]>0x07)
  139.                                                 tempt[5]=0x01;
  140.                                         break;
  141.                                 }
  142.                                 case 5://时
  143.                                 {
  144.                                         tempt[2]+=0x01;
  145.                                         if((tempt[2]&0x0f)==0x0a)
  146.                                         {
  147.                                                 tempt[2]+=0x10;
  148.                                                 tempt[2]=tempt[2]&0xf0;
  149.                                         }
  150.                                         if(((tempt[2]&0x0f)==0x04)&((tempt[2]&0xf0)==0x20))
  151.                                                 tempt[2]=0x00;
  152.                                         break;
  153.                                 }
  154.                                 case 6://分
  155.                                 {
  156.                                         tempt[1]+=0x01;
  157.                                         if((tempt[1]&0x0f)==0x0a)
  158.                                         {
  159.                                                 tempt[1]+=0x10;
  160.                                                 tempt[1]=tempt[1]&0xf0;
  161.                                         }
  162.                                         if(tempt[1]==0x60)
  163.                                                 tempt[1]=0x00;
  164.                                         break;
  165.                                 }
  166.                                 case 7://秒
  167.                                 {
  168.                                         tempt[0]+=0x01;
  169.                                         if((tempt[0]&0x0f)==0x0a)
  170.                                         {
  171.                                                 tempt[0]+=0x10;
  172.                                                 tempt[0]=tempt[0]&0xf0;
  173.                                         }
  174.                                         if(tempt[0]==0x60)
  175.                                                 tempt[0]=0x00;
  176.                                         break;
  177.                                 }
  178.                                 case 8://闹表时
  179.                                 {
  180.                                         stime[1]+=0x01;
  181.                                         if((stime[1]&0x0f)==0x0a)
  182.                                         {
  183.                                                 stime[1]+=0x10;
  184.                                                 stime[1]=stime[1]&0xf0;
  185.                                         }
  186.                                         if(((stime[1]&0x0f)==0x04)&&((stime[1]&0xf0)==0x20))
  187.                                                 stime[1]=0x00;
  188.                 Ds1302Write(0x8e,0x00);//关闭写保护
  189.                                         Ds1302Write(0xc0,stime[0]);
  190.                                         Ds1302Write(0xc2,stime[1]);
  191.                 Ds1302Write(0x8e,0x80);//打开写保护

  192.                                         break;
  193.                                 }
  194.                                 case 9://闹表分
  195.                                 {
  196.                                         stime[0]+=0x01;
  197.                                         if((stime[0]&0x0f)==0x0a)
  198.                                         {
  199.                                                 stime[0]+=0x10;
  200.                                                 stime[0]=stime[0]&0xf0;
  201.                                         }
  202.                                         if(((stime[0]&0x0f)==0x00)&&((stime[0]&0xf0)==0x60))
  203.                                                 stime[0]=0x00;
  204.                 Ds1302Write(0x8e,0x00);//关闭写保护
  205.                                         Ds1302Write(0xc0,stime[0]);
  206.                                         Ds1302Write(0xc2,stime[1]);
  207.                 Ds1302Write(0x8e,0x80);//打开写保护
  208.                                         break;
  209.                                 }

  210.                         }
  211.                 }
  212.                 while(!key2);
  213.         }
  214.         if(key3==0)//选中位置-1
  215.         {
  216.                 delayms(30);
  217.                 if(key3==0)
  218.                 {
  219.                         switch(stat)
  220.                         {
  221.                                 case 1://年
  222.                                 {
  223.                                         if(tempt[6]==0x00)//逢00变99
  224.                                                         tempt[6]=0x99;
  225.                                         else if((tempt[6]&0x0f)==0x00)//逢0进9
  226.                                         {
  227.                                                 tempt[6]-=0x10;
  228.                                                 tempt[6]=tempt[6]|0x09;
  229.                                         }
  230.                                         else tempt[6]--;
  231.                                         //检查调整月之后的日期有没有溢出
  232.                                         isrun=isryear(tempt[6]);
  233.                                         //判断平年闰年2月是否溢出
  234.                                         if((tempt[4]==0x02)&&(tempt[3]>0x29)&&(isrun==1))
  235.                                                 tempt[3]=0x29;
  236.                                         else if((tempt[4]==0x02)&&(tempt[3]>0x28)&&(isrun==0))
  237.                                                 tempt[3]=0x28;
  238.                                         break;
  239.                                 }
  240.                                 case 2://月
  241.                                 {
  242.                                         if(((tempt[4]&0x0f)==0x01)&((tempt[4]&0xf0)==0x00))//逢1变12
  243.                                                 tempt[4]=0x12;
  244.                                         else if((tempt[4]&0x0f)==0x00)//10变9
  245.                                         {
  246.                                                 tempt[4]=0x09;
  247.                                         }
  248.                                         else tempt[4]-=0x01;
  249.                                         //检查调整月之后的日期有没有溢出
  250.                                         isrun=isryear(tempt[6]);
  251.                                         if((tempt[4]==0x02)&&(tempt[3]>0x29)&&(isrun==1))
  252.                                                 tempt[3]=0x29;
  253.                                         else if((tempt[4]==0x02)&&(tempt[3]>0x28)&&(isrun==0))
  254.                                                 tempt[3]=0x28;
  255.                                         else if(((tempt[4]==0x01)||(tempt[4]==0x03)||(tempt[4]==0x05)
  256.                                                 ||(tempt[4]==0x07)||(tempt[4]==0x08)||(tempt[4]==0x10)
  257.                                                 ||(tempt[4]==0x12))&&(tempt[3]>0x31))
  258.                                                 tempt[3]=0x31;
  259.                                         else if(((tempt[4]==0x04)||(tempt[4]==0x06)||(tempt[4]==0x09)
  260.                                                 ||(tempt[4]==0x11))&&(tempt[3]>0x30))
  261.                                                 tempt[3]=0x30;
  262.                                         break;
  263.                                 }
  264.                                 case 3://日
  265.                                 {
  266.                                         //检查调整月之后的日期有没有溢出
  267.                                         isrun=isryear(tempt[6]);
  268.                                         if((tempt[4]==0x02)&&(tempt[3]==0x01)&&(isrun==1))
  269.                                                 tempt[3]=0x29;
  270.                                         else if((tempt[4]==0x02)&&(tempt[3]==0x01)&&(isrun==0))
  271.                                                 tempt[3]=0x28;
  272.                                         else if(((tempt[4]==0x01)||(tempt[4]==0x03)||(tempt[4]==0x05)
  273.                                                 ||(tempt[4]==0x07)||(tempt[4]==0x08)||(tempt[4]==0x10)
  274.                                                 ||(tempt[4]==0x12))&&(tempt[3]==0x01))
  275.                                                 tempt[3]=0x31;
  276.                                         else if(((tempt[4]==0x04)||(tempt[4]==0x06)||(tempt[4]==0x09)
  277.                                                 ||(tempt[4]==0x11))&&(tempt[3]==0x01))
  278.                                                 tempt[3]=0x30;
  279.                                         else if((tempt[3]&0x0f)==0x00)//逢0借1变9
  280.                                         {
  281.                                                 tempt[3]-=0x10;
  282.                                                 tempt[3]=tempt[3]|0x09;
  283.                                         }
  284.                                         else         tempt[3]-=0x01;
  285.                                         break;
  286.                                 }
  287.                                 case 4://星期
  288.                                 {
  289.                                         tempt[5]-=0x01;
  290.                                         if(tempt[5]==0x00)
  291.                                                 tempt[5]=0x07;
  292.                                         break;
  293.                                 }
  294.                                 case 5://时
  295.                                 {
  296.                                         if(tempt[2]==0x00)
  297.                                                 tempt[2]=0x23;
  298.                                         else if((tempt[2]&0x0f)==0x00)
  299.                                         {
  300.                                                 tempt[2]-=0x10;
  301.                                                 tempt[2]=tempt[2]|0x09;
  302.                                         }
  303.                                         else tempt[2]-=0x01;
  304.                                         break;
  305.                                 }
  306.                                 case 6://分
  307.                                 {
  308.                                         if(tempt[1]==0x00)
  309.                                         {
  310.                                                 tempt[1]=0x59;
  311.                                         }
  312.                                         else if((tempt[1]&0x0f)==0x00)
  313.                                         {
  314.                                                 tempt[1]-=0x10;
  315.                                                 tempt[1]=tempt[1]|0x09;
  316.                                         }
  317.                                         else tempt[1]-=0x01;
  318.                                         break;
  319.                                 }
  320.                                 case 7://秒
  321.                                 {
  322.                                         if(tempt[0]==0x00)
  323.                                                 tempt[0]=0x59;
  324.                                         else if((tempt[0]&0x0f)==0x00)
  325.                                         {
  326.                                                 tempt[0]-=0x10;
  327.                                                 tempt[0]=tempt[0]|0x09;
  328.                                         }
  329.                                         else tempt[0]-=0x01;
  330.                                         break;
  331.                                 }
  332.                                 case 8://闹表时
  333.                                 {
  334.                                         if(stime[1]==0x00)
  335.                                                 stime[1]=0x23;
  336.                                         else if((stime[1]&0x0f)==0x00)
  337.                                         {
  338.                                                 stime[1]-=0x10;
  339.                                                 stime[1]=stime[1]|0x09;
  340.                                         }
  341.                                         else stime[1]-=0x01;
  342.                 Ds1302Write(0x8e,0x00);//关闭写保护
  343.                                         Ds1302Write(0xc0,stime[0]);
  344.                                         Ds1302Write(0xc2,stime[1]);
  345.                 Ds1302Write(0x8e,0x80);//打开写保护
  346.                                         break;
  347.                                 }
  348.                                 case 9://闹表分
  349.                                 {
  350.                                         if(stime[0]==0x00)
  351.                                                 stime[0]=0x59;
  352.                                         else if((stime[0]&0x0f)==0x00)
  353.                                         {
  354.                                                 stime[0]-=0x10;
  355.                                                 stime[0]=stime[0]|0x09;
  356.                                         }
  357.                                         else stime[0]-=0x01;
  358.                 Ds1302Write(0x8e,0x00);//关闭写保护
  359.                                         Ds1302Write(0xc0,stime[0]);
  360.                                         Ds1302Write(0xc2,stime[1]);
  361.                 Ds1302Write(0x8e,0x80);//打开写保护
  362.                                         break;
  363.                                 }

  364.                         }
  365.                 }
  366.                 while(!key3);
  367.         }
  368.         if(key4==0)//设置
  369.         {
  370.                 delayms(30);
  371.                 if(key4==0)
  372.                 {
  373.                                 stat=0;
  374.                 }
  375.                 while(!key4);
  376.                 //退出设置读取闹表时间
  377.                 stime[0]=Ds1302Read(0xc1);
  378.                 stime[1]=Ds1302Read(0xc3);
  379.         }
  380.         if(stat>0)
  381.         {
  382.                 Ds1302Write(0x8e,0x00);//关闭写保护
  383.                 for(n=0;n<8;n++){
  384.                                  Ds1302Write(WRITE_RTC_ADDR[n],tempt[n]);
  385.                 }
  386.                 Ds1302Write(0x8e,0x80);//打开写保护
  387.         }
  388. }
  389. void showtime()//显示正常时间
  390. {
  391.         Ds1302readTime(p3);//读取时间
  392.         dispros(p1,p2,p3);//转换时间
  393.         Lcdwritedat(0x80,mdate);//显示日期
  394.         Lcdwritedat(0x80+0x40,mtime);//显示时间
  395. }
  396. void showntime()//显示闹表设置
  397. {
  398.                 stime[0]=Ds1302Read(0xc1);
  399.                 stime[1]=Ds1302Read(0xc3);
  400.                 ntime[0]=stime[1]/16+0x30;
  401.                 ntime[1]=stime[1]%16+0x30;
  402.                 ntime[2]=':';
  403.                 ntime[3]=stime[0]/16+0x30;
  404.                 ntime[4]=stime[0]%16+0x30;
  405.                 ntime[5]=0;

  406.                 Lcdwritedat(0x80,"Set Alarm Time: ");
  407.                 Lcdwritedat(0x80+0x40,ntime);//显示时间
  408.                 Lcdwritedat(0x80+0x40+5,"   ");//显示温度之前空格
  409. }
  410. void Timer0Init()
  411. {
  412.         TMOD=0x01; //设置定时器0工作方式为1
  413.         TH0=(65536-45872)/256;
  414.         TL0=(65536-45872)%256;
  415.         ET0=1; //开启定时器0中断
  416.         TR0=1;        //开启定时器        
  417.         EA=1;  //打开总中断
  418. }
  419. ……………………

  420. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
全部代码51hei下载地址:
万年历.zip (74.74 KB, 下载次数: 99)

评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:889094 发表于 2021-3-24 19:17 | 显示全部楼层
感谢中间各路大神有帮助,基本算起步了,继续努力

评分

参与人数 1黑币 +15 收起 理由
wulin + 15 动手能力不错,算入门了,再接再厉。

查看全部评分

回复

使用道具 举报

ID:584814 发表于 2021-3-25 14:42 | 显示全部楼层
这里是提问区,建议移到应该去的地方
回复

使用道具 举报

ID:377210 发表于 2021-3-25 20:17 | 显示全部楼层
厉害了,晶振也在面包板上飞线
回复

使用道具 举报

ID:230742 发表于 2021-3-26 00:45 | 显示全部楼层
1302三根线要接3个上拉电阻。4.7K就行。要想时间准一点,1302的晶振也接两个6P的电容到负极。试一下。
回复

使用道具 举报

ID:403593 发表于 2021-3-26 08:10 | 显示全部楼层
赞一个!恭喜顺利入坑。。。
回复

使用道具 举报

ID:889094 发表于 2021-3-30 20:40 | 显示全部楼层
啤酒瓶子老大 发表于 2021-3-26 00:45
1302三根线要接3个上拉电阻。4.7K就行。要想时间准一点,1302的晶振也接两个6P的电容到负极。试一下。

嗯,谢谢指导,也没做成板子,只是练习熟悉一下模块
回复

使用道具 举报

ID:914561 发表于 2021-4-30 18:29 | 显示全部楼层
手绘原理图,功底可以
回复

使用道具 举报

ID:59830 发表于 2021-5-1 10:59 | 显示全部楼层
现在很少用  笔画 原理图 , 想起以前 我也是这样.  
现在大家对电脑依赖太大了.
多多向这位学习.
回复

使用道具 举报

ID:889094 发表于 2021-5-3 15:39 | 显示全部楼层
yygdzjs 发表于 2021-5-1 10:59
现在很少用  笔画 原理图 , 想起以前 我也是这样.  
现在大家对电脑依赖太大了.
多多向这位学习.

不是想手绘,新手,开始不会用软件画,后面学了点,现在勉强能用软件画点简单的了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表