📄 main887.c
字号:
//******************************************************************************
// 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 + -