找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

如何根据成型的单片机时钟编写程序?

查看数: 2720 | 评论数: 4 | 收藏 0
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2016-12-28 11:51

正文摘要:

如图,单片机的型号是stc15f204ea,之前在网上买了些零件,将之组装完成后才发现缺少相对应的程序。 请问,如果想要编写出相对应的时钟闹钟程序,需要怎么做? 可以的话,请务必留下详细的回复。

回复

ID:158248 发表于 2016-12-28 23:09
这个得根据电路来写程序,你可以用已有的原件设计电路,再编写程序。
ID:155507 发表于 2016-12-28 21:21
相对应的时钟闹钟程序
  1. //
  2. // STC15F204EA DIY LED Clock
  3. //

  4. #include "stc15.h"
  5. #include <stdint.h>
  6. #include <stdio.h>
  7. #include "adc.h"
  8. #include "ds1302.h"
  9. #include "led.h"
  10.    
  11. #define FOSC    11059200

  12. // clear wdt
  13. #define WDT_CLEAR()    (WDT_CONTR |= 1 << 4)

  14. // alias for relay and buzzer outputs, using relay to drive led for indication of main loop status
  15. #define RELAY   P1_4
  16. #define BUZZER  P1_5
  17.    
  18. // adc channels for sensors
  19. #define ADC_LIGHT 6
  20. #define ADC_TEMP  7

  21. // three steps of dimming. Photoresistor adc value is 0-255. Lower values = brighter.
  22. #define DIM_HI  100
  23. #define DIM_LO  190

  24. // button switch aliases
  25. #define SW2     P3_0
  26. #define S2      1
  27. #define SW1     P3_1
  28. #define S1      0

  29. // display mode states
  30. enum keyboard_mode {
  31.     K_NORMAL,
  32.     K_WAIT_S1,
  33.     K_WAIT_S2,
  34.     K_SET_HOUR,
  35.     K_SET_MINUTE,
  36.     K_SET_HOUR_12_24,
  37.     K_SEC_DISP,
  38.     K_TEMP_DISP,
  39.     K_DATE_DISP,
  40.     K_DATE_SWDISP,
  41.     K_SET_MONTH,
  42.     K_SET_DAY,
  43.     K_WEEKDAY_DISP,
  44.     K_DEBUG
  45. };

  46. // display mode states
  47. enum display_mode {
  48.     M_NORMAL,
  49.     M_SET_HOUR_12_24,
  50.     M_SEC_DISP,
  51.     M_TEMP_DISP,
  52.     M_DATE_DISP,
  53.     M_WEEKDAY_DISP,
  54.     M_DEBUG
  55. };

  56. /* ------------------------------------------------------------------------- */

  57. void _delay_ms(uint8_t ms)
  58. {       
  59.     // i,j selected for fosc 11.0592MHz, using oscilloscope
  60.     // the stc-isp tool gives inaccurate values (perhaps for C51 vs sdcc?)
  61.     // max 255 ms
  62.     uint8_t i, j;
  63.     do {
  64.             i = 4;
  65.             j = 240;
  66.             do
  67.             {
  68.                     while (--j);
  69.             } while (--i);
  70.     } while (--ms);
  71. }

  72. // GLOBALS
  73. uint8_t  count;     // was uint16 - 8 seems to be enough
  74. uint16_t temp;      // temperature sensor value
  75. uint8_t  lightval;  // light sensor value

  76. volatile uint8_t displaycounter;
  77. volatile uint8_t _100us_count;
  78. volatile uint8_t _10ms_count;

  79. uint8_t dmode = M_NORMAL;     // display mode state
  80. uint8_t kmode = K_NORMAL;
  81. uint8_t smode,lmode;

  82. volatile __bit  display_colon;         // flash colon
  83. __bit  flash_01;
  84. __bit  flash_23;
  85. __bit  beep = 1;

  86. volatile __bit  S1_LONG;
  87. volatile __bit  S1_PRESSED;
  88. volatile __bit  S2_LONG;
  89. volatile __bit  S2_PRESSED;

  90. volatile uint8_t debounce[2];      // switch debounce buffer
  91. volatile uint8_t switchcount[2];
  92. #define SW_CNTMAX 80

  93. void timer0_isr() __interrupt 1 __using 1
  94. {
  95.     // display refresh ISR
  96.     // cycle thru digits one at a time
  97.     uint8_t digit = displaycounter % 4;

  98.     // turn off all digits, set high   
  99.     P3 |= 0x3C;

  100.     // auto dimming, skip lighting for some cycles
  101.     if (displaycounter % lightval < 4 ) {
  102.         // fill digits
  103.         P2 = dbuf[digit];
  104.         // turn on selected digit, set low
  105.         P3 &= ~(0x4 << digit);  
  106.     }
  107.     displaycounter++;

  108.     //  divider: every 10ms
  109.     if (++_100us_count == 100) {
  110.         _100us_count = 0;
  111.         _10ms_count++;

  112.         // colon blink stuff, 500ms
  113.         if (_10ms_count == 50) {
  114.             display_colon = !display_colon;
  115.             _10ms_count = 0;
  116.         }
  117.             
  118.         // switch read, debounce:
  119.         // increment count if settled closed
  120.         if ((debounce[0]) == 0x00) {
  121.             // down for at least 8 ticks
  122.             S1_PRESSED = 1;
  123.             switchcount[0]++;
  124.         } else {
  125.             // released or bounced, reset state            
  126.             S1_PRESSED = 0;
  127.             switchcount[0] = 0;
  128.         }

  129.         if ((debounce[1]) == 0x00) {
  130.             // down for at least 8 ticks            
  131.             S2_PRESSED = 1;
  132.             switchcount[1]++;
  133.         } else {
  134.             // released or bounced, reset state
  135.             S2_PRESSED = 0;
  136.             switchcount[1] = 0;
  137.         }

  138.         // debouncing stuff
  139.         // keep resetting halfway if held long
  140.         if (switchcount[0] > SW_CNTMAX)
  141.             {switchcount[0] = SW_CNTMAX; S1_LONG=1;}
  142.         if (switchcount[1] > SW_CNTMAX)
  143.             {switchcount[1] = SW_CNTMAX; S2_LONG=1;}

  144.         // read switch positions into sliding 8-bit window
  145.         debounce[0] = (debounce[0] << 1) | SW1;
  146.         debounce[1] = (debounce[1] << 1) | SW2;
  147.     }
  148. }

  149. void Timer0Init(void)                //100us @ 11.0592MHz
  150. {
  151.         TL0 = 0xA4;                //Initial timer value
  152.         TH0 = 0xFF;                //Initial timer value
  153.     TF0 = 0;                //Clear TF0 flag
  154.     TR0 = 1;                //Timer0 start run
  155.     ET0 = 1;        // enable timer0 interrupt
  156.     EA = 1;         // global interrupt enable
  157. }

  158. #define getkeypress(a) a##_PRESSED

  159. int8_t gettemp(uint16_t raw) {
  160.     // formula for ntc adc value to approx C
  161.     return 76 - raw * 64 / 637;
  162. }

  163. /*********************************************/
  164. int main()
  165. {
  166.     // SETUP
  167.     // set photoresistor & ntc pins to open-drain output
  168.     P1M1 |= (1<<6) | (1<<7);
  169.     P1M0 |= (1<<6) | (1<<7);
  170.             
  171.     // init rtc
  172.     ds_init();
  173.     // init/read ram config
  174.     ds_ram_config_init();
  175.    
  176.     // uncomment in order to reset minutes and hours to zero.. Should not need this.
  177.     //ds_reset_clock();   
  178.    
  179.     Timer0Init(); // display refresh & switch read
  180.    
  181.     // LOOP
  182.     while(1)
  183.     {

  184.       RELAY = 0;
  185.       _delay_ms(100);
  186.       RELAY = 1;

  187.       // run every ~1 secs
  188.       if ((count & 3) == 0) {
  189.           lightval = getADCResult8(ADC_LIGHT) >> 3;
  190.           temp = gettemp(getADCResult(ADC_TEMP)) + (config_table[CONFIG_TEMP_BYTE]&CONFIG_TEMP_MASK) - 4;

  191.           // constrain dimming range
  192.           if (lightval < 4)
  193.               lightval = 4;

  194.       }      

  195.       ds_readburst(); // read rtc

  196.       // keyboard decision tree
  197.       switch (kmode) {
  198.          
  199.           case K_SET_HOUR:
  200.               flash_01 = !flash_01;
  201.               if (! flash_01) {
  202.                   if (getkeypress(S2)) ds_hours_incr();
  203.                   if (getkeypress(S1)) kmode = K_SET_MINUTE;
  204.               }
  205.               break;
  206.               
  207.           case K_SET_MINUTE:
  208.               flash_01 = 0;
  209.               flash_23 = !flash_23;
  210.               if (! flash_23) {
  211.                   if (getkeypress(S2)) ds_minutes_incr();
  212.                   if (getkeypress(S1)) kmode = K_SET_HOUR_12_24;
  213.               }
  214.               break;

  215.           case K_SET_HOUR_12_24:
  216.               dmode=M_SET_HOUR_12_24;
  217.               if (getkeypress(S2)) ds_hours_12_24_toggle();
  218.               if (getkeypress(S1)) kmode = K_NORMAL;
  219.               break;
  220.               
  221.           case K_TEMP_DISP:
  222.               dmode=M_TEMP_DISP;
  223.               if (getkeypress(S1))
  224.                   { uint8_t offset=config_table[CONFIG_TEMP_BYTE]&CONFIG_TEMP_MASK;
  225.                     offset++; offset&=CONFIG_TEMP_MASK;
  226.                     config_table[CONFIG_TEMP_BYTE]=(config_table[CONFIG_TEMP_BYTE]&~CONFIG_TEMP_MASK)|offset;
  227.                   }
  228.               if (getkeypress(S2)) kmode = K_DATE_DISP;
  229.               break;
  230.                         
  231.           case K_DATE_DISP:
  232.               dmode=M_DATE_DISP;
  233.               if (getkeypress(S1)) {kmode=K_WAIT_S1; lmode=CONF_SW_MMDD?K_SET_DAY:K_SET_MONTH; smode=K_DATE_SWDISP; }
  234.               if (getkeypress(S2)) kmode = K_WEEKDAY_DISP;                        
  235.               break;

  236.           case K_DATE_SWDISP:
  237.               CONF_SW_MMDD=!CONF_SW_MMDD;
  238.               kmode=K_DATE_DISP;
  239.               break;
  240.               
  241.           case K_SET_MONTH:
  242.               flash_01 = !flash_01;
  243.               if (! flash_01) {
  244.                   if (getkeypress(S2)) { ds_month_incr(); }
  245.                   if (getkeypress(S1)) { flash_01 = 0; kmode = CONF_SW_MMDD?K_DATE_DISP:K_SET_DAY; }
  246.               }
  247.               break;
  248.               
  249.           case K_SET_DAY:
  250.               flash_23 = !flash_23;
  251.               if (! flash_23) {
  252.                   if (getkeypress(S2)) { ds_day_incr(); }
  253.                   if (getkeypress(S1)) { flash_23 = 0; kmode = CONF_SW_MMDD?K_SET_MONTH:K_DATE_DISP;
  254.                   }
  255.               }
  256.               break;
  257.               
  258.           case K_WEEKDAY_DISP:
  259.               dmode=M_WEEKDAY_DISP;
  260.               if (getkeypress(S1)) ds_weekday_incr();
  261.               if (getkeypress(S2)) kmode = K_NORMAL;
  262.               break;
  263.          
  264.           case K_DEBUG:
  265.               dmode=M_DEBUG;
  266.               if (count>100) kmode = K_NORMAL;
  267.               if (S1_PRESSED||S2_PRESSED) count=0;
  268.               break;

  269.           case K_SEC_DISP:
  270.               dmode=M_SEC_DISP;
  271.               if (getkeypress(S1) || (count>100)) { kmode = K_NORMAL; }
  272.               if (getkeypress(S2)) { ds_sec_zero(); }
  273.               break;

  274.           case K_WAIT_S1:
  275.               count=0;
  276.               if (!S1_PRESSED) {
  277.                if (S1_LONG) {S1_LONG=0; kmode=lmode;}
  278.                       else  {kmode=smode;}
  279.                }
  280.               break;

  281.           case K_WAIT_S2:
  282.               count=0;
  283.               if (!S2_PRESSED) {
  284.                if (S2_LONG) {S2_LONG=0; kmode=lmode;}
  285.                       else  {kmode=smode;}
  286.                }
  287.               break;

  288.           case K_NORMAL:         
  289.           default:
  290.               flash_01 = 0;
  291.               flash_23 = 0;

  292.               dmode=M_NORMAL;

  293.               if (S1_PRESSED) { kmode = K_WAIT_S1; lmode=K_SET_HOUR; smode=K_SEC_DISP;  }
  294.               //if (S2_PRESSED) { kmode = K_WAIT_S2; lmode=K_DEBUG;    smode=K_TEMP_DISP; }
  295.               if (S2_PRESSED) { kmode = K_TEMP_DISP; }
  296.       
  297.       };

  298.       // display execution tree
  299.      
  300.       clearTmpDisplay();

  301.       switch (dmode) {
  302.           case M_NORMAL:
  303.               if (flash_01) {
  304.                   dotdisplay(1,display_colon);
  305.               } else {
  306.                   if (!H12_24) {
  307.                       filldisplay( 0, (rtc_table[DS_ADDR_HOUR]>>4)&(DS_MASK_HOUR24_TENS>>4), 0);        // tenhour
  308.                   } else {
  309.                       if (H12_TH) filldisplay( 0, 1, 0);        // tenhour in case AMPM mode is on, then '1' only is H12_TH is on
  310.                   }                  
  311.                   filldisplay( 1, rtc_table[DS_ADDR_HOUR]&DS_MASK_HOUR_UNITS, display_colon);      
  312.               }
  313.   
  314.               if (flash_23) {
  315.                   dotdisplay(2,display_colon);
  316.                   dotdisplay(3,H12_24&H12_PM);        // dot3 if AMPM mode and PM=1
  317.               } else {
  318.                   filldisplay( 2, (rtc_table[DS_ADDR_MINUTES]>>4)&(DS_MASK_MINUTES_TENS>>4), display_colon);        //tenmin
  319.                   filldisplay( 3, rtc_table[DS_ADDR_MINUTES]&DS_MASK_MINUTES_UNITS, H12_24 & H12_PM);                  //min
  320.               }
  321.               break;

  322.           case M_SET_HOUR_12_24:
  323.               if (!H12_24) {
  324.                   filldisplay( 1, 2, 0); filldisplay( 2, 4, 0);
  325.               } else {
  326.                   filldisplay( 1, 1, 0); filldisplay( 2, 2, 0);                  
  327.               }
  328.               filldisplay( 3, LED_h, 0);
  329.               break;

  330.           case M_SEC_DISP:
  331.               dotdisplay(0,display_colon);
  332.               dotdisplay(1,display_colon);
  333.               filldisplay(2,(rtc_table[DS_ADDR_SECONDS]>>4)&(DS_MASK_SECONDS_TENS>>4),0);
  334.               filldisplay(3,rtc_table[DS_ADDR_SECONDS]&DS_MASK_SECONDS_UNITS,0);
  335.               break;
  336.               
  337.           case M_DATE_DISP:
  338.               if (flash_01) {
  339.                   dotdisplay(1,1);
  340.               } else {
  341.                  if (!CONF_SW_MMDD) {
  342.                   filldisplay( 0, rtc_table[DS_ADDR_MONTH]>>4, 0);        // tenmonth ( &MASK_TENS useless, as MSB bits are read as '0')
  343.                   filldisplay( 1, rtc_table[DS_ADDR_MONTH]&DS_MASK_MONTH_UNITS, 1); }         
  344.                  else {
  345.                   filldisplay( 2, rtc_table[DS_ADDR_MONTH]>>4, 0);        // tenmonth ( &MASK_TENS useless, as MSB bits are read as '0')
  346.                   filldisplay( 3, rtc_table[DS_ADDR_MONTH]&DS_MASK_MONTH_UNITS, 0); }         
  347.               }
  348.               if (!flash_23) {
  349.                  if (!CONF_SW_MMDD) {
  350.                   filldisplay( 2, rtc_table[DS_ADDR_DAY]>>4, 0);                      // tenday   ( &MASK_TENS useless)
  351.                   filldisplay( 3, rtc_table[DS_ADDR_DAY]&DS_MASK_DAY_UNITS, 0); }     // day      
  352.                  else {
  353.                   filldisplay( 0, rtc_table[DS_ADDR_DAY]>>4, 0);                      // tenday   ( &MASK_TENS useless)
  354.                   filldisplay( 1, rtc_table[DS_ADDR_DAY]&DS_MASK_DAY_UNITS, 1); }     // day      
  355.               }     
  356.               break;
  357.                   
  358.           case M_WEEKDAY_DISP:
  359.               filldisplay( 1, LED_DASH, 0);
  360.               filldisplay( 2, rtc_table[DS_ADDR_WEEKDAY], 0);                //weekday ( &MASK_UNITS useless, all MSBs are '0')
  361.               filldisplay( 3, LED_DASH, 0);
  362.               break;
  363.               
  364.           case M_TEMP_DISP:
  365.               filldisplay( 0, ds_int2bcd_tens(temp), 0);
  366.               filldisplay( 1, ds_int2bcd_ones(temp), 0);
  367.               filldisplay( 2, CONF_C_F ? LED_f : LED_c, 1);
  368.               // if (temp<0) filldisplay( 3, LED_DASH, 0);  -- temp defined as uint16, cannot be <0
  369.               break;                  

  370.           case M_DEBUG:
  371.               filldisplay( 0, switchcount[0]>>4, S1_LONG);
  372.               filldisplay( 1, switchcount[0]&15, S1_PRESSED);
  373.               filldisplay( 2, switchcount[1]>>4, S2_LONG);
  374.               filldisplay( 3, switchcount[1]&15, S2_PRESSED);
  375.               break;
  376.       }

  377.       __critical { updateTmpDisplay(); }
  378.                   
  379.       // save ram config
  380.       ds_ram_config_write();
  381.       
  382.       if (S1_PRESSED || S2_PRESSED && ! (S1_LONG || S2_LONG)) {
  383.           // try to dampen button over-response
  384.           _delay_ms(100);
  385.       }

  386.       // reset long presses when button released
  387.       if (! S1_PRESSED && S1_LONG) {
  388.           S1_LONG = 0;
  389.       }
  390.       if (! S2_PRESSED && S2_LONG) {
  391.           S2_LONG = 0;
  392.       }
  393.         
  394.       count++;
  395.       WDT_CLEAR();
  396.     }
  397. }
  398. /* ------------------------------------------------------------------------- */
复制代码


https://github.com/zerog2k/stc_diyclock
ID:7485 发表于 2016-12-28 21:21
有电路图就可以。要知道按键、显示、蜂鸣器、ds1302各自对应的IO。
ID:113208 发表于 2016-12-28 21:02
这个要有电路图呀!而且你跟他买,他应该会提供程序。

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

Powered by 单片机教程网

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