久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3116|回復: 12
打印 上一主題 下一主題
收起左側

單片機+1302數碼管時鐘程序調不了時間

[復制鏈接]
跳轉到指定樓層
樓主
ID:725922 發表于 2021-9-26 00:07 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
參考了幾個程序的核心部分,自己修改組合了一下,就想實現一個基本的可調時鐘。一共3個按鍵,設置,加,減。按設置可以在時,分鐘之間切換,同時相應位會閃爍。秒是采用的led指示,通過定時器中斷試驗出的計數值來控制,不是特別準確,主要起裝飾作用。。目前的現象是,能按照初始時間走時,按設置能切換閃爍,但無法加減小時或者分鐘,應該是往1302寫數據的程序有問題,但也沒看出來有什么問題,沒有解決的思路了,希望各位高手指點一下錯誤。

單片機源程序如下:
  1. #include<reg52.h>
  2. #include <intrins.h>
  3. #define uint unsigned int
  4. #define uchar unsigned char
  5. uint milsec;
  6. uchar i,t,a,d,sec,hour,hour1,min,min1,flag,temp,key=0,S_flag=0,k=0;

  7. unsigned char led[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};  //用一維數組定義0-9、橫杠、全滅

  8. unsigned char b[4]={0x07,0x0b,0x0d,0x0e}; //掃描

  9. unsigned char c[4];

  10. sbit dula=P2^6;
  11. sbit wela=P2^7;

  12. sbit SCLK=P1^0;    //1302接口
  13. sbit IO=P1^1;
  14. sbit RST=P1^2;

  15. sbit ACC0=ACC^0;
  16. sbit ACC7=ACC^7;

  17. //sbit key=P3^7;                //按鍵接口
  18. sbit key1=P3^3;
  19. sbit key2=P3^1;
  20. sbit key3=P3^2;
  21. sbit S5=P1^3;                 //指示秒的led

  22. void delay(uint xms)//ms延時函數
  23. {
  24.         uint x,y;
  25.         for(x=xms;x>0;x--)
  26.          for(y=110;y>0;y--);
  27. }


  28. /*********************over***********************/
  29. /********************ds1302****************************/
  30. void write_byte(uchar dat)
  31. {
  32.         ACC=dat;
  33.         RST=1;
  34.         for(a=8;a>0;a--)
  35.         {
  36.                 IO=ACC0;
  37.                 SCLK=0;
  38.                 SCLK=1;
  39.                 ACC=ACC>>1;
  40.         }
  41. }
  42. uchar read_byte()
  43. {
  44.         RST=1;
  45.         for(a=8;a>0;a--)
  46.         {
  47.                 ACC7=IO;
  48.                 SCLK=1;
  49.                 SCLK=0;
  50.                 ACC=ACC>>1;

  51.         }
  52.         return (ACC);
  53. }
  54. void write_1302(uchar add,uchar dat)
  55. {

  56.         RST=0;
  57.         SCLK=0;
  58.         RST=1;
  59.         write_byte(add);
  60.         write_byte(dat);
  61.         SCLK=1;
  62.         RST=0;
  63. }
  64. uchar read_1302(uchar add)
  65. {
  66.         uchar temp;
  67.         RST=0;
  68.         SCLK=0;
  69.         RST=1;
  70.         write_byte(add);
  71.         temp=read_byte();
  72.         SCLK=1;
  73.         RST=0;
  74.         return(temp);
  75. }
  76. uchar BCD_Decimal(uchar bcd)
  77. {
  78. uchar Decimal;
  79. Decimal=bcd>>4;
  80. return(Decimal=Decimal*10+(bcd&=0x0F));
  81. }

  82. uchar Decimal_BCD(uchar dec)
  83. {
  84.   uchar bcd;
  85.   bcd=((dec%10)&0x0f)|(((dec/10)<<4)&0xf0);
  86.   return bcd;
  87. }



  88. void ds1302_init()
  89. {
  90. RST=0;
  91. SCLK=0;
  92. write_1302(0x8e,0x00);          //關寫保護

  93. write_1302(0xc0,0xfe);         
  94. write_1302(0xc2,0xff);
  95.         
  96. write_1302(0x80,0x00);  //寫初始sec
  97. write_1302(0x82,0x10);        //寫初始min
  98. write_1302(0x84,0x18);         //寫初始hour
  99.         
  100. write_1302(0x8e,0x80);        //開寫保護

  101. }




  102. void display()
  103. {
  104.         
  105.     switch(key)
  106.         {
  107.         case 0: c[0]=led[hour/10];
  108.                         c[1]=led[hour%10];
  109.                         c[2]=led[min/10];
  110.                     c[3]=led[min%10];
  111.                         break;

  112.         case 1:        if(S_flag==0)   
  113.             {     
  114.                         c[0]=led[hour/10];
  115.                         c[1]=led[hour%10];
  116.             }   
  117.             else   
  118.             {
  119.                         c[0]=0xff;
  120.                         c[1]=0xff;
  121.             }   
  122.                         
  123.                         c[2]=led[min/10];
  124.                         c[3]=led[min%10];
  125.                         break;

  126.         case 2:        c[0]=led[hour/10];
  127.                         c[1]=led[hour%10];
  128.                
  129.                 if(S_flag==0)   
  130.             {     
  131.                         c[2]=led[min/10];
  132.                         c[3]=led[min%10];
  133.             }   
  134.             else   
  135.             {
  136.                         c[2]=0xff;
  137.                         c[3]=0xff;
  138.             }  
  139.                         break;         

  140.         }                                       
  141. }
  142.         

  143. void init()
  144. {
  145.         TMOD=0x01;
  146.         TH0=0xfc;     //定時1ms   
  147.     TL0=0x18;
  148.         EA=1;
  149.         ET0=1;
  150.         TR0=1;
  151.         S5=0;
  152. }


  153. void cmg(void)//數碼管鎖存函數
  154. {
  155.         dula=1;
  156.         P0=0x00;
  157.         dula=0;
  158.         wela=1;
  159.         P0=0x00;
  160.         wela=0;
  161. }



  162. void keyscan()
  163. {

  164.         if(key1==0)//key1為功能鍵
  165.         {
  166.         delay(2);
  167.         if(key1==0)
  168.         {
  169.         //while(!key1);
  170.         for(i=0;((i<10)&&(key1==0));i++)          //檢測按鍵釋放
  171.     {
  172.     delay(1);
  173.     }
  174.         key++;
  175.         
  176.         if(key>2)
  177.         key=0;
  178.         
  179.         if(key!=0)
  180.         {

  181.         switch(key)
  182.         {
  183.         
  184.         case 1:  
  185.                  if(key2==0)                         //調時
  186.                  delay(2);
  187.                          if(key2==0)
  188.                          {
  189.                            
  190.                                 for(i=0;((i<10)&&(key2==0));i++)           //檢測按鍵釋放
  191.                                 {
  192.                                 delay(1);
  193.                                 }
  194.                         
  195.                             hour1=hour;
  196.                                 hour1++;
  197.                                 if(hour1>23)
  198.                                 hour1=0;
  199.                                  
  200.                                 temp=Decimal_BCD(hour1);
  201.                                 //temp=(hour1)/10*16+(hour1)%10;
  202.                                write_1302(0x8e,0x00);
  203.                                write_1302(0x84,temp);
  204.                               write_1302(0x8e,0x80);                                 
  205.                          }
  206.         
  207.                          if(key3==0)                        
  208.                  delay(2);
  209.                          if(key3==0)
  210.                          {
  211.                            
  212.                                 for(i=0;((i<10)&&(key3==0));i++)                   //檢測按鍵釋放
  213.                                 {
  214.                                 delay(1);
  215.                                 }
  216.                 hour1=hour;
  217.                                 hour1--;
  218.                                 if(hour1<0)
  219.                                 hour1=23;
  220.                            
  221.                                  //temp=Decimal_BCD(hour1);
  222.                                 temp=(hour1)/10*16+(hour1)%10;
  223.                                write_1302(0x8e,0x00);
  224.                                write_1302(0x84,temp);
  225.                               write_1302(0x8e,0x80);
  226.                                                                  
  227.                          }
  228.                
  229.                          break;

  230.         case 2:  if(key2==0)                         //調分
  231.                  delay(2);
  232.                          if(key2==0)
  233.                          {
  234.                                    for(i=0;((i<10)&&(key2==0));i++)
  235.                {
  236.                 delay(1);
  237.                }
  238.                                 if(min<59)
  239.                                 min++;
  240.                                 else
  241.                                 min=0;
  242.                                 //temp=(min)/10*16+(min)%10;
  243.                                  temp=Decimal_BCD(min);
  244.                              write_1302(0x8e,0x00);
  245.                                write_1302(0x82,temp);
  246.                     write_1302(0x80,0x00);          //miao復位
  247.                                write_1302(0x8e,0x80);                                         
  248.                          }
  249.                

  250.                          if(key3==0)                        
  251.                  delay(2);
  252.                          if(key3==0)
  253.                          {
  254.                             for(i=0;((i<10)&&(key3==0));i++)
  255.                 {
  256.                 delay(1);
  257.                 }
  258.                                 if(min>0)
  259.                                 min--;
  260.                                 else
  261.                                 min=59;
  262.                                 temp=(min)/10*16+(min)%10;
  263.                                  //temp=Decimal_BCD(min);
  264.                              write_1302(0x8e,0x00);
  265.                                write_1302(0x82,temp);
  266.                                 write_1302(0x80,0x00);          //miao復位
  267.                                write_1302(0x8e,0x80);                                 
  268.                          }

  269.                         break;
  270.         }
  271.          
  272.    }
  273.    }
  274.    }
  275. }
  276.                
  277.            
  278.                   

  279. void main()
  280. {

  281.     cmg();//數碼管鎖存 (關閉開發板數碼管)
  282.         ds1302_init();
  283.         init();
  284.         while(1)
  285.         {
  286.           keyscan();
  287.           display();
  288.     }
  289. }


  290. void timer0() interrupt 1
  291. {
  292.     TH0=0xfc;     //定時1ms   
  293.     TL0=0x18;
  294.     //TL0 = (65536-1932)/256;        //設置定時初值                10ms
  295.     //TH0 = (65536-1932)%256;
  296.         //TH0=0xfb;     //定時ms   
  297.      //TL0=0x74;
  298.         /*t++;
  299.         if(t==255)
  300.         {
  301.             t=0;
  302.                 S5=!S5;
  303.         }
  304.          */
  305.         
  306.         d++;
  307.         if(d==20)
  308.         {
  309.         d=0;
  310.     write_1302(0x8e,0x00);
  311.         //sec = BCD_Decimal(read_1302(0x81));
  312.         min = BCD_Decimal(read_1302(0x83));
  313.         hour = BCD_Decimal(read_1302(0x85));
  314.         write_1302(0x8e,0x80);
  315.         }
  316.         
  317.         milsec++;
  318.         if(milsec==440)
  319.         {
  320.                 milsec=0;
  321.                 S_flag=!S_flag;
  322.                 S5=!S5;
  323.         }
  324.         
  325.     if(k==4)  
  326.     k=0;   
  327.     P0=c[k];     
  328.     P2=b[k++];      
  329.     delay(1);     
  330.     P2=0xff;
  331. }
復制代碼


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:99987 發表于 2021-9-26 12:29 | 只看該作者
寫入數據適當加延時或空操作,太快芯片反應不過來錯誤。
回復

使用道具 舉報

板凳
ID:725922 發表于 2021-9-26 15:10 | 只看該作者
madell 發表于 2021-9-26 12:29
寫入數據適當加延時或空操作,太快芯片反應不過來錯誤。

其實我也覺得可能是這個節奏上有問題,尤其是顯示刷新的太快。
回復

使用道具 舉報

地板
ID:844772 發表于 2021-9-26 16:45 | 只看該作者
能否把寫函數的這三句: IO=ACC0;  SCLK=0; SCLK=1;順序改一下再加個延時,改為:  SCLK=0;  IO=ACC0;SCLK=1;_nop_(); 或者你再看看手冊,按你寫的時序,延時不夠。
回復

使用道具 舉報

5#
ID:401564 發表于 2021-9-26 17:22 | 只看該作者
樓上已經有人說了,在讀寫時鐘間增加延時
可以在調用函數時先讓時鐘線低電平SCLK=0;
這樣的話,DS1302的SDA就會經歷一個上升沿和一個下降沿,也就不用在乎它是上升沿寫入還是下降沿寫入了

IO=ACC0;
SCLK=1;
_nop_();
SCLK=0;
_nop_();
ACC=ACC>>1;
_nop_();
回復

使用道具 舉報

6#
ID:624769 發表于 2021-9-26 20:48 | 只看該作者
那么多人給你分析了代碼,我就不看你的代碼了, 就提幾個關鍵的時序,
RST = 0    =>  RST =1     手冊上要求最少 4us 間隔,實際測試 2us 的間隔是有必要的。
CLK = 0   =>   RST =1     手冊上要求最少2us 間隔  實際測試最少 0.3us 是有必要的。
在STC8系列單片機, 24MHz 下。
IO = 0  =>   IO = 1     如IO有上拉電阻, 可在 IO = 1 后 立刻 CLK = 1
如沒有上拉電阻,  IO = 1 后  最少 3個 NOP 才可以 CLK = 1
IO = 1   =>   IO =0     無論有沒有上拉電阻,  IO =0 后 都可以立刻  CLK = 1
回復

使用道具 舉報

7#
ID:725922 發表于 2021-9-26 23:17 | 只看該作者
感謝各位的指點,我再看下。單片機水平還很菜,不過也在努力吧。
回復

使用道具 舉報

8#
ID:725922 發表于 2021-10-5 12:18 | 只看該作者
找到問題了,不是1302寫不進去時間,是按鍵掃描函數有問題。。按下設置后,再次掃描按鍵函數時,因為檢測不到按鍵按下,所以進不去函數了,因此也無法掃描到加減語句,修改if嵌套就好了。但是現在加減還是有點卡頓,需要慢一點按,偶爾不太靈,不過還能接受吧
回復

使用道具 舉報

9#
ID:725922 發表于 2021-10-5 12:47 | 只看該作者
按鍵卡頓,把keyscan()函數放中斷里面,設置一個合理的掃描時間,靈敏度提高,有改善。
回復

使用道具 舉報

10#
ID:161164 發表于 2021-10-5 15:51 | 只看該作者
wdmcp 發表于 2021-10-5 12:47
按鍵卡頓,把keyscan()函數放中斷里面,設置一個合理的掃描時間,靈敏度提高,有改善。

中斷里不要放太多東西
不要用太長(>1ms)的delay
貼段代碼讓你參考一下
  1. void keyscan()
  2. {static u8 Delay_XD;//靜態局部變數,離開函數后保持數值
  3. bit Key_Add, Key_Dec;//局部變數,離開函數后清零
  4.         if(!key1 || !key2 || !key3)//有鍵按下
  5.         {
  6.                 if(Delay_XD<0xFF)Delay_XD++;//消抖延時并限制溢出
  7.                 if(Delay_XD == 250)//延時250個周期
  8.                 {
  9.                         if(!key1)//功能鍵按下
  10.                         {
  11.                                 key++;
  12.                                 if(key>2)key=0;
  13.                         }
  14.                         if(!key2)//加鍵按下
  15.                         {
  16.                                 Key_Add = 1;//加標志位置1
  17.                         }
  18.                         if(!key3)//減鍵按下
  19.                         {
  20.                                 Key_Dec = 1;//減標志位置1
  21.                         }                       
  22.                 }
  23.         }else{
  24.                 Delay_XD = 0;//沒有鍵按下清零
  25.         }
  26.         switch(key)
  27.         {
  28.                 case 1:
  29.                         if(Key_Add)
  30.                         {
  31.                                 hour1=hour;
  32.                                 hour1++;
  33.                                 if(hour1>23)
  34.                                         hour1=0;

  35.                                 temp=Decimal_BCD(hour1);
  36.                                 //temp=(hour1)/10*16+(hour1)%10;
  37.                                 write_1302(0x8e,0x00);
  38.                                 write_1302(0x84,temp);
  39.                                 write_1302(0x8e,0x80);
  40.                         }

  41.                         if(Key_Dec)
  42.                         {
  43.                                 hour1=hour;
  44.                                 hour1--;
  45.                                 if(hour1<0)
  46.                                         hour1=23;

  47.                                 //temp=Decimal_BCD(hour1);
  48.                                 temp=(hour1)/10*16+(hour1)%10;
  49.                                 write_1302(0x8e,0x00);
  50.                                 write_1302(0x84,temp);
  51.                                 write_1302(0x8e,0x80);
  52.                         }
  53.                         break;

  54.                 case 2:
  55.                         if(Key_Add)
  56.                         {
  57.                                 if(min<59)
  58.                                         min++;
  59.                                 else
  60.                                         min=0;
  61.                                 //temp=(min)/10*16+(min)%10;
  62.                                 temp=Decimal_BCD(min);
  63.                                 write_1302(0x8e,0x00);
  64.                                 write_1302(0x82,temp);
  65.                                 write_1302(0x80,0x00);          //miao復位
  66.                                 write_1302(0x8e,0x80);
  67.                         }

  68.                         if(Key_Dec)
  69.                         {
  70.                                 if(min>0)
  71.                                         min--;
  72.                                 else
  73.                                         min=59;
  74.                                 temp=(min)/10*16+(min)%10;
  75.                                 //temp=Decimal_BCD(min);
  76.                                 write_1302(0x8e,0x00);
  77.                                 write_1302(0x82,temp);
  78.                                 write_1302(0x80,0x00);          //miao復位
  79.                                 write_1302(0x8e,0x80);
  80.                         }
  81.                         break;
  82.                
  83.                 default:
  84.                         break;
  85.         }
  86. }
復制代碼
回復

使用道具 舉報

11#
ID:725922 發表于 2021-10-5 20:10 | 只看該作者
lkc8210 發表于 2021-10-5 15:51
中斷里不要放太多東西
不要用太長(>1ms)的delay
貼段代碼讓你參考一下

謝謝熱心的回復。
回復

使用道具 舉報

12#
ID:824490 發表于 2021-10-7 11:57 | 只看該作者
判斷問題要精準!
1302能走時,說明初始化正常,說明寫入時間正常,說明寫入代碼沒問題。不能設置時間,就去查按鍵代碼了。

什么延時啊、節奏啊、中斷啊、、、都是空的!除非你初始化用的不是與設置時間是2套寫入代碼。。
回復

使用道具 舉報

13#
ID:725922 發表于 2021-10-8 18:06 | 只看該作者
名字不是重點 發表于 2021-10-7 11:57
判斷問題要精準!
1302能走時,說明初始化正常,說明寫入時間正常,說明寫入代碼沒問題。不能設置時間,就 ...

對,排查問題思路要清晰,我就有點糊涂了。開始以為是定時器讀取頻率太快,可能導致寫入時間出問題,直到增加延時還不行,我才看出按鍵函數有大漏洞。。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲一区二区av | 久久久久久亚洲欧洲 | 日韩在线免费 | 中文字幕亚洲精品 | 亚州成人 | 中文字幕综合 | 欧美成人一级 | 黄色网址在线播放 | 国产精品99久久久久久久久久久久 | 亚洲精品一区二区在线观看 | 日韩成人一区 | 懂色中文一区二区在线播放 | 成人免费日韩 | 欧美亚洲综合久久 | 欧美jizzhd精品欧美巨大免费 | 久久网日本 | 午夜影院在线观看视频 | 中文字幕视频一区 | 一级欧美日韩 | 91影院在线观看 | 日日操夜夜操视频 | 欧美中文字幕在线观看 | 婷婷激情在线 | 久久免费精品视频 | 日本高清中文字幕 | 日日拍夜夜 | 91麻豆精品国产91久久久久久久久 | 色综合久久久久 | www.黄色片视频 | 天堂久久一区 | 97影院2| 欧美精品一区二区三区在线四季 | 久久久久久久电影 | 性一交一乱一伦视频免费观看 | 日韩在线一区二区 | 日韩爱爱网站 | 亚洲精品久久久久avwww潮水 | 日韩成人精品 | 一区二区三区亚洲 | jizz在线看片 | 蜜月aⅴ国产精品 |