找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4432|回复: 5
收起左侧

工艺品时钟制作 高精度

[复制链接]
ID:156124 发表于 2017-4-30 16:38 | 显示全部楼层 |阅读模式
很久没发帖了,那么来一贴,这个项目历时3个半月,因为刚开始也就做着玩。先上图。
155726.jpg
  1. #include <reg52.h>
  2. #include <intrins.h>
  3. #include<string.h>

  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. #define ulong unsigned long
  7. P4SW=0xff;
  8. uchar sec, min, hour, day, month,counter,xingqi,AL1SEC,AL1MIN,AL1HOUR,AL1DAY,AL2MIN,AL2HOUR,AL2DAY,AMZT;
  9. uchar EDA=7;
  10. uint year;
  11. bit ack;
  12. uint cnt = 0;
  13. uchar i = 0;
  14. uchar j = 10;
  15. sbit leden1 = P0^1;
  16. sbit leden2 = P0^3;
  17. sbit leden3 = P0^7;
  18. sbit leden4 = P2^7;
  19. sbit leden5 = P0^6;
  20. sbit led1 = P0^0;
  21. sbit led2 = P0^2;
  22. sbit led3 = P0^4;
  23. sbit led4 = P4^4;
  24. sbit led5 = P2^6;
  25. sbit led6 = P2^2;
  26. sbit led7 = P2^0;


  27. sbit SDA=P2^4;     //模拟I2C数据传送位SDA           
  28. sbit SCL=P2^5;     //模拟I2C时钟控制位SCL

  29. #define ADDRTW          0xD0    //器件写地址
  30. #define ADDRTD          0xD1 //器件读地址
  31. #define DS3231_SEC      0x00   //秒
  32. #define DS3231_MIN      0x01   //分
  33. #define DS3231_HOUR     0x02   //时
  34. #define DS3231_DAY      0x03   //星期
  35. #define DS3231_DATE     0x04   //日
  36. #define DS3231_MONTH    0x05   //月
  37. #define DS3231_YEAR     0x06   //年
  38. //闹铃1            
  39. #define DS3231_Al1SEC   0x07   //秒
  40. #define DS3231_AL1MIN   0x08   //分
  41. #define DS3231_AL1HOUR  0x09   //时
  42. #define DS3231_AL1DAY   0x0A   //星期/日
  43. //闹铃2
  44. #define DS3231_AL2MIN   0x0b   //分
  45. #define DS3231_AL2HOUR  0x0c   //时
  46. #define DS3231_AL2DAY   0x0d   //星期/日
  47. #define DS3231_CONTROL  0x0e   //控制寄存器
  48. #define DS3231_STATUS   0x0f   //状态寄存器
  49. bit ack;




  50. void ledyinshe( ulong  j )   
  51. {  led1=1;led2=1;led3=1;led4=1;led5=1;led6=1;led7=1;

  52. switch(j)
  53. {
  54.    case 0: led1=0;led2=0;led3=0;led4=1;led5=0;led6=0;led7=0; break;
  55.   case 1: led1=1;led2=0;led3=1;led4=1;led5=0;led6=1;led7=1; break;
  56.   case 2: led1=0;led2=1;led3=0;led4=0;led5=0;led6=1;led7=0; break;
  57.   case 3: led1=0;led2=0;led3=1;led4=0;led5=0;led6=1;led7=0; break;
  58.   case 4: led1=1;led2=0;led3=1;led4=0;led5=0;led6=0;led7=1; break;
  59.   case 5: led1=0;led2=0;led3=1;led4=0;led5=1;led6=0;led7=0; break;
  60.   case 6: led1=0;led2=0;led3=0;led4=0;led5=1;led6=0;led7=0; break;
  61.   case 7: led1=1;led2=0;led3=1;led4=1;led5=0;led6=0;led7=0; break;
  62.   case 8: led1=0;led2=0;led3=0;led4=0;led5=0;led6=0;led7=0; break;
  63.   case 9: led1=0;led2=0;led3=1;led4=0;led5=0;led6=0;led7=0; break;
  64.   case 10:led1=1;led2=1;led3=1;led4=1;led5=1;led6=1;led7=0; break;
  65.   case 11:led1=1;led2=1;led3=1;led4=0;led5=1;led6=1;led7=1; break;
  66.   case 12:led1=0;led2=1;led3=1;led4=1;led5=1;led6=1;led7=1; break;
  67.   case 13:led1=1;led2=1;led3=1;led4=1;led5=1;led6=1;led7=1; break;
  68.   default:break;
  69. }
  70. }
  71. void Delay100us()  [url=]//@11.0592MHz[/url]
  72. {
  73. unsigned char i, j;
  74. _nop_();
  75. _nop_();
  76. i = 2;
  77. j = 15;
  78. do
  79. {
  80.   while (--j);
  81. } while (--i);
  82. }
  83. void delay1ms(uchar j)
  84. {
  85. while(j!=0)
  86. {uchar i;
  87. for(i=124;i>0;i--);  //延时124*8+10=1002us
  88. j--;
  89. }
  90. }
  91. void delay1(unsigned char i)
  92. {
  93. for(i;i>0;i--);
  94. }
  95. uchar BCD2HEX(uchar val)           //BCD转换为Byte           
  96. {  uchar i;
  97.    i= val&0x0f;
  98.    val >>= 4;
  99.    val &= 0x0f;
  100.    val *= 10;
  101.     i+= val;
  102.    return i;
  103. }
  104. uchar BCD2HEX2(uchar val)           //BCD转换为Byte           
  105. {  uchar i;
  106.    i= val&0x0f;
  107.    val >>= 4;
  108.    val &= 0x07;
  109.    val *= 10;
  110.     i+= val;
  111.    return i;
  112. }

  113. uchar BCD2HEXAM(uchar val)           //BCD转换为Byte           
  114. {  uchar i;
  115.    i= val&0x03;  
  116.    return i;
  117. }
  118. uchar HEX2BCD(uchar val)//B码转换为BCD码
  119.          {
  120.          uchar i,j,k;
  121.            i=val/10;
  122.            j=val%10;
  123.            k=j+(i<<4);
  124.            return k;
  125.          }
  126.    uchar HEX2BCDAM(uchar val)//B码转换为BCD码
  127.          {
  128.          uchar i,j,k;
  129.            i=val/10;
  130.            j=val%10;
  131.            k=j+(i<<4);
  132.      k|=0x80;
  133.            return k;
  134.          }
  135. void Start()      
  136. {
  137.    SDA=1;                  //发送起始条件的数据信号
  138.    delay1(1);
  139.    SCL=1;
  140.    delay1(5);             //起始条件建立时间大于4.7us,延时
  141.      SDA=0;                  //发送起始信号
  142.    delay1(5);             // 起始条件锁定时间大于4μs
  143.    SCL=0;                  //钳住I2C总线,准备发送或接收数据
  144.    delay1(2);
  145. }
  146. void Stop()
  147. {
  148.    SDA=0;                  //发送结束条件的数据信号
  149.    delay1(1);             //发送结束条件的时钟信号
  150.    SCL=1;                  //结束条件建立时间大于4us
  151.     delay1(5);
  152.    SDA=1;                  //发送I2C总线结束信号
  153.    delay1(4);
  154. }
  155. /********************************************************/
  156. /*******************************************************************
  157.                   字节数据发送函数               
  158. 函数原型:     void  SendByte(uchar Dat);
  159. 功能:      将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
  160.           此状态位进行操作.(不应答或非应答都使ack=0)
  161.           ack=1        发送数据正常,
  162.           ack=0        被控器无应答或损坏。
  163. ********************************************************************/
  164. void SendByte(uchar Dat)
  165. {
  166. uchar BitCnt;
  167.    for(BitCnt=0;BitCnt<8;BitCnt++)         //要传送的数据长度为8位
  168.     {
  169.        if((Dat<<BitCnt)&0x80)
  170.            SDA=1;                          //判断发送位
  171.        else
  172.            SDA=0;               
  173.          delay1(1);
  174.          SCL=1;                            //置时钟线为高,通知被控器开始接收数据位
  175.          delay1(5);                       //保证时钟高电平周期大于4μs   
  176.          SCL=0;
  177.     }
  178.    delay1(2);
  179.    SDA=1;                                 //8位发送完后释放数据线,准备接收应答位
  180.    delay1(2);  
  181.    SCL=1;
  182.     delay1(3);
  183.    if(SDA==1)
  184.        ack=0;   
  185.    else
  186.        ack=1;                             //判断是否接收到应答信号
  187.    SCL=0;
  188.    delay1(2);
  189. }
  190. uchar RcvByte()                                                                                  //功能:     用来接收从器件传来的数据,并判断总线错误(不发应答信号),发完后请用应答函数应答从机。
  191. {
  192. uchar retc;
  193. uchar BitCnt;
  194.   retc=0;
  195.   SDA=1;                          //置数据线为输入方式
  196.   for(BitCnt=0;BitCnt<8;BitCnt++)
  197.    {
  198.        delay1(1);  
  199.        SCL=0;                      //置时钟线为低,准备接收数据位
  200.        delay1(5);                 //时钟低电平周期大于4.7μs
  201.        SCL=1;                      //置时钟线为高使数据线上数据有效
  202.        delay1(3);
  203.        retc=retc<<1;
  204.        if(SDA==1)
  205.            retc=retc+1;            //读数据位,接收的数据位放入retc中
  206.        delay1(2);
  207.    }
  208.   SCL=0;
  209.   delay1(2);
  210.   return(retc);
  211. }
  212. void I2CACK(bit a)                       // 功能:       主控器进行应答信号(可以是应答或非应答信号,由位参数a决定)
  213. {
  214.    if(a==0)
  215.        SDA=0;              //在此发出应答或非应答信号
  216.    else
  217.        SDA=1;
  218.    delay1(3);     
  219.    SCL=1;
  220.    delay1(5);             //时钟低电平周期大于4μs
  221.    SCL=0;                  //清时钟线,钳住I2C总线以便继续接收
  222.    delay1(2);   
  223. }
  224. uchar I2CRead()                                                                                  /************从DS3231当前地址读一个字节************/
  225. {
  226. uchar read_data;
  227.          Start();
  228.    SendByte(ADDRTD);                                             
  229.    if(ack==0)
  230.     {
  231. return(0);
  232.     }
  233.    read_data = RcvByte();
  234.    I2CACK(1);
  235.    Stop();
  236.    return read_data;
  237. }
  238. uchar I2CReadAdd(uchar addr)                                                      /************从DS3231指定地址读一个字节************/
  239.          {
  240.              Start();
  241.              SendByte(ADDRTW);                           
  242.              if(ack==0)
  243.              {        
  244.            return(0);
  245.              }
  246.              SendByte(addr);
  247.              if(ack==0)
  248.              {        
  249.            return(0);
  250.              }
  251.              return(I2CRead());
  252.          }
  253. void Readtime()                                                                                            /*********************读取时间**********************/
  254.          {
  255.           uchar temp;
  256.           temp=I2CReadAdd(DS3231_SEC);//秒
  257.           sec=BCD2HEX(temp);
  258.           temp=I2CReadAdd(DS3231_MIN);//分
  259.           min=BCD2HEX(temp);
  260.           temp=I2CReadAdd(DS3231_HOUR);  //时                  
  261.           hour=BCD2HEX(temp);
  262.           temp=I2CReadAdd(DS3231_DATE);  //日
  263.           day=BCD2HEX(temp);
  264.           temp=I2CReadAdd(DS3231_MONTH); //月
  265.           month=BCD2HEX(temp);
  266.           temp=I2CReadAdd(DS3231_YEAR);  //年
  267.           year=BCD2HEX(temp);
  268.     year+=2000;
  269.     temp=I2CReadAdd(DS3231_DAY);  //星期
  270.     xingqi = BCD2HEX(temp);
  271.      temp=I2CReadAdd(DS3231_AL1MIN );  //星期
  272.     AL1MIN = BCD2HEX2(temp);
  273.      temp=I2CReadAdd(DS3231_AL1HOUR);  //星期
  274.     AL1HOUR= BCD2HEX2(temp);
  275.     temp=I2CReadAdd(DS3231_AL2MIN );  //星期
  276.     AL2MIN = BCD2HEX2(temp);
  277.      temp=I2CReadAdd(DS3231_AL2HOUR);  //星期
  278.     AL2HOUR= BCD2HEX2(temp);

  279.     temp=I2CReadAdd(DS3231_STATUS );  //星期
  280.     AMZT= BCD2HEXAM(temp);
  281.    
  282.           }
  283. void InitDS3231()                                                                                                            //ds3231初始化
  284.          {SCL=1;
  285.           delay1(5);
  286.           SDA=1;
  287.           delay1(5);
  288.          }
  289. /*  
  290. void TimeDisplay(uchar Dhour,ucharDmin,uchar Dsec)                                     //时分秒数组赋值
  291.          {
  292.       b[0]=numbr[Dhour / 10];        // 时十位
  293.              b[1]=numbr[Dhour % 10];        // 时个位
  294.              b[4]=numbr[Dmin / 10];         // 分十位
  295.              b[5]=numbr[Dmin % 10];         // 分个位
  296.              b[8]=numbr[Dsec / 10];         // 秒十位
  297.              b[9]=numbr[Dsec % 10];         // 秒个位
  298.       
  299.          }
  300.      */
  301.      /*
  302. void DateDisplay(uchar Dyear,ucharDmonth,uchar Dday)                       //年月天数组赋值   
  303.          {
  304.      
  305.       a[2]=numbr[Dyear / 10];        // 年十位
  306.              a[3]=numbr[Dyear % 10];        // 年个位
  307.              a[6]=numbr[Dmonth / 10];       // 月十位
  308.              a[7]=numbr[Dmonth % 10];       // 月个位
  309.              a[10]=numbr[Dday / 10];         // 天十位
  310.              a[11]=numbr[Dday % 10];         // 天个位     
  311.      
  312.          }
  313.      */
  314. void Start_I2C()
  315. {
  316.    SDA=1;                  //发送起始条件的数据信号
  317.    delay1(1);
  318.    SCL=1;
  319.    delay1(5);             //起始条件建立时间大于4.7us,延时
  320.    SDA=0;                  //发送起始信号
  321.    delay1(5);             // 起始条件锁定时间大于4μs
  322.    SCL=0;                  //钳住I2C总线,准备发送或接收数据
  323.    delay1(2);
  324. }
  325. void Stop_I2C()
  326. {
  327.     SDA=0;                  //发送结束条件的数据信号
  328.    delay1(1);             //发送结束条件的时钟信号
  329.    SCL=1;                  //结束条件建立时间大于4us
  330.    delay1(5);
  331.    SDA=1;                  //发送I2C总线结束信号
  332.    delay1(4);
  333. }
  334. uchar write_byte(uchar addr, uchar write_data)
  335. {
  336.    Start_I2C();
  337.    SendByte(ADDRTW);                //////*******************************************************************///////////
  338.    if (ack == 0)
  339.        return 0;
  340.    SendByte(addr);   
  341.    if (ack == 0)
  342.        return 0;
  343.    SendByte(write_data);
  344.    if (ack == 0)
  345.        return 0;
  346.    Stop_I2C();
  347.     delay1ms(10);      
  348.    return 1;
  349. }
  350. void ModifyTime(uchar yea,uchar mon,uchar da,uchar hou,uchar min,uchar sec,uchar xq,uchar AL1DAY,uchar A1HOUR,uchar A1MIN,uchar AL1SEC,uchar AL2DAY,uchar A2HOUR,uchar AL2MIN)
  351. {     uchar temp=0;
  352.    temp=HEX2BCD(yea);                 
  353.    write_byte(DS3231_YEAR,temp);   //修改年
  354.    temp=HEX2BCD(mon);
  355.    write_byte(DS3231_MONTH,temp);  //修改月
  356.    temp=HEX2BCD(da);                                                                                     /////////////////////
  357.    write_byte(DS3231_DATE,temp);   //修改日
  358.    temp=HEX2BCD(hou);
  359.    write_byte(DS3231_HOUR,temp);   //修改时
  360.    temp=HEX2BCD(min);
  361.    write_byte(DS3231_MIN,temp); //修改分
  362.    temp=HEX2BCD(sec);
  363.    write_byte(DS3231_SEC,temp); //修改秒

  364.   temp=HEX2BCD(xq);
  365.    write_byte(DS3231_DAY,temp); //修改星期
  366.    
  367.    temp=HEX2BCD(AL1SEC);
  368.    write_byte(DS3231_Al1SEC,temp); //修改星期
  369.     temp=HEX2BCD(A1MIN);
  370.    write_byte(DS3231_AL1MIN,temp); //修改星期
  371.     temp=HEX2BCD(A1HOUR);
  372.    write_byte(DS3231_AL1HOUR,temp); //修改星期
  373.     temp=HEX2BCDAM(AL1DAY);
  374.   write_byte(DS3231_AL1DAY ,temp); //修改星期
  375.    

  376. temp=HEX2BCD(AL2MIN);
  377.    write_byte(DS3231_AL2MIN,temp); //修改星期
  378.     temp=HEX2BCD(A2HOUR);
  379.    write_byte(DS3231_AL2HOUR,temp); //修改星期
  380.    temp=HEX2BCDAM(AL2DAY);
  381.    write_byte(DS3231_AL2DAY,temp); //修改星期


  382. }

  383. unsigned char str[17] ;
  384. void main()
  385. {
  386. TMOD = 0x01;
  387. TH0 = 0xFC;
  388. TL0 = 0x67;
  389. TR0 = 1;
  390. EA = 1;
  391. ET0 = 1;
  392. InitDS3231();            

  393.    ModifyTime(17,2,25,14,43,0,6,7,13,19,30,7,13,19);   //年月白时分秒星期
  394.   delay1ms(100);
  395.      Readtime();

  396.   EDA=HEX2BCD(7);
  397.   write_byte(DS3231_CONTROL ,EDA);
  398.   EDA=HEX2BCD(8);
  399.   write_byte(DS3231_STATUS ,EDA);
  400.   
  401.   delay1ms(100);
  402.   while(1)      
  403. {
  404.      
  405.   Readtime();
  406.    if(cnt >= 1000)
  407.   {
  408.    cnt = 0;
  409.    if(j<=11)j++;else j=10;
  410.    
  411.   
  412.   }
  413.   
  414.   

  415.   }  
  416. }
  417. void jianduan1()
  418. {
  419.   if(leden1==1)
  420.   {
  421. leden1=0;
  422. Delay100us();Delay100us();Delay100us();Delay100us();
  423. Delay100us(); Delay100us();Delay100us();Delay100us();
  424. Delay100us(); Delay100us();Delay100us();Delay100us();
  425.   }
  426.   else
  427.   {
  428.    leden1=1;
  429.   }
  430. }
  431. void jianduan2()
  432. {
  433.   if(leden2==1)
  434.   {
  435. leden2=0;
  436. Delay100us(); Delay100us();Delay100us();Delay100us();
  437. Delay100us(); Delay100us();Delay100us();Delay100us();
  438. Delay100us(); Delay100us();Delay100us();Delay100us();
  439.   }
  440.   else
  441.   {
  442.    leden2=1;
  443.   }
  444.   }
  445. void InterruptTimer0()  interrupt 1   
  446. {              
  447. TH0 = 0xFC;
  448. TL0 = 0x67;
  449. cnt++;

  450. led1=1;led2=1;led3=1;led4=1;led5=1;led6=1;led7=1;
  451. switch(i)
  452. {
  453.   case 0:jianduan1(); leden2=0; leden3=0;leden4=0;leden5=0;i++; ledyinshe(min%10 );break;
  454.   case 1: leden1=0;jianduan2(); leden3=0;leden4=0;leden5=0;i++; ledyinshe(min/10%10 );break;
  455.   case 2: leden1=0; leden2=0; leden3=1;leden4=0;leden5=0;i++; ledyinshe(j);break;
  456.   case 3: leden1=0; leden2=0; leden3=0;leden4=1;leden5=0;i++; ledyinshe(hour%10);break;
  457.   case 4: leden1=0; leden2=0; leden3=0;leden4=0;leden5=1;i=0; ledyinshe(hour/10%10);break;

  458.   default:;break;

  459. }
  460. }
复制代码


160108.jpg
160109.jpg
160105.jpg
160104.jpg
160102.jpg
160059.jpg
160041.jpg
160042.jpg
160055.jpg
160057.jpg
160040.jpg
160037.jpg
160035.jpg
160031.jpg
160011.jpg
160013.jpg
160016.jpg
160023.jpg
160009.jpg
160007.jpg
160005.jpg
160003.jpg
155802.jpg
155807.jpg
155810.jpg
160000.jpg
155758.jpg
155753.jpg
155751.jpg
155743.jpg
155728.jpg
155730.jpg
155739.jpg
155741.jpg
155721.jpg
155720.jpg
1.jpg
155719.jpg

电子时钟源码.rar

68.56 KB, 下载次数: 29, 下载积分: 黑币 -5

回复

使用道具 举报

ID:146089 发表于 2017-5-2 09:56 | 显示全部楼层
棚子搭的歪歪扭扭不美观
回复

使用道具 举报

ID:162238 发表于 2017-5-3 12:44 | 显示全部楼层
创意挺好的 , 个人感觉架子换成黑色的或者白色的绿色的应该会更好看
回复

使用道具 举报

ID:182887 发表于 2017-5-3 19:50 | 显示全部楼层
还是挺好看的
回复

使用道具 举报

ID:476271 发表于 2019-7-25 10:09 | 显示全部楼层
个人感觉架子换成黑色的或者白色的绿色的应该会更好
回复

使用道具 举报

ID:25899 发表于 2019-7-26 21:28 | 显示全部楼层
这自己做数码管有创意
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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