×
单片机 > 单片机程序设计 > 详情

DS1302+AT24C02+按键数码管显示程序

发布时间:2020-06-04 发布时间:
|
  1. #include  

  2. #include  

  3. #define uint unsigned int  

  4. #define uchar unsigned char  

  5. bit write=0;  

  6. sbit led0=P1^5;  

  7. sbit led1=P1^6;  

  8. sbit led2=P1^7;  

  9.   

  10. sbit sda=P1^1;  

  11. sbit scl=P1^0;  

  12.   

  13. sbit SCLK=P3^5;     

  14. sbit DATA=P3^6;     

  15. sbit RST=P3^7;  

  16.   

  17. sbit sg=P2^7;  

  18. sbit ss=P2^6;  

  19. sbit sb=P2^5;  

  20. sbit sq=P2^4;  

  21. uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};   

  22. uchar second,minute=0;  

  23. uchar sec;  

  24. sbit beep=P3^4;         // 0  

  25. uint state=0;           // 0:时钟状态 1:设置秒 2:设置分 3:初始设置状态  

  26. sbit key1=P2^1;         // 进入设定模式以及 确认设置    先设置秒 后设置分  

  27. sbit key3=P2^0;         //          ++  

  28. sbit key4=P2^2;         //          --  

  29. uchar count=0;   

  30. void display();  

  31. void delay()  

  32. {;;}  

  33. void delayms(uint ms)  

  34. {  

  35.     uint i,j;  

  36.     for(i=ms;i>0;i--);  

  37.         for(j=110;j>0;j--);  

  38. }  

  39. /******************/  

  40. void start()  

  41. {  

  42.     sda=1;  

  43.     delay();  

  44.     scl=1;  

  45.     _nop_();  

  46.     _nop_();  

  47.     _nop_();  

  48.     _nop_();  

  49.     _nop_();  

  50.     sda=0;  

  51.     _nop_();  

  52.     _nop_();  

  53.     _nop_();  

  54.     _nop_();  

  55.     _nop_();  

  56.       

  57. }  

  58. void stop()  

  59. {  

  60.     sda=0;  

  61.     _nop_();  

  62.     scl=1;  

  63.     _nop_();  

  64.     _nop_();  

  65.     _nop_();  

  66.     _nop_();  

  67.     _nop_();  

  68.     sda=1;  

  69.     _nop_();  

  70.     _nop_();  

  71.     _nop_();  

  72.     _nop_();  

  73. }  

  74. void respons()   

  75. {     

  76.       

  77.     uchar i;  

  78.     scl=1;  

  79.     delay();  

  80.     while((sda==1)&&(i<100))i++;  

  81.     scl=0;  

  82.     delay();  

  83. }  

  84. void initAT()  

  85. {  

  86.     sda=1;  

  87.     delay();  

  88.     scl=1;  

  89.     delay();  

  90. }  

  91. void write_byte(uchar date)  

  92. {  

  93.     uchar i,temp;  

  94.     temp=date;  

  95.     for(i=0;i<8;i++)  

  96.     {  

  97.         temp=temp<<1;  

  98.         scl=0;  

  99.         delay();  

  100.         sda=CY;  

  101.         delay();  

  102.         scl=1;  

  103.         delay();  

  104.     }  

  105.     scl=0;  

  106.     delay();  

  107.     sda=1;  

  108.     delay();  

  109. }  

  110. uchar read_byte()  

  111. {  

  112.     uchar i,k;  

  113.     scl=0;  

  114.     delay();  

  115.     sda=1;  

  116.     delay();  

  117.     for(i=0;i<8;i++)  

  118.     {  

  119.         scl=1;  

  120.         delay();  

  121.         k=(k<<1)|sda;  

  122.         scl=0;  

  123.         delay();  

  124.     }  

  125.     return k;  

  126. }  

  127. void write_add(uchar address,uchar date)  

  128. {  

  129.     start();  

  130.     write_byte(0xa0);          //1010 000 0 0为读 1为写  

  131.     respons();  

  132.     write_byte(address);  

  133.     respons();  

  134.     write_byte(date);  

  135.     respons();  

  136.     stop();   

  137. }  

  138. uchar read_add(uchar address)  

  139. {  

  140.     uchar date;  

  141.     start();  

  142.     write_byte(0xa0);  

  143.     respons();  

  144.     write_byte(address);  

  145.     respons();  

  146.     start();  

  147.     write_byte(0xa1);           //1010 000 1  

  148.     respons();  

  149.     date=read_byte();  

  150.     stop();  

  151.     return date;  

  152. }  

  153. /*************************************************/  

  154. void write1302(uchar dat)  

  155. {  

  156.   uchar i;   

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

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

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

  160.     {  

  161.          DATA=dat&0x01;    //取出dat的第0位数据写入1302  低位在前,高位在后  

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

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

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

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

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

  167.       }  

  168. }   

  169. void writeset1302(uchar Cmd,uchar dat)  

  170.  {      

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

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

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

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

  175.         write1302(Cmd);  //写入命令字  

  176.         write1302(dat);  //写数据  

  177.         SCLK=1;          //将时钟电平置于高电平状态  

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

  179.  }    

  180.  uchar Read1302()  

  181.  {  

  182.     uchar i,dat;  

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

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

  185.      {   dat>>=1;  

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

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

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

  189.          _nop_();  //稍微等待  

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

  191.          _nop_();  

  192.       }    

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

  194. }   

  195. uchar ReadSet1302(uchar Cmd)  

  196.  {  

  197.     uchar dat;  

  198.     RST=0;                 //拉低RST  

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

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

  201.     write1302(Cmd);       //写入命令字  

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

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

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

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

  206. }  

  207. void confirm()  

  208. {  

  209.     uchar ReadValue;  

  210.     ReadValue = ReadSet1302(0x81);   //从秒寄存器读数据  

  211.     second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//将读出数据转化              //0x70=01110000 &同为同 异为0 保留111位  0x0f=1111 保留后四位  

  212.     ReadValue = ReadSet1302(0x83);  //从分寄存器读  

  213.     minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化  

  214. }  

  215. /********************************************************************************************************************/  

  216. void init_DS1302()  

  217. {     

  218.     uchar flag;  

  219.     flag= ReadSet1302(0x81);  

  220.     if(flag&0x80)     

  221.     {      //判断时钟芯片是否关闭  

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

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

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

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

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

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

  228.         writeset1302(0x8c,((9/10)<<4|(9%10)));   //根据写年寄存器命令字,写入年的初始值  

  229.         writeset1302(0x90,0xa5);                //打开充电功能 选择2K电阻充电方式  

  230.         writeset1302(0x8E,0x80);              //根据写状态寄存器命令字,写入保护指令  

  231.     }  

  232. }  

  233. void bee()  

  234. {  

  235.     beep=0;  

  236.     delayms(100);  

  237.     beep=1;  

  238. }  

  239. void display()       //先秒后分  

  240. {   

  241.     if(state==0||state==3)  

  242.         {  

  243.             uchar ge0,ge1,shi1,shi0;  

  244.             ge0=second%10;  

  245.             shi0=second/10;  

  246.             ge1=minute%10;  

  247.             shi1=minute/10;  

  248.   

  249.             sq=0;  

  250.             P0=table[ge0];  

  251.             delayms(5);  

  252.             sq=1;  

  253.             P0=0xff;  

  254.               

  255.             sb=0;  

  256.             P0=table[shi0];  

  257.             delayms(5);  

  258.             sb=1;  

  259.             P0=0xff;  

  260.               

  261.             ss=0;  

  262.             P0=table[ge1];  

  263.             delayms(5);  

  264.             ss=1;  

  265.             P0=0xff;  

  266.               

  267.             sg=0;  

  268.             P0=table[shi1];  

  269.             delayms(5);  

  270.             sg=1;  

  271.             P0=0xff;  

  272.         }  

  273.     else  

  274.     {  

  275.             uchar ge,shi;  

  276.             ge=count%10;  

  277.             shi=count/10;  

  278.             sq=0;  

  279.             P0=table[ge];  

  280.             delayms(5);  

  281.             sq=1;  

  282.             P0=0xff;  

  283.             sb=0;  

  284.             P0=table[shi];  

  285.             delayms(5);  

  286.             sb=1;  

  287.             P0=0xff;  

  288.     }  

  289. }  

  290. void steins()             // 将设置后的数据存入时钟模块内  

  291. {  

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

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

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

  295.     writeset1302(0x8E,0x80);              //根据写状态寄存器命令字,写入保护指令  

  296. }  

  297. void keyscan()  

  298. {  

  299.     if(key1==0)   // 进入设定模式0 1 2 &确认设置  PS:先设置秒 后设置分  

  300.     {  

  301.         delayms(10);  

  302.         if(key1==0)  

  303.         {   while(!key1)display();  

  304.             display();  

  305.             bee();  

  306.             if(state==0)  

  307.                 {  

  308.                     led0=0;  

  309.                     led1=1;  

  310.                     led2=1;  

  311.                     state=3;  

  312.                 }  

  313.             else  

  314.                 {  

  315.                     if(state==3)  

  316.                     {  

  317.                         led0=1;  

  318.                         led1=0;  

  319.                         led2=1;  

  320.                         state=1;  

  321.                         count=second;  

  322.                     }     

  323.                     else  

  324.                     {     

  325.                         if(state==1)   //s  

  326.                         {     

  327.                             led0=1;  

  328.                             led1=1;  

  329.                             led2=0;  

  330.                             state=2;  

  331.                             second=count;  

  332.                             count=minute;  

  333.                         }  

  334.                         else  

  335.                         {  

  336.                             if(state==2)   //m  

  337.                             {     

  338.                             led2=0;  

  339.                             led1=0;  

  340.                             led0=0;  

  341.                             state=0;  

  342.                             minute=count;  

  343.                             count=0;  

  344.                             steins();  

  345.                             }  

  346.                         }  

  347.                     }  

  348.                 }  

  349.               

  350.         }  

  351.     }  

  352.     if(key3==0)    //++  

  353.     {  

  354.         delayms(10);  

  355.         if(key3==0)  

  356.         {     

  357.               

  358.             while(!key3)display();;  

  359.             display();  

  360.             bee();  

  361.             if(state==1||state==2)  

  362.                 {  

  363.                 if(count==60)  

  364.                     count=0;  

  365.                 else  

  366.                     count++;  

  367.                 }  

  368.         }  

  369.     }  

  370.     if(key4==0)    //--  

  371.     {     

  372.         delayms(10);  

  373.         if(key4==0)  

  374.         {     

  375.               

  376.             while(!key4)display();  

  377.             display();  

  378.             bee();  

  379.             if(state==1||state==2)  

  380.                 {  

  381.                 if(count==0)  

  382.                     count=60;  

  383.                 else  

  384.                     count--;  

  385.                 }  

  386.         }  

  387.     }  

  388. }  

  389.   

  390. void main()  

  391. {  

  392.     beep=1;  

  393.     led0=0;  

  394.     led1=0;  

  395.     led2=0;  

  396.     state=0;                  //引脚初始化  

  397.     initAT();                 //AT24c02初始化  

  398.     sec=read_add(2);  

  399.     second=sec%60;  

  400.     minute=sec/60;  

  401.     delayms(1);  

  402.     init_DS1302();            //DS1302初始化  

  403.     delayms(1);  

  404.     steins();                 //获取时钟数据  

  405.     while(1)  

  406.     {  

  407.         display();  

  408.         confirm();  

  409.         sec=minute*60+second;  

  410.         write_add(2,sec);  

  411.         keyscan();  

  412.     }  

  413. }  



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
ARM 汇编的必知必会