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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

帖子
查看: 5549|回復: 0
打印 上一主題 下一主題
收起左側

用STC系列單片機制作四位可預置計時器

[復制鏈接]
跳轉到指定樓層
樓主





  用STC系列單片機制作四位可預置計時器_用UM5140X計時器電路改裝
#:當使用的EEPROM起始地址不是C2~C7的IC時請到STC_EEPROM.h文件中注釋#define EEPROM_C2_C7這行宏定義
功能: 具有二個按鍵,四位紅色共陽極數碼顯示
  P3.6長按 = 模式鍵、短按 = 移位、保存
  P3.7長按 = 開始鍵、短按 = 加數、停止計時
  具有正、倒;計分或計秒預設選擇
  具有預約、倒計時;開機功能分別輸出一個1S低電平信號和一個長通低電平信號

使用說明:
A: 上電前若P1.0對地則為倒計秒//P1.1對地則為倒計分//其它狀態組合未定義,建議不使用。
1: 長按P3.6口開關則先重新調出存在eeprom在的計時停止計時顯示P***且第一個*以125ms閃爍
此時若依次短按P3.6口開關則移向下一位閃爍,在該位閃爍若短按P3.7口的開關則此位加1。
當第三個*閃爍時如果再短按一次P3.6口開關則保存此次設定值并退出設置狀態,顯示***。若
在閃爍10s內沒有新鍵按下則自動退出設置狀態并不保存此次設定值,顯示***。
2: 長按P3.7口開關則開始計時顯示***且最后一個dp點閃爍,在計時器運行中若短按P3.7口開關則
停止計時,10s內沒有新鍵按下則自動重載預設值,顯示***。
3: 當時間從預設值倒計到 000 時停止倒計時且P1^2口輸出1S低電平信號(后自動變高)、P1.3口長通
低電平信號(短按P3.7口開關可關閉),10s后自動重載預設值。
程序設計:LBQ691477940  2018-03-10
升級記錄:
增加上電自動選擇設置正計時與倒計時的初步程序編寫。  2018-3-11 23:08
P1.0 & P1.1 對地時為倒計秒
P1.0        對地時為倒計分
P1.1  對地時為正計秒
P1.0 & P1.1 不接時為正計分       2018-3-11 09:33
  1. /*********************************************************************/
  2. #include
  3. #include
  4. #include
  5. #define nop _nop_()
  6. #define uint unsigned int
  7. #define uchar unsigned char
  8. #define ulong unsigned long
  9. #define SBI(Y,X) Y |= (1 << X) //讓Y的X位置1
  10. #define CBI(Y,X) Y &= ~(1 << X) //讓Y的X位清0
  11. #define set_key  P1  //定義鍵盤口
  12. #define KEY  P3   //定義鍵盤口
  13. #define set_djm  0x00 //P1.0 & P1.1 對地時為倒計秒
  14. #define set_zjm  0x01 //P1.0        對地時為倒計分
  15. #define set_djf  0x02 //P1.1    對地時為正計秒
  16. //#define set_zjf  0x03 //P1.0 & P1.1 不接時為正計分
  17. sbit    P1_4 = P1^4; //位驅動
  18. sbit    P1_5 = P1^5; //位驅動
  19. sbit P1_6 = P1^6; //位驅動
  20. sbit P1_7 = P1^7; //位驅動
  21. sbit OUT1S = P1^2; //到時間后輸出約1S低電平
  22. sbit OUTL = P1^3; //到時間后輸出低電平,直到短按P3^7口開關鍵后才變高
  23. sbit DP   = P2^2;
  24. sbit sw_mode = P3^6;  //長按為模式鍵、短按移位
  25. sbit sw_strat = P3^7; //長按為開始鍵、短按加數
  26. bit  DPP = 0, g_shi = 0,up_dn; //閃爍標志位、千位是否顯示標志位、正計時與倒計時標志位為1時倒計。
  27. static uchar yiwei = 4;   //用于設置時間值時移位
  28. static uint count = 0;    //定時器0內的計數器
  29. uint  set_count,set_time,time1 = 0; //倒計數次數、設置的時間值(倒計時計數器)、正計時計數器
  30. uchar  shi,ge,sf,bf,xflash,flash1;  //千位、百位、十位、個位、10s后自動退出設置、到時間后輸出1s
  31. uchar  Ttotal[4];  //前面三個字節為設置好的時間,最后一個字節用來判斷eeprom是否寫過
  32. /*********************  函數聲明  *****************************************/
  33. uchar key_function(void);   //獨立按鍵檢測函數聲明
  34. void delay_ms(uint n);  //12MHZ晶振時毫秒級CPU延時函數
  35. void write_time(void);  //轉換時間值并寫入
  36. void abc_cba(unsigned int time);   //轉換時間值供顯示
  37. void Read_time(void);  //讀出存在eeprom內的時間值
  38. /*********************** 共陽極數字編碼  ********************************/
  39. uchar code table[]={
  40. //P2.0=E / P2.1=D / P2.2=DP / P2.3=C / P2.4=G / P2.5=B / P2.6=F / P2.7=A
  41. //   0   1  2 3  4   5    6 7  8   9
  42. 0x14,0xd7,0x4c,0x45,0x87,0x25,0x24,0x17,0x04,0x05,0x0e,0xff};//0~9 P共陽極數字編碼
  43. /***************************************************************************/

  44. /*********************************************************************
  45. 功能:12MHZ晶振時毫秒級CPU延時函數
  46. 參數: 1~65535(不可以為0)
  47. 結果:占用CPU方式延時與參數值相同的毫秒時間
  48. 備注:應用于1T單片機時i<600 ;12T單片機時i<125
  49. XX: LBQ691477940   2011-02-19
  50. /**************************************************************************/
  51. void delay_ms(uint n)
  52. {
  53. uint i;
  54. while(--n !=0)
  55. {
  56. #ifdef EEPROM_C2_C7
  57.   for(i = 0;i < 600;i++);
  58. #else
  59.   for(i = 0;i < 125;i++);
  60. #endif
  61. }
  62. }
  63. /****************************************************************************
  64. /*********************************************************************
  65. 函數名:獨立按鍵檢測函數(帶參數返回)
  66. 全局變量:無
  67. 參數說明:無
  68. 返回說明:返回按鍵值
  69. 說明:延時消抖,返回值為0xff表示無按鍵按下或按鍵不正常
  70. /**********************************************************************************/
  71. uchar key_function(void)
  72. {
  73. uchar data keytemp = 0;  //按鍵值局部變量
  74. if ((set_key & 0x03) != 0x03) //如果有按鍵按下 0000 0011 03h
  75.          //        0000 0001 01h
  76. {        //        0000 0010 02h
  77.   keytemp = set_key & 0x03; //取鍵值
  78.   delay_ms(50);    //延時消抖
  79.   if ((set_key & 0x03) == keytemp)
  80.   {
  81.    return (keytemp); //返回按鍵值
  82.   }
  83.   else
  84.   {
  85.    return (0xff);  //無正常按鍵
  86.   }
  87. }
  88. return (0xff);      //無按鍵按下
  89. }
  90. /************************************************************************/
  91. /*********************  轉換時間值并寫入 ***************************/
  92. void write_time(void)
  93. {
  94. Ttotal[0] = time1 / 100;
  95. Ttotal[1] = time1 % 100 / 10;
  96. Ttotal[2] = time1 % 10;
  97. Ttotal[3] = 0x00;
  98. Sector_Erase(EEPROM_ADD);   //擦除扇區
  99. String_write(EEPROM_ADD,4,Ttotal);  //重新寫入數據
  100. String_Read(EEPROM_ADD,4); //重新設置后讀出來備用,目的是更新Read_buf[]數組方便定時器0
  101. }       //中斷后time = Read_buf[0] * 100 + Read_buf[1] * 10 + Read_buf[2];的取值
  102. /*************************************************************************************/
  103. /***************************** 轉換時間值供顯示 *************************************/
  104. void abc_cba(unsigned int time)
  105. {
  106. ge = time / 100;
  107. sf = time % 100 / 10;
  108. bf = time % 10;
  109. }
  110. /**********************************************************************************/
  111. /************************** 讀出存在eeprom內的時間值 *********************/
  112. void Read_time(void)
  113. {   
  114. String_Read(EEPROM_ADD,4);  //讀出來備用
  115.          //EEPROM_ADD 要寫讀內部EEPROM的始起地扯
  116.          //  4    共要讀出4個數據
  117. if(Read_buf[3] != 0)//不為0表示eeprom內容未寫過
  118. {
  119.   time1 = 138;//給一個為138的初值
  120.   write_time();//寫入eeprom
  121. }
  122. set_time = Read_buf[0] * 100 + Read_buf[1] * 10 + Read_buf[2];
  123. if(up_dn)time1 = set_time;  //如果為倒計送設置的值
  124. else time1 = 0;     //如果為正計送0
  125. }
  126. /******************************************************************************/

  127. //*******************************主程序******************************************
  128. void main()
  129. {
  130. uint keynum;  //長按計數緩存區
  131. bit key = 0 ;  //sw_mode鍵長按標志位/正計、倒計
  132. SP = 0x60; //堆棧指針

  133. /******** 注意STC89系列沒有此時鐘頻率分頻功能故只能有 12M晶振  ******************/

  134. //CLK_DIV = 0x00; //系統時鐘
  135. CLK_DIV = 0x01;  //系統時鐘/2
  136. //CLK_DIV = 0x02; //系統時鐘/4
  137. //CLK_DIV = 0x03; //系統時鐘/8
  138. //CLK_DIV = 0x04; //系統時鐘/16
  139. //CLK_DIV = 0x06; //系統時鐘/32
  140. //CLK_DIV = 0x06; //系統時鐘/64
  141. //CLK_DIV = 0x07; //系統時鐘/128

  142. /*********************************************************************************/
  143. set_key = 0xff;
  144. switch (key_function())
  145. {
  146.   case set_djm:
  147.   {
  148.    up_dn = 1;  //正計時與倒計時標志位、為1時倒計。
  149.    set_count = 20;  //P1.6對地倒計秒
  150.    break;
  151.   }  
  152.   case set_djf:
  153.   {
  154.    up_dn = 1;  //正計時與倒計時標志位、為1時倒計。
  155.    set_count = 1200; //P1.7對地倒計分
  156.    break;
  157.   }
  158.   case set_zjm:
  159.   {
  160.    up_dn = 0;  //正計時與倒計時標志位、為1時倒計。
  161.    set_count = 20;  //P1.6對地倒計秒
  162.    break;
  163.   }  
  164.   /* case set_zjf:
  165.   {  
  166.    break;
  167.   } */
  168.   default:
  169.   {
  170.    up_dn = 0;  //正計時與倒計時標志位、為1時倒計。
  171.    set_count = 1200; //P1.7對地倒計分
  172.    break;
  173.   }
  174. }
  175. /***************************************************************************/
  176. TMOD = 0x11;   //設置定時器0/1為工作方式1(0001 0001)
  177. //write_time();//寫入eeprom
  178. TH0 = (65536 - 50000) / 256;
  179. TL0 = (65536 - 50000) % 256;
  180. TH1 = (65536 - 2500) / 256;
  181. TL1 = (65536 - 2500) % 256;
  182. ET1 = 1;
  183. TR1 = 1;
  184. ET0 = 1;
  185. EA = 1;   //開定時器0中斷、啟動定時器0、開總中斷
  186. OUT1S = 1; //到時間后輸出約1S低電平,上電后置1
  187. OUTL = 1; //到時間后輸出約低電平,上電后置1
  188. Read_time(); //讀出存在eeprom內的時間值
  189. if(up_dn) time1 = set_time;
  190. abc_cba(time1);  //轉換時間值供顯示

  191. /*********************  長按為模式鍵、短按移位  **************************************/
  192. while(1)
  193. {  
  194.   if ((KEY & 0xc0) == 0x80) //如果有按鍵按下 1100 0000 C0h
  195.          //        1011 1111 80h
  196.   {
  197.    delay_ms(20); //延時消抖
  198.    while ((KEY & 0xc0) == 0x80) //長按為模式鍵、短按移位
  199.    {
  200.     keynum++;
  201.     delay_ms(10);  //防止干擾
  202.     if (keynum > 200) //如果是長按sw_mode模式鍵則
  203.     {
  204.      TR0 = 0;  //停止計時器0
  205.      DPP = 0;  //關閉小數點閃爍標志位
  206.      key = 1;  //置sw_mode鍵有長按標志位
  207.      g_shi = 1;  //千位是否顯示標志位置位
  208.      yiwei = 0;
  209.      xflash = 0;   //每按一次清0一次讓其永遠達不到10s的退出值
  210.      time1 = Read_buf[0] * 100 + Read_buf[1] * 10 + Read_buf[2];//重調回之前值
  211.      if(up_dn) abc_cba(set_time);//如果為倒計時轉換set_time時間值供顯示
  212.      else abc_cba(time1); //如果為正計時轉換time1時間值供顯示
  213.     }
  214.    }
  215.    if (keynum > 200)
  216.    {
  217.     keynum = 0;
  218.    }  
  219.    else if(keynum >= 10) //防止干擾
  220.    {
  221.     keynum = 0;   
  222.     if(key)  //如果sw_mode鍵有長按標志位
  223.     {
  224.      TR0 = 0;
  225.      DPP = 0;   //關閉小數點閃爍標志位
  226.      xflash = 0;   //每按一次清0一次讓其永遠達不到10s的退出值
  227.      yiwei++;
  228.      if(yiwei >= 3)
  229.      {
  230.       yiwei = 4;  //讓移位功能失效
  231.       key = 0;  //關閃sw_mode鍵有長按標志位
  232.       g_shi = 0;  //關閉千位是否顯示標志位
  233.       write_time(); //轉換時間值并寫入
  234.       if(!up_dn)time1 = 0; //如果為正計時則保存完后恢復time1為 000
  235.      }
  236.     }
  237.    }
  238.   }
  239. /**************** 長按為開始鍵、短按加數、停止計時  ************************************/
  240.   if ((KEY & 0xc0) == 0x40) //如果有按鍵按下 1100 0000 C0h
  241.   {       //        0111 1111 40h
  242.    delay_ms(20); //延時消抖
  243.    while ((KEY & 0xc0) == 0x40) //長按為開始鍵、短按加數、停止計時
  244.    {         
  245.     keynum++;
  246.     delay_ms(10);  //防止干擾
  247.     if (keynum > 200) //如果長按sw_strat開始鍵則
  248.     {
  249.      if((set_time !=0)||(up_dn == 0))//set_time=0未重置數時不能啟動倒計時或為正計時模式時啟動計時器
  250.      {
  251.       Read_time(); //啟動前先更新set_time的值供定時器0中斷程序參考
  252.       count = 0;  //定時器0內的計數器清0保持每次時間一樣
  253.       TR0 = 1;  //開啟計時器0
  254.      }  
  255.     }
  256.    }
  257.    if (keynum > 200)
  258.    {
  259.     keynum = 0;
  260.    }  
  261.    else if(keynum >= 10) //防止干擾
  262.    {
  263.     keynum = 0;
  264.     TR0 = 0; //關閃計時器0
  265.     DPP = 0; //關閉小數點閃爍標志位
  266.     xflash = 0; //每按一次清0一次讓其永遠達不到10s的退出值
  267.     OUTL = 1; //短按P3^7口開關鍵后才變高   
  268.     switch(yiwei)
  269.     {
  270.      case 0:
  271.      {
  272.       ge++;
  273.       if(ge >= 10) //如果大于10清0
  274.       ge = 0;
  275.       break;
  276.      }
  277.     case 1:
  278.      {
  279.       sf++;
  280.       if(sf >= 10) //如果大于10清0
  281.       sf = 0;
  282.       break;
  283.      }
  284.     case 2:
  285.      {
  286.       bf++;
  287.       if(bf >= 10) //如果大于10清0
  288.       bf = 0;
  289.       break;
  290.      }
  291.      default:
  292.      {      
  293.       break;
  294.      }      
  295.     }
  296.     set_time = time1 = ge * 100 + sf * 10 + bf; //將調節后的值轉換為time值
  297.    }
  298.   }
  299.   if(up_dn) abc_cba(set_time);//如果為倒計時轉換set_time時間值供顯示
  300.   else abc_cba(time1); //如果為正計時轉換time1時間值供顯示   
  301. }
  302. }
  303. /**************************************************************************/
  304. /*****************************************************************************
  305. 函數功能:定時器中斷
  306. 入口參數:
  307. 出口參數:
  308. /****************************************************************************/
  309. void timer0(void) interrupt 1
  310. {  
  311. CY = 0;
  312. TL0 +=(65536 - 50007) % 256;//中斷響應時間同步修正/重裝初值(低8位修正值)
  313. TH0 = (65536 - 50000) / 256 +(unsigned char)CY;//高8位初值修正/重裝初值(高8位修正值)
  314. count++;
  315. if (count == set_count) //50ms x 20 = 1秒鐘
  316. {      //50ms x 1200 = 1分鐘
  317.   count = 0x00;
  318.   time1++;
  319.   set_time--;
  320.   if(!set_time)   //如果已倒計為0則重讀eeprom內的值
  321.   {
  322.    TR0 = 0;
  323.    flash1 = 0;   //到時間后先將其清0保證1s輸出的時間
  324.    DPP = 1;   //這里置1經下面取反后則為0關閉小數點閃爍標志位
  325.    OUT1S = OUTL = 0; //輸出低電平直到短按P3^7口開關鍵后才變高
  326.   }      //到時間后輸出約1S低電平
  327. }
  328. DPP = ~DPP;  //爍標志位取反一次
  329. xflash = 0;  //讓其永遠達不到10s的退出值
  330. }  
  331. /******************************************************************/
  332. /******************************************************************/
  333. void timer1(void) interrupt 3
  334. {
  335. static uchar led;
  336. uchar flash;
  337. bit flas;
  338. TH1 = (65536 - 2500) / 256;
  339. TL1 = (65536 - 2500) % 256;
  340. flash++;
  341. if(flash == 50)  //2.5ms x 50 = 125ms
  342. {
  343.   flash = 0;
  344.   flas = !flas; //跟據移位值來使某位閃煥
  345.   xflash++;
  346.   if(!OUT1S)  //從OUT1S輸出為低時才++
  347.   flash1++;
  348. }
  349. if(flash1 == 8)  //125ms x 8 = 1s 后自動變為高電平
  350. {
  351.   OUT1S = 1;  //到時間后輸出約1S低電平
  352. }
  353. if(xflash == 80) //125ms x 80 = 10s 后自動退出設置狀態
  354. {
  355.   xflash = 0;  //清0
  356.   yiwei = 4;  //讓跟據移位值來使某位閃煥功能失效
  357.   if(up_dn)
  358.   set_time = Read_buf[0] * 100 + Read_buf[1] * 10 + Read_buf[2];//如果為倒計時重調回之前值
  359.   else
  360.   time1 = 0;  //如果為倒計時則清0
  361.   DPP = 0;  //關閉小數點閃爍標志位
  362.   g_shi = 0;  //關閉千位是否顯示標志位
  363. }
  364. switch(led)
  365. {
  366.   case 0:
  367.   {
  368.    P1_7 = 0;
  369.    if(g_shi)
  370.    P2 = table[10]; //不顯示千位
  371.    else
  372.    P2 = table[11]; //顯示千位
  373.    P1_4 = 1;
  374.    led = 1;
  375.    break;
  376.   }
  377.   case 1:
  378.   {
  379.    if((flas)&&(yiwei == 0))//跟據移位值來使某位閃煥
  380.    P2 = table[11]; //不顯示
  381.    else
  382.    P2 = table[ge]; //顯示個位
  383.    P1_4 = 0;
  384.    P1_5 = 1;
  385.    led = 2;
  386.    break;
  387.   }
  388.   case 2:
  389.   {
  390.    if((flas)&&(yiwei == 1))//跟據移位值來使某位閃煥
  391.    P2 = table[11]; //不顯示
  392.    else
  393.    P2 = table[sf]; //顯示十分位
  394.    P1_5 = 0;
  395.    P1_6 = 1;
  396.    led = 3;
  397.    break;
  398.   }
  399.   case 3:
  400.   {
  401.    if((flas)&&(yiwei == 2))//跟據移位值來使某位閃煥
  402.    P2 = table[11]; //不顯示
  403.    else
  404.    P2 = table[bf]; //顯示百分位
  405.    if(DPP)
  406.     DP = 0;  //直接打開小數點
  407.    else
  408.     DP = 1;  //直接關閉小數點
  409.    P1_6 = 0;
  410.    P1_7 = 1;
  411.    led = 0;
  412.    break;
  413.   }
  414.   default:break;
  415. }
  416. }
  417. /******************************************** END  ********************************/
復制代碼



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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日本一区二区不卡视频 | 国产又爽又黄免费视频 | 少妇xxxx69 | 日本在线看片 | 亚洲精品乱码久久久久 | 欧美色综合网 | 成人一区二区视频 | 午夜精品在线观看 | 伊人久久免费视频 | 日本天堂在线观看 | 看逼网站 | 极品新婚夜少妇真紧 | 国产在线视频一区二区 | 亚洲黄色成人 | 久久人体视频 | 毛片毛片毛片 | h视频免费在线观看 | www.欧美日韩 | 一区二区三区高清 | 欧美 日韩 国产 成人 在线 | 一级特黄毛片 | 中文字幕不卡在线 | 亚洲欧美视频一区 | 日韩精品影院 | avtt久久| 97av在线视频| 欧美激情区 | 可以免费看的av | 特级丰满少妇一级aaaa爱毛片 | 99久久九九| 黄色三级视频在线观看 | 午夜在线观看免费视频 | 成人午夜av| 91视频专区 | 国产伦精品一区二区三区视频网站 | 国产a久久麻豆入口 | 超碰福利在线 | 91激情视频 | 最新中文字幕在线 | 久久久久久国产 | 丝袜美腿一区二区三区 |