Добавил:
Upload
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Микропроцессорная техника / MSP430G2xx3_Code_Examples / msp430g2xx3_pinosc_04
.c/* --COPYRIGHT--,BSD_EX
* Copyright (c) 2012, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*******************************************************************************
*
* MSP430 CODE EXAMPLE DISCLAIMER
*
* MSP430 code examples are self-contained low-level programs that typically
* demonstrate a single peripheral function or device feature in a highly
* concise manner. For this the code may rely on the device's power-on default
* register values and settings such as the clock configuration and care must
* be taken when combining code from several examples to avoid potential side
* effects. Also see www.ti.com/grace for a GUI- and www.ti.com/msp430ware
* for an API functional library-approach to peripheral configuration.
*
* --/COPYRIGHT--*/
//******************************************************************************
// MSP430G2xx3 Demo - Capacitive Touch, Pin Oscillator Method, 5 buttons, UART
//
// Description: Basic 8-button input using the built-in pin oscillation feature
// on GPIO input structure. PinOsc signal feed into TA0CLK. WDT interval is used
// to gate the measurements. Difference in measurements indicate button touch.
// Pins used for inputs listed in the diagram below.
// After each scan, one UART byte identifying the key# being pressed is
// transmitted via TimerA UART at port pin P1.1.
//
//
// ACLK = VLO = 12kHz, MCLK = SMCLK = 1MHz DCO
//
// MSP430G2xx3
// -----------------
// /|\| |
// | | |
// --|RST |
// | |
// input 1-->|P2.0 P1.1|--> TA UART output TXD
// | |
// input 2-->|P2.1 |
// | |
// input 3-->|P2.2 |
// | |
// input 4-->|P2.3 |
// | |
// input 5-->|P2.4 |
// | |
// ----------------- All five inputs are capacitive touch inputs
//
// Brandon Elliott/D. Dang
// Texas Instruments Inc.
// November 2010
// Built with IAR Embedded Workbench Version: 5.10
//******************************************************************************
#include <msp430.h>
/* Define User Configuration values */
/*----------------------------------*/
/* Defines WDT SMCLK interval for sensor measurements*/
#define WDT_meas_setting (DIV_SMCLK_512)
/* Defines WDT ACLK interval for delay between measurement cycles*/
#define WDT_delay_setting (DIV_ACLK_512)
/* Sensor settings*/
#define NUM_SEN 5 // Total number of sensors
#define KEY_LVL 190 // Defines threshold for a key press
/* Set to ~ half the max delta expected*/
/* Definitions for use with the WDT settings*/
#define DIV_ACLK_32768 (WDT_ADLY_1000) // ACLK/32768
#define DIV_ACLK_8192 (WDT_ADLY_250) // ACLK/8192
#define DIV_ACLK_512 (WDT_ADLY_16) // ACLK/512
#define DIV_ACLK_64 (WDT_ADLY_1_9) // ACLK/64
#define DIV_SMCLK_32768 (WDT_MDLY_32) // SMCLK/32768
#define DIV_SMCLK_8192 (WDT_MDLY_8) // SMCLK/8192
#define DIV_SMCLK_512 (WDT_MDLY_0_5) // SMCLK/512
#define DIV_SMCLK_64 (WDT_MDLY_0_064) // SMCLK/64
/* Global variables for sensing*/
unsigned int base_cnt[NUM_SEN];
unsigned int meas_cnt[NUM_SEN];
int delta_cnt[NUM_SEN];
unsigned char key_press[NUM_SEN];
char key_pressed;
int cycles;
const unsigned char electrode_bit_P2[NUM_SEN]={BIT0, BIT1, BIT2, BIT3, BIT4};
/* System Routines*/
void measure_count(void); // Measures each capacitive sensor
void TX_Byte (char); // Transmits key pressed via UART
/* Main Function*/
int main(void)
{
unsigned int i,j;
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
if (CALBC1_1MHZ==0xFF) // If calibration constant erased
{
while(1); // do not load, trap CPU!!
}
if (CALBC1_8MHZ==0xFF) // If calibration constant erased
{
while(1); // do not load, trap CPU!!
}
DCOCTL = 0; // Select lowest DCOx and MODx settings
BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz
DCOCTL = CALDCO_1MHZ;
BCSCTL3 |= LFXT1S_2; // LFXT1 = VLO
IE1 |= WDTIE; // enable WDT interrupt
P2SEL = 0x00; // No XTAL
__bis_SR_register(GIE); // Enable interrupts
measure_count(); // Establish baseline capacitance
for (i = 0; i<NUM_SEN; i++)
base_cnt[i] = meas_cnt[i];
for(i=15; i>0; i--) // Repeat and avg base measurement
{
measure_count();
for (j = 0; j<NUM_SEN; j++)
base_cnt[j] = (meas_cnt[j]+base_cnt[j])/2;
}
/* Main loop starts here*/
while (1)
{
j = KEY_LVL;
measure_count(); // Measure all sensors
for (i = 0; i<NUM_SEN; i++)
{
/* Handle baseline measurment for a base C decrease*/
if (base_cnt[i] < meas_cnt[i]) // If negative: result increased
{ // beyond baseline, cap decreased
base_cnt[i] = (base_cnt[i]+meas_cnt[i]) >> 1; // Re-average up quickly
delta_cnt[i] = 0; // Zero out for position determination
}
else
{
delta_cnt[i] = base_cnt[i] - meas_cnt[i]; // Calculate delta: c_change
}
if (delta_cnt[i] > j) // Determine if each key is pressed
{ // per a preset threshold
key_press[i] = 1; // Specific key pressed
j = delta_cnt[i];
key_pressed = i+1; // key pressed
}
else
key_press[i] = 0;
}
/* Delay to next sample, sample more slowly if no keys are pressed*/
if (key_pressed)
{
TX_Byte(key_pressed);
BCSCTL1 = (BCSCTL1 & 0x0CF) + DIVA_0; // ACLK/(0:1,1:2,2:4,3:8)
cycles = 20;
}
else
{
cycles--;
if (cycles > 0) // ACLK/(0:1,1:2,2:4,3:8)
BCSCTL1 = (BCSCTL1 & 0x0CF) + DIVA_0;
else
{ // ACLK/(0:1,1:2,2:4,3:8)
BCSCTL1 = (BCSCTL1 & 0x0CF) + DIVA_3;
cycles = 0;
}
}
WDTCTL = WDT_delay_setting; // WDT, ACLK, interval timer
/* Handle baseline measurment for a base C increase*/
if (!key_pressed) // adjust down if no keys touched
{
for (i = 0; i<NUM_SEN; i++)
base_cnt[i] = base_cnt[i] - 1; // Adjust baseline down, should be
} // slow to accomodate for genuine
__bis_SR_register(LPM3_bits); // changes in sensor C
}
} // End Main
/* Measure count result (capacitance) of each sensor*/
/* Routine setup for four sensors, not dependent on NUM_SEN value!*/
void measure_count(void)
{
char i;
TA0CTL = TASSEL_3+MC_2; // TACLK, cont mode
TA0CCTL1 = CM_3+CCIS_2+CAP; // Pos&Neg,GND,Cap
for (i = 0; i<NUM_SEN; i++)
{
/*Configure Ports for relaxation oscillator*/
/*The P2SEL2 register allows Timer_A to receive it's clock from a GPIO*/
/*See the Application Information section of the device datasheet for info*/
P2DIR &= ~ electrode_bit_P2[i];
P2SEL &= ~ electrode_bit_P2[i];
P2SEL2 |= electrode_bit_P2[i]; // input oscillation feeds TACLK
/* Setup Gate Timer */
WDTCTL = WDT_meas_setting; // WDT, ACLK, interval timer
TA0CTL |= TACLR; // Clear Timer_A TAR
__bis_SR_register(LPM0_bits+GIE); // Wait for WDT interrupt
TA0CCTL1 ^= CCIS0; // Create SW capture of CCR1
meas_cnt[i] = TACCR1; // Save result
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
P2SEL2 &= ~electrode_bit_P2[i];
}
TA0CTL = 0; // Stop Timer_A
}
/* Watchdog Timer interrupt service routine*/
#pragma vector=WDT_VECTOR
__interrupt void watchdog_timer(void)
{
TA0CCTL1 ^= CCIS0; // Create SW capture of CCR1
__bic_SR_register_on_exit(LPM3_bits); // Exit LPM3 on reti
}
/* UART Information: Conditions for 9600 Baud SW TX-only UART, SMCLK = 8MHz */
#define Bitime 0x0341 // x us bit length ~ x baud
#define TXD BIT1 // TXD on P1.1
unsigned int RXTXData;
unsigned char BitCnt;
void TX_Byte (char TX_DATA)
{
DCOCTL = 0; // Select lowest DCOx and MODx settings
BCSCTL1 = CALBC1_8MHZ; // Set DCO to 8MHz
DCOCTL = CALDCO_8MHZ;
TX_DATA += '0'; // Convert key# to ASCII character
CCTL0 = OUT; // TXD Idle as Mark
TACTL = TASSEL_2 + MC_2; // SMCLK, continuous mode
P1SEL |= TXD;
P1DIR |= TXD;
BitCnt = 0xA; // Load Bit counter, 8data + ST/SP
CCR0 = TAR; // Current state of TA counter
CCR0 += Bitime; // Some time till first bit
RXTXData = TX_DATA;
RXTXData |= 0x100; // Add mark stop bit to RXTXData
RXTXData = RXTXData << 1; // Add space start bit
CCTL0 = CCIS0 + OUTMOD0 + CCIE; // TXD = mark = idle
while ( CCTL0 & CCIE )
{
__bis_SR_register(LPM0_bits); // Enter LPM0
}
DCOCTL = 0; // Select lowest DCOx and MODx settings
BCSCTL1 = CALBC1_1MHZ; // return DCO to 1MHz
DCOCTL = CALDCO_1MHZ;
P1SEL &= ~TXD;
TACTL = 0; // Stop Timer
}
/* Timer A0 interrupt service routine*/
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A0 (void)
{
if (CCTL0 & CCIS0) // TX on CCI0B?
{
CCR0 += Bitime; // Add Offset to CCR0
if ( BitCnt == 0)
CCTL0 &= ~ CCIE; // All bits TXed, disable interrupt
else
{
if (RXTXData & 0x01)
CCTL0 &= ~ OUTMOD2; // TX Mark
else
CCTL0 |= OUTMOD2; // TX Space
RXTXData = RXTXData >> 1;
BitCnt --;
}
CCTL0 &= ~ CCIFG;
}
else // for LED gradient only
TACCTL0 &= ~CCIE; // interrupt disbled
__bic_SR_register_on_exit(LPM0_bits);
}
Соседние файлы в папке MSP430G2xx3_Code_Examples