標題:
如何根據成型的單片機時鐘編寫程序?
[打印本頁]
作者:
消失的阿白
時間:
2016-12-28 11:51
標題:
如何根據成型的單片機時鐘編寫程序?
QQ圖片20161228114049.jpg
(897.35 KB, 下載次數: 102)
下載附件
2016-12-28 11:40 上傳
如圖,單片機的型號是stc15f204ea,之前在網上買了些零件,將之組裝完成后才發(fā)現缺少相對應的程序。
請問,如果想要編寫出相對應的時鐘鬧鐘程序,需要怎么做?
可以的話,請務必留下詳細的回復。
作者:
張偉靈
時間:
2016-12-28 21:02
這個要有電路圖呀!而且你跟他買,他應該會提供程序。
作者:
ahshmj
時間:
2016-12-28 21:21
有電路圖就可以。要知道按鍵、顯示、蜂鳴器、ds1302各自對應的IO。
作者:
angmall
時間:
2016-12-28 21:21
相對應的時鐘鬧鐘程序
//
// STC15F204EA DIY LED Clock
//
#include "stc15.h"
#include <stdint.h>
#include <stdio.h>
#include "adc.h"
#include "ds1302.h"
#include "led.h"
#define FOSC 11059200
// clear wdt
#define WDT_CLEAR() (WDT_CONTR |= 1 << 4)
// alias for relay and buzzer outputs, using relay to drive led for indication of main loop status
#define RELAY P1_4
#define BUZZER P1_5
// adc channels for sensors
#define ADC_LIGHT 6
#define ADC_TEMP 7
// three steps of dimming. Photoresistor adc value is 0-255. Lower values = brighter.
#define DIM_HI 100
#define DIM_LO 190
// button switch aliases
#define SW2 P3_0
#define S2 1
#define SW1 P3_1
#define S1 0
// display mode states
enum keyboard_mode {
K_NORMAL,
K_WAIT_S1,
K_WAIT_S2,
K_SET_HOUR,
K_SET_MINUTE,
K_SET_HOUR_12_24,
K_SEC_DISP,
K_TEMP_DISP,
K_DATE_DISP,
K_DATE_SWDISP,
K_SET_MONTH,
K_SET_DAY,
K_WEEKDAY_DISP,
K_DEBUG
};
// display mode states
enum display_mode {
M_NORMAL,
M_SET_HOUR_12_24,
M_SEC_DISP,
M_TEMP_DISP,
M_DATE_DISP,
M_WEEKDAY_DISP,
M_DEBUG
};
/* ------------------------------------------------------------------------- */
void _delay_ms(uint8_t ms)
{
// i,j selected for fosc 11.0592MHz, using oscilloscope
// the stc-isp tool gives inaccurate values (perhaps for C51 vs sdcc?)
// max 255 ms
uint8_t i, j;
do {
i = 4;
j = 240;
do
{
while (--j);
} while (--i);
} while (--ms);
}
// GLOBALS
uint8_t count; // was uint16 - 8 seems to be enough
uint16_t temp; // temperature sensor value
uint8_t lightval; // light sensor value
volatile uint8_t displaycounter;
volatile uint8_t _100us_count;
volatile uint8_t _10ms_count;
uint8_t dmode = M_NORMAL; // display mode state
uint8_t kmode = K_NORMAL;
uint8_t smode,lmode;
volatile __bit display_colon; // flash colon
__bit flash_01;
__bit flash_23;
__bit beep = 1;
volatile __bit S1_LONG;
volatile __bit S1_PRESSED;
volatile __bit S2_LONG;
volatile __bit S2_PRESSED;
volatile uint8_t debounce[2]; // switch debounce buffer
volatile uint8_t switchcount[2];
#define SW_CNTMAX 80
void timer0_isr() __interrupt 1 __using 1
{
// display refresh ISR
// cycle thru digits one at a time
uint8_t digit = displaycounter % 4;
// turn off all digits, set high
P3 |= 0x3C;
// auto dimming, skip lighting for some cycles
if (displaycounter % lightval < 4 ) {
// fill digits
P2 = dbuf[digit];
// turn on selected digit, set low
P3 &= ~(0x4 << digit);
}
displaycounter++;
// divider: every 10ms
if (++_100us_count == 100) {
_100us_count = 0;
_10ms_count++;
// colon blink stuff, 500ms
if (_10ms_count == 50) {
display_colon = !display_colon;
_10ms_count = 0;
}
// switch read, debounce:
// increment count if settled closed
if ((debounce[0]) == 0x00) {
// down for at least 8 ticks
S1_PRESSED = 1;
switchcount[0]++;
} else {
// released or bounced, reset state
S1_PRESSED = 0;
switchcount[0] = 0;
}
if ((debounce[1]) == 0x00) {
// down for at least 8 ticks
S2_PRESSED = 1;
switchcount[1]++;
} else {
// released or bounced, reset state
S2_PRESSED = 0;
switchcount[1] = 0;
}
// debouncing stuff
// keep resetting halfway if held long
if (switchcount[0] > SW_CNTMAX)
{switchcount[0] = SW_CNTMAX; S1_LONG=1;}
if (switchcount[1] > SW_CNTMAX)
{switchcount[1] = SW_CNTMAX; S2_LONG=1;}
// read switch positions into sliding 8-bit window
debounce[0] = (debounce[0] << 1) | SW1;
debounce[1] = (debounce[1] << 1) | SW2;
}
}
void Timer0Init(void) //100us @ 11.0592MHz
{
TL0 = 0xA4; //Initial timer value
TH0 = 0xFF; //Initial timer value
TF0 = 0; //Clear TF0 flag
TR0 = 1; //Timer0 start run
ET0 = 1; // enable timer0 interrupt
EA = 1; // global interrupt enable
}
#define getkeypress(a) a##_PRESSED
int8_t gettemp(uint16_t raw) {
// formula for ntc adc value to approx C
return 76 - raw * 64 / 637;
}
/*********************************************/
int main()
{
// SETUP
// set photoresistor & ntc pins to open-drain output
P1M1 |= (1<<6) | (1<<7);
P1M0 |= (1<<6) | (1<<7);
// init rtc
ds_init();
// init/read ram config
ds_ram_config_init();
// uncomment in order to reset minutes and hours to zero.. Should not need this.
//ds_reset_clock();
Timer0Init(); // display refresh & switch read
// LOOP
while(1)
{
RELAY = 0;
_delay_ms(100);
RELAY = 1;
// run every ~1 secs
if ((count & 3) == 0) {
lightval = getADCResult8(ADC_LIGHT) >> 3;
temp = gettemp(getADCResult(ADC_TEMP)) + (config_table[CONFIG_TEMP_BYTE]&CONFIG_TEMP_MASK) - 4;
// constrain dimming range
if (lightval < 4)
lightval = 4;
}
ds_readburst(); // read rtc
// keyboard decision tree
switch (kmode) {
case K_SET_HOUR:
flash_01 = !flash_01;
if (! flash_01) {
if (getkeypress(S2)) ds_hours_incr();
if (getkeypress(S1)) kmode = K_SET_MINUTE;
}
break;
case K_SET_MINUTE:
flash_01 = 0;
flash_23 = !flash_23;
if (! flash_23) {
if (getkeypress(S2)) ds_minutes_incr();
if (getkeypress(S1)) kmode = K_SET_HOUR_12_24;
}
break;
case K_SET_HOUR_12_24:
dmode=M_SET_HOUR_12_24;
if (getkeypress(S2)) ds_hours_12_24_toggle();
if (getkeypress(S1)) kmode = K_NORMAL;
break;
case K_TEMP_DISP:
dmode=M_TEMP_DISP;
if (getkeypress(S1))
{ uint8_t offset=config_table[CONFIG_TEMP_BYTE]&CONFIG_TEMP_MASK;
offset++; offset&=CONFIG_TEMP_MASK;
config_table[CONFIG_TEMP_BYTE]=(config_table[CONFIG_TEMP_BYTE]&~CONFIG_TEMP_MASK)|offset;
}
if (getkeypress(S2)) kmode = K_DATE_DISP;
break;
case K_DATE_DISP:
dmode=M_DATE_DISP;
if (getkeypress(S1)) {kmode=K_WAIT_S1; lmode=CONF_SW_MMDD?K_SET_DAY:K_SET_MONTH; smode=K_DATE_SWDISP; }
if (getkeypress(S2)) kmode = K_WEEKDAY_DISP;
break;
case K_DATE_SWDISP:
CONF_SW_MMDD=!CONF_SW_MMDD;
kmode=K_DATE_DISP;
break;
case K_SET_MONTH:
flash_01 = !flash_01;
if (! flash_01) {
if (getkeypress(S2)) { ds_month_incr(); }
if (getkeypress(S1)) { flash_01 = 0; kmode = CONF_SW_MMDD?K_DATE_DISP:K_SET_DAY; }
}
break;
case K_SET_DAY:
flash_23 = !flash_23;
if (! flash_23) {
if (getkeypress(S2)) { ds_day_incr(); }
if (getkeypress(S1)) { flash_23 = 0; kmode = CONF_SW_MMDD?K_SET_MONTH:K_DATE_DISP;
}
}
break;
case K_WEEKDAY_DISP:
dmode=M_WEEKDAY_DISP;
if (getkeypress(S1)) ds_weekday_incr();
if (getkeypress(S2)) kmode = K_NORMAL;
break;
case K_DEBUG:
dmode=M_DEBUG;
if (count>100) kmode = K_NORMAL;
if (S1_PRESSED||S2_PRESSED) count=0;
break;
case K_SEC_DISP:
dmode=M_SEC_DISP;
if (getkeypress(S1) || (count>100)) { kmode = K_NORMAL; }
if (getkeypress(S2)) { ds_sec_zero(); }
break;
case K_WAIT_S1:
count=0;
if (!S1_PRESSED) {
if (S1_LONG) {S1_LONG=0; kmode=lmode;}
else {kmode=smode;}
}
break;
case K_WAIT_S2:
count=0;
if (!S2_PRESSED) {
if (S2_LONG) {S2_LONG=0; kmode=lmode;}
else {kmode=smode;}
}
break;
case K_NORMAL:
default:
flash_01 = 0;
flash_23 = 0;
dmode=M_NORMAL;
if (S1_PRESSED) { kmode = K_WAIT_S1; lmode=K_SET_HOUR; smode=K_SEC_DISP; }
//if (S2_PRESSED) { kmode = K_WAIT_S2; lmode=K_DEBUG; smode=K_TEMP_DISP; }
if (S2_PRESSED) { kmode = K_TEMP_DISP; }
};
// display execution tree
clearTmpDisplay();
switch (dmode) {
case M_NORMAL:
if (flash_01) {
dotdisplay(1,display_colon);
} else {
if (!H12_24) {
filldisplay( 0, (rtc_table[DS_ADDR_HOUR]>>4)&(DS_MASK_HOUR24_TENS>>4), 0); // tenhour
} else {
if (H12_TH) filldisplay( 0, 1, 0); // tenhour in case AMPM mode is on, then '1' only is H12_TH is on
}
filldisplay( 1, rtc_table[DS_ADDR_HOUR]&DS_MASK_HOUR_UNITS, display_colon);
}
if (flash_23) {
dotdisplay(2,display_colon);
dotdisplay(3,H12_24&H12_PM); // dot3 if AMPM mode and PM=1
} else {
filldisplay( 2, (rtc_table[DS_ADDR_MINUTES]>>4)&(DS_MASK_MINUTES_TENS>>4), display_colon); //tenmin
filldisplay( 3, rtc_table[DS_ADDR_MINUTES]&DS_MASK_MINUTES_UNITS, H12_24 & H12_PM); //min
}
break;
case M_SET_HOUR_12_24:
if (!H12_24) {
filldisplay( 1, 2, 0); filldisplay( 2, 4, 0);
} else {
filldisplay( 1, 1, 0); filldisplay( 2, 2, 0);
}
filldisplay( 3, LED_h, 0);
break;
case M_SEC_DISP:
dotdisplay(0,display_colon);
dotdisplay(1,display_colon);
filldisplay(2,(rtc_table[DS_ADDR_SECONDS]>>4)&(DS_MASK_SECONDS_TENS>>4),0);
filldisplay(3,rtc_table[DS_ADDR_SECONDS]&DS_MASK_SECONDS_UNITS,0);
break;
case M_DATE_DISP:
if (flash_01) {
dotdisplay(1,1);
} else {
if (!CONF_SW_MMDD) {
filldisplay( 0, rtc_table[DS_ADDR_MONTH]>>4, 0); // tenmonth ( &MASK_TENS useless, as MSB bits are read as '0')
filldisplay( 1, rtc_table[DS_ADDR_MONTH]&DS_MASK_MONTH_UNITS, 1); }
else {
filldisplay( 2, rtc_table[DS_ADDR_MONTH]>>4, 0); // tenmonth ( &MASK_TENS useless, as MSB bits are read as '0')
filldisplay( 3, rtc_table[DS_ADDR_MONTH]&DS_MASK_MONTH_UNITS, 0); }
}
if (!flash_23) {
if (!CONF_SW_MMDD) {
filldisplay( 2, rtc_table[DS_ADDR_DAY]>>4, 0); // tenday ( &MASK_TENS useless)
filldisplay( 3, rtc_table[DS_ADDR_DAY]&DS_MASK_DAY_UNITS, 0); } // day
else {
filldisplay( 0, rtc_table[DS_ADDR_DAY]>>4, 0); // tenday ( &MASK_TENS useless)
filldisplay( 1, rtc_table[DS_ADDR_DAY]&DS_MASK_DAY_UNITS, 1); } // day
}
break;
case M_WEEKDAY_DISP:
filldisplay( 1, LED_DASH, 0);
filldisplay( 2, rtc_table[DS_ADDR_WEEKDAY], 0); //weekday ( &MASK_UNITS useless, all MSBs are '0')
filldisplay( 3, LED_DASH, 0);
break;
case M_TEMP_DISP:
filldisplay( 0, ds_int2bcd_tens(temp), 0);
filldisplay( 1, ds_int2bcd_ones(temp), 0);
filldisplay( 2, CONF_C_F ? LED_f : LED_c, 1);
// if (temp<0) filldisplay( 3, LED_DASH, 0); -- temp defined as uint16, cannot be <0
break;
case M_DEBUG:
filldisplay( 0, switchcount[0]>>4, S1_LONG);
filldisplay( 1, switchcount[0]&15, S1_PRESSED);
filldisplay( 2, switchcount[1]>>4, S2_LONG);
filldisplay( 3, switchcount[1]&15, S2_PRESSED);
break;
}
__critical { updateTmpDisplay(); }
// save ram config
ds_ram_config_write();
if (S1_PRESSED || S2_PRESSED && ! (S1_LONG || S2_LONG)) {
// try to dampen button over-response
_delay_ms(100);
}
// reset long presses when button released
if (! S1_PRESSED && S1_LONG) {
S1_LONG = 0;
}
if (! S2_PRESSED && S2_LONG) {
S2_LONG = 0;
}
count++;
WDT_CLEAR();
}
}
/* ------------------------------------------------------------------------- */
復制代碼
https://github.com/zerog2k/stc_diyclock
作者:
zeng_fanlong
時間:
2016-12-28 23:09
這個得根據電路來寫程序,你可以用已有的原件設計電路,再編寫程序。
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1