📄 metro.c
字号:
#include <htc.h>
#include <sys.h>
/*
* Metronome
*
* A metronome project for the 16C57.
* Compile with optimisation ON.
*
* Copyright (C)1996 HI-TECH Software.
* Freely distubutable.
*/
static const unsigned char digits[10] =
{
0x5F, /* 0 */
0x06,
0x3B,
0x2F, /* 3 */
0x66,
0x6D,
0x7D,
0x07, /* 7 */
0x7F,
0x6F,
};
static const unsigned char wave[] =
{
1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1
};
#define TOUT 0x10 // watchdog timeout bit in STATUS
#define XTAL 4000000 // crystal freq
#define PRE 4 // prescaler value
#define INTVL 1000u // 1000uS (1mS) per loop
#define DIVIDE (XTAL/PRE/INTVL/4) // division ratio - must be < 256
#define SECS(x) ((x)*1000000/INTVL/21) // convert secs to outer loop count
#define DEBOUNCE 10 // debounce 10mS
#define COUNT 40 // this many debounce intervals to do something
#define CYCLES sizeof(wave) // this many cycles per "tick"
#define PWRDOWN 30 // power down time
persistent static unsigned char rate; // current rate
static bit btn_1, btn_2; // push buttons
static bit spkr; // speaker bit
static bit counting; // we are counting up or down
static bit fast; // we are counting fast!
static bit display; // display on
main()
{
unsigned char digcnt, // digit counter
segcnt, // segment counter
debounce, // debounce timer
button, // button press timer
cntcnt, // counter timer for speed up
beep_cnt, // beep timer
curval; // current value
unsigned int tick_cnt, // delay timer
powerdown, // powerdown timer
tock_cnt; // tick-tock reload value
OPTION = 1;
PORTA = 0x0C; // Enable both buttons
PORTB = 0x80; // set bits low
TRISA = ~0x0F; // bits 0-3 are output
TRISB = ~0x7F; // bits 0-6 are output
#ifdef _16C71
ADCON1 = 3;
#endif
btn_1 = 0;
btn_2 = 0;
if((STATUS & TOUT)) { // power on-reset?
rate = 60; // initialize rate
beep_cnt = CYCLES;
display = 1;
powerdown = SECS(PWRDOWN);
} else { // watchdog reset
if(PORTB & 0x80) { // no buttons pressed - back to sleep
TRISA = 0xFF; // hi-Z all pins
TRISB = 0xFF;
OPTION = 0xB; // WDT prescaled by 8 - about 150 ms
asm(" sleep");
}
display = 1;
powerdown = SECS(PWRDOWN);
}
spkr = 0;
debounce = 0;
button = 0;
counting = 0;
tock_cnt = (unsigned)(60*1000000/INTVL)/rate;
tick_cnt = tock_cnt;
for(;;) {
if(powerdown)
if(--powerdown == 0) {
display = 0;
if(!spkr) {
TRISA = 0xFF; // hi-Z all pins
TRISB = 0xFF;
OPTION = 0xB; // WDT prescaled by 8 - about 150 ms
asm(" sleep");
}
}
curval = rate;
digcnt = 0;
do {
segcnt = 1; // least sig. segment
do {
asm(" clrwdt");
while((TMR0 & 0x80) == 0) // sync with TMR0
continue;
if(beep_cnt && wave[--beep_cnt])
PORTA ^= 0x8; // toggle speaker bit
while(TMR0 & 0x80)
continue;
TMR0 = -DIVIDE; // reprogram TMR0
if(--tick_cnt == 0) {
tick_cnt = tock_cnt;
if(spkr)
beep_cnt = CYCLES;
}
if(beep_cnt && wave[--beep_cnt])
PORTA ^= 0x8; // toggle speaker bit
PORTA |= 0x7; // all digits off
PORTA &= ~(1 << digcnt); // enable one digit
PORTB = 0x80; // all segments off
if(display)
PORTB |= segcnt & digits[curval % 10]; // convert digit to seg pattern
segcnt <<= 1;
if(digcnt == 0 && !btn_2) { // scan button 1
if((PORTB & 0x80) == 0) {
if(!btn_1) {
debounce = 0;
button = 0;
cntcnt = 0;
fast = 0;
}
btn_1 = 1;
if(++debounce == DEBOUNCE) {
debounce = 0;
button++;
}
display = 1;
powerdown = SECS(PWRDOWN);
} else {
if(!counting && btn_1 && button > 1 && button < COUNT/3)
spkr = 0;
btn_1 = 0;
button = 0;
}
} else if(digcnt == 1 && !btn_1) { // scan button 2
if((PORTB & 0x80) == 0) {
if(!btn_2) {
debounce = 0;
button = 0;
cntcnt = 0;
fast = 0;
}
btn_2 = 1;
if(++debounce == DEBOUNCE) {
debounce = 0;
button++;
}
display = 1;
powerdown = SECS(PWRDOWN);
} else {
if(!counting && btn_2 && button > 1 && button < COUNT/3)
spkr = 1;
btn_2 = 0;
button = 0;
}
}
if(button >= COUNT/3) {
if(fast) {
if(btn_1)
rate -= 10;
else
rate += 10;
} else {
if(btn_1)
rate--;
else
rate++;
if(++cntcnt == 5)
fast = 1;
}
if(rate < 10)
rate = 10;
if(rate > 200)
rate = 200;
counting = 1;
button = 0;
}
} while(!(segcnt & 0x80));
if(counting && !btn_1 && !btn_2) {
tock_cnt = (unsigned)(60*1000000/INTVL)/rate;
counting = 0;
}
curval /= 10;
} while(++digcnt != 3);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -