⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 metro.c

📁 pic单片机例程
💻 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 + -