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

📄 main887.c

📁 用PIC16F887做的4个触摸按键的例程
💻 C
📖 第 1 页 / 共 2 页
字号:
//******************************************************************************
// Software License Agreement
//
// The software supplied herewith by Microchip Technology
// Incorporated (the "Company") is intended and supplied to you, the
// Company抯 customer, for use solely and exclusively on Microchip
// products. The software is owned by the Company and/or its supplier,
// and is protected under applicable copyright laws. All rights are
// reserved. Any use in violation of the foregoing restrictions may
// subject the user to criminal sanctions under applicable laws, as
// well as to civil liability for the breach of the terms and
// conditions of this license.
//
// THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES,
// WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
// TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
// IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
//
//******************************************************************************


#include	"main887.h"
#include	"ssp.h"
#include	"display.h"
#include	"audio.h"

//__CONFIG(INTIO & WDTDIS & PWRTEN & MCLRDIS & UNPROTECT & BORDIS & LVPDIS & IESODIS & FCMDIS);


// Defines
// Pinouts
// .. See header file


/** Variables **/

// Debug
unsigned long 	tep;

// I2C Communications
unsigned char	ByteCount;	
unsigned int	TempInt;
unsigned char	SSPCommand;
unsigned char	SSPIndex;
unsigned char	SSPSize;
unsigned char	IndexCount;

unsigned char	AvgIndex;
unsigned char	SliderIndex;

FFlags Flags;
BButtons Buttons;

bank2 unsigned int	RAW	   [NUM_BTTNS];
bank2 unsigned int	AVERAGE[NUM_BTTNS];		// Can't fit all in one bank. Only 96 bytes per Banks 2|3, (Max 24 bttns)
bank3 unsigned int	GUARD  [NUM_BTTNS];
bank3 unsigned int	TRIP   [NUM_BTTNS];		//  "


unsigned char	FIRST;						// first variable to 'discard' first N samples
unsigned char	INDEX;						// Index of what button is being checked.

unsigned int	VALUE;						// current button value
unsigned int	BIGVAL;						// current button bigval
unsigned int	SMALLAVG;					// current button smallavg

unsigned char	option_save;				// save/restore variable for option register in sleep mode.

// Helper variables
unsigned int		j;						// Loop variable, not for use inside ISR.



/** Constants **/

// 0x94/0xA0 = Cin0-    ,   0x95/0xA1 = Cin1-   (Sets comparator operation and proper channel.)
const unsigned char	COMP1[2]			= {0x94, 0x95};				// comparator preset values for each button
const unsigned char	COMP2[2]			= {0xA0, 0xA1};
//const unsigned char	COMP3[2]			= {0xA0, 0xA1};
//const unsigned int	COMP4[2]			= {0xA0, 0xA1};



/*====================================================================
========================  PROGRAM CODE  ==============================
====================================================================*/

/*....................................................................
. 	main()
.
.		Entry point of program.
....................................................................*/
void main(void) {



	INIT();											// Launch Device Initializations
	ClearK_LEDs();									// Init all Keypad LEDs to OFF state
	SetSliderLEDs(1);								// Init Slider Minimum LED to ON state
	Flags.SLEEP = 0;								// Initial Sleeping State (0=off)





	while (1) {										// Loop forever, illum LED if button is down.


		// Normal Awake Operation

		// Illuminate Keypad LEDs
		K_LED1 = (Buttons.BTN1 == 1) ? ON : OFF;	// (if : else)
		K_LED2 = (Buttons.BTN2 == 1) ? ON : OFF;
		K_LED3 = (Buttons.BTN3 == 1) ? ON : OFF;
		K_LED4 = (Buttons.BTN4 == 1) ? ON : OFF;
		K_LED5 = (Buttons.BTN5 == 1) ? ON : OFF;
		K_LED6 = (Buttons.BTN6 == 1) ? ON : OFF;
		K_LED7 = (Buttons.BTN7 == 1) ? ON : OFF;
		K_LED8 = (Buttons.BTN8 == 1) ? ON : OFF;
		K_LED9 = (Buttons.BTN9 == 1) ? ON : OFF;
		K_LED0 = (Buttons.BTN0 == 1) ? ON : OFF;

		// Beep if needed
		if ( !Flags.BUZZDONE && (Buttons.BTN0 || Buttons.BTN1 || Buttons.BTN2 || Buttons.BTN3 || Buttons.BTN4 || Buttons.BTN5 || Buttons.BTN6 || Buttons.BTN7 || Buttons.BTN8 || Buttons.BTN9)) {
			// If a buzz is not complete, and any button was pressed fire off a beep.
			Buzz();
		}

	
		
		// Illuminate Slider Position LEDs
		if (INDEX == iSL1) {
			// To prevent flickering as code is set up, must display indicator for button
			// only after a scan of all slider buttons.  Otherwise displaying mid scan
			// may cause flickering as only partial data is present of a complete scan.

			// This implementation defualts to the higher value if a press is
			// detected on multiple positions.

			if (Buttons.SLIDER6 == 1)
				SetSliderLEDs(6);
			else if (Buttons.SLIDER5 == 1)
				SetSliderLEDs(5);
			else if (Buttons.SLIDER4 == 1)
				SetSliderLEDs(4);
			else if (Buttons.SLIDER3 == 1)
				SetSliderLEDs(3);
			else if (Buttons.SLIDER2 == 1)
				SetSliderLEDs(2);
			else if (Buttons.SLIDER1 == 1)
				SetSliderLEDs(1);						// Lowest position is default 
		}

	
		// Standby Operation (sleep)

		// ... 
		// Issue Sleep Command
		if (Buttons.PWR) {
			Flags.SLEEP = 1;
			Buttons.PWR = 0;

			if (START == 1 || BF == 1)
				while (STOP == 0);
			SetMasterMode();							// Set I2C for master mode to issue commands	
			ShutdownWheel();							// Issue wheel shutdown command
			SSPIE = 0;									// Turn off I2C comms


			// Showy stuff for going to sleep mode
			// ...
			SetK_LEDs();								// Set all lights on, then turn them off
			SetSliderLEDs(6);							// Set moving down for show
			for (j=0; j<0x3000; j++);					// momentary delay
			SetSliderLEDs(5);
			K_LED1 = K_LED3 = OFF;						// turn keypad led's off in a distinct pattern
			for (j=0; j<0x3000; j++);
			SetSliderLEDs(4);
			K_LED2 = OFF;				
			for (j=0; j<0x3000; j++);
			SetSliderLEDs(3);
			K_LED4 = K_LED6 = OFF;					
			for (j=0; j<0x3000; j++);
			SetSliderLEDs(2);
			K_LED5 = K_LED7 = K_LED9 = OFF;					
			for (j=0; j<0x3000; j++);
			SetSliderLEDs(1);
			K_LED8 = OFF;			
			for (j=0; j<0x3000; j++);
			SetSliderLEDs(99);							// Set all off for sleep
			K_LED0 = 0;									// Set last keypad LED off.
		}

		// Begin Sleep operation
		if (Flags.SLEEP) {
			// Set Channel for wake-up button
			SetChannel(iPWR);							// Set to wake-up based off power button


			WDTCON = 0b00001110;						// WDT Off, WDT Prescalar 1:4096  31khz/4096 --> T~=0.12sec
			WDTCON = 0b00000110;						// 1:256 wdt ps  256/31kHz = 8.25ms asleep
			for (j=0; j<NUM_BTTNS; j++)
				AVERAGE[j] = 0;							// Clear all averages (so on wake does not cause issue).
		}
		// Continued sleep operation
		while (Flags.SLEEP) {

			CLRWDT();						// Clear WDT
			WDTCON |= 0x01;					// Enable WDT
			SLEEP();						// Put part to sleep for ~ 0.25 sec
			NOP();
			NOP();
			NOP();							// Nops to ensure no extra code is run.
			NOP();
			// On wake, Disable WDT for normal operation
			WDTCON &= 0xFE;					// Disable WDT
					
					
		
			// Provide enough time to scan for a button.
			FIRST = 3;							// Discard first N readings to establish nominal
			for (j=0; j<100; j++)				// Allow to stabilize and ensure
				Buttons.PWR = 0;				// Ensure cleared on waking

			ClearK_LEDs();						// Init all Keypad LEDs to OFF state
			for (j=0; j<0xFFFF; j++) {    		// Counts 0x1000, estimated to be plenty of on time.
				if (Buttons.PWR == 1) {
					GIE = 0;					// temporarily disable interrupts for the show portion.
					Buttons.BTN0  = 0;
					Buttons.BTN1  = 0;
			 		Buttons.BTN2  = 0;
			 		Buttons.BTN3  = 0;
			 		Buttons.BTN4  = 0;
			 		Buttons.BTN5  = 0;
			 		Buttons.BTN6  = 0;			// Clear all button flags.
			 		Buttons.BTN7  = 0;
					Buttons.BTN8  = 0;
					Buttons.BTN9  = 0;
					Buttons.SLIDER1 = 0;
					Buttons.SLIDER2 = 0;
					Buttons.SLIDER3 = 0;
					Buttons.SLIDER4 = 0;
					Buttons.SLIDER5 = 0;
					Buttons.SLIDER6 = 0; 
					Buttons.PWR = 0;

					// Awake Wheel
					T0IE = 0;						// Wait till finished waking up wheel to allow cap interrupts
					if (START == 1 || BF == 1)
						while (STOP == 0);
					SetMasterMode();				// Set master mode to issue cmds
					WakeupWheel();					// Issue wakeup to wheel

					// LED Turn on sequence (for show)
					SetSliderLEDs(1);			// make lights go up on slider bar led's
					K_LED0 = ON;				// sequence keypad led's too.
					for (j=0; j<0x3000; j++);
					SetSliderLEDs(2);			// Set moving up for show
					K_LED7 = ON;
					for (j=0; j<0x3000; j++);
					SetSliderLEDs(3);
					K_LED4 = ON;
					for (j=0; j<0x3000; j++);
					SetSliderLEDs(4);
					K_LED1 = ON;
					for (j=0; j<0x3000; j++);
					SetSliderLEDs(5);
					K_LED2 = ON;
					for (j=0; j<0x3000; j++);
					SetSliderLEDs(6);
					K_LED3 = ON;
					for (j=0; j<0x3000; j++);
					SetSliderLEDs(7);
					K_LED6 = ON;
					for (j=0; j<0x3000; j++);
					SetSliderLEDs(99);
					K_LED9 = ON;
					for (j=0; j<0x3000; j++);
					K_LED8 = ON;				// there are more keypad led's than slider
					for (j=0; j<0x3000; j++);
					K_LED5 = ON;				// so they get two of their own.
					for (j=0; j<0x3000; j++);


					// Begin resuming normal operation
					Flags.SLEEP = 0;			// Disable SLEEP flag
					FIRST = 34;				// Need to reinit all buttons cleared averages. 17butt*2ea.
					break;
				}
			}

			// If exiting sleep..
			if (Flags.SLEEP == 0) {
				// LEDs
				ClearK_LEDs();					// Init all Keypad LEDs to OFF state
				SetSliderLEDs(1);				// Init Slider Minimum LED to ON state				
				// Averages
				for (j=0; j<NUM_BTTNS; j++)
					AVERAGE[j] = 0;				// Clear all averages (so on wake does not cause issue).
				// Renable intpts
				SSPIE = 1;						// Re-enable i2c interrupt
				T0IE = 1;						// Allow cap interrupts, fully normal operation resumes
				GIE = 1;						// Re-enable interrupts on awake after the showy stuff.
				SetSlaveMode();					// Setup slave mode to talk to PC GUI (must be after wakeupwheel transmission complete)


			}

		}


	}
}







/*....................................................................
. INIT()
.
.		Initialization Routine to set up part's variables and
.	peripherals.
....................................................................*/
void INIT(void) {


	// Set Pin I/O Direction

	// Determining pin usage from schematic (help determine TRIS setting)
	//--------------------------------------------------------------------------
	//			7		6		5		4		3		2		1		0
	// PORTA	LED		LED		C2OUT	.		.		C2+		C12IN0-	C12IN1-
	// PORTB	.		.		.		.		MUXSEL	S2		S1		S0
	// PORTC	LED		LED		LED		SDA		SCL		BUZZ	LED		T1CKI
	// PORTD	.		LED		LED		LED		LED		LED		LED		LED
	// PORTE	X		X		X		X		.		LED		LED		LED
	//--------------------------------------------------------------------------

	// Set LEDs as outputs
	TRISA &= 0b00111111;
	TRISC &= 0b00011101;
	TRISD &= 0b10000000;
	TRISE &= 0b11111000;

	// Set Selector channels as outputs
	TRISB &= 0b11110000;

	// Set Buzzer as output
	TRISC &= 0b11111011;

	// Capacitive
	TRISA &= 0b11011111;		// C2OUT = output
	TRISA |= 0b00000011;		// Comparator inputs C12INx-, x=0,1  as inputs
	TRISC |= 0b00000001;		// T1CKI = input


	// SDA & SCL taken care of in ssp.h / ssp.c
	// ... 



	CapInit();					// Initialize Capacitive Sensing
	SSPInit();					// Initialize I2C Communications

		
	SliderIndex = 1;			// Index for sliders to start at 1

	GIE = 1;					// turn on the global interrupts once done w/inits
}






/*....................................................................
.	isr()
.
.		Interrupt Service Routine - is the function called when any
.	interrupt is received on the part.  The device context saves, 
.	and then redirects flow here. Program flow will be returned at
.	the end of this function.  The flagging interrupt MUST be
.	cleared in software! (or you will be stuck for-ev-er).
....................................................................*/
void interrupt isr(void)
{																		
	
	// Timer 0 Interrupt
	if (T0IF == 1 && T0IE == 1) {													// Timer 0 Overflow Occurred, 
		// Service Capacitive Routine
		// .. pending not interfering with I2C
		TMR1ON	= 0;																// stop Timer1
	
		if (Flags.SSPBF == 1)														// SSP is busy, and can not interrupt it.
			RestartTimers();														// Clear timers
		else 																		// SSP is not busy, do cap. stuff
			CapISR();																// Service Routine {resets/restarts tmrs}			
	}



	if (Flags.SLEEP && SSPIF == 1)
		SSPIF = 0;																	// In sleep mode clear all SSP comm intpts

	// SSP Interrupt
	if (SSPIF == 1 && SSPIE == 1)													// SSP Interrupt Detected
		SSPISR();


	// Timer Interrupt During Non-TMR0 Intpt?
	if (T0IF == 1)																	// Catch if timer interrupt during ssp?  Handled at end of ISR.
		RestartTimers();															// (Clears T0IF)

}





/*....................................................................
. RestartTimers()
.
.		Resets and restarts timers 0 & 1 used for capacitive sensing.
....................................................................*/
void RestartTimers(void) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -