📄 f93x_captouchsense_switch.c
字号:
//-----------------------------------------------------------------------------
// F93x_CapTouchSense_Switch.c
//-----------------------------------------------------------------------------
// Copyright 2007 Silicon Laboratories, Inc.
// http://www.silabs.com
//
// Program Description:
//
// This program lights up the yellow LED on the C8051F93x target board when
// the capacitive touch sense (contactless) switch (P2.0) is touched. It
// also lights up the red LED when the (contactless) switch (P2.1) is touched.
//
// A relaxation oscillator is implemented using an on-chip analog comparator
// and external resistors R15 through R19. The high-to-low transitions of the
// relaxation oscillator are counted by Timer0. The relaxation oscillator
// frequency depends on the capacitance of the touch sense trace capacitor.
// The count of Timer0 is periodically checked on every Timer2 overflow.
// Depending on the count, it can be determined whether SW3 is being touched
// or not.
//
//
// How To Test:
//
// Setup:
// 1) Download code to the 'F930 target board
// 2) Ensure that pins 1-2, 3-4, 5-6, and 7-8 are shorted on the J8 header
//
// One Time Calibration (stored in non-volatile flash):
// 1) Both LEDs will be lit. Place a finger on either Touch Sense Pad (P2.0
// or P2.1), and hold it there. Do not remove this finger till step 3.
// 2) Press and hold switch SW2 (P0.2) for if your finger ison Touch Sense
// Pad (P2.0). Otherwise press and hold SW3 (P0.3) if your finger is on
// Touch Sense Pad (P2.1). Release the switch after 1 second.
// 3) The red LED will continue to be lit if your finger was touching the
// P2.0 pad. The yellow LED will continue to be lit if your finger was touching
// the P2.1 pad. Remove finger from the Touch Sense Pad. The LEDs should
// switch off.
//
// Usage:
// 1) Touch SW20. The Red LED (P1.6) should light up in response.
// 2) Touch SW21. The Yellow LED (P1.5) should light up in response.
//
// Target: C8051F930, C8051F920
// Tool chain: Generic
// Command Line: None
//
// Release 1.0
// -Initial Revision (FB)
// -5 OCT 2007
//
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <compiler_defs.h>
#include <C8051F930_defs.h> // SFR declarations
#include <stdio.h>
//-----------------------------------------------------------------------------
// Pin Declarations
//-----------------------------------------------------------------------------
SBIT (RED_LED, SFR_P1, 5); // '0' means ON, '1' means OFF
SBIT (YELLOW_LED, SFR_P1, 6); // '0' means ON, '1' means OFF
SBIT (SW2, SFR_P0, 2); // SW2 == 0 means switch pressed
SBIT (SW3, SFR_P0, 3); // SW3 == 0 means switch pressed
//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------
#define SYSCLK 24500000 // SYSCLK frequency in Hz
#define BAUDRATE 230400 // Baud rate of UART in bps
#define LED_ON 0 // Macros to turn LED on and off
#define LED_OFF 1
#define SW21_SENSITIVITY 250 // Sensitivity value used for both
// Touch Sense switches. Larger values
// make sthe switches more sensitive
#define CAL_ADDRESS 0 // Address in the scratchpad to store
// the calibrated switch value
#define SCRATCHPAD 1 // Passed to the Flash access routines
// to indicate that the calibration
// constant is located in the scratchpad
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
// Timer2 count of SW20 relaxation oscillator transitions
UU16 SW20_Timer_Count;
UU16 SW21_Timer_Count;
// Touch Switch: SW20==0 means finger sensed; SW20==1 means finger not sensed.
U8 SW20_Status;
U8 SW21_Status;
//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------
void SYSCLK_Init (void);
void PORT_Init (void);
void TouchSense_Init (void);
void Wait_MS(unsigned int ms);
void TouchSense_Update(void);
void Calibrate (void);
U16 Get_Calibration(void);
// FLASH read/write/erase routines
void FLASH_ByteWrite (U16 addr, U8 byte, U8 SFLE);
U8 FLASH_ByteRead (U16 addr, U8 SFLE);
void FLASH_PageErase (U16 addr, U8 SFLE);
//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------
void main (void)
{
PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer
// enable)
PORT_Init(); // Initialize Port I/O
SYSCLK_Init (); // Initialize Oscillator
TouchSense_Init(); // Initialize Comparator0 and
// Timer2 for use with TouchSense
if( Get_Calibration() == 0xFFFF)
{
Calibrate ();
}
while(1)
{
Wait_MS(25); // Polling Interval
if(!SW2 || !SW3) // If the P0.2 Switch is Pressed
{
Calibrate(); // Calibrate the Touch Pads
}
TouchSense_Update(); // Update switch variables
YELLOW_LED = SW20_Status; // Set LED states based on the
RED_LED = SW21_Status; // switch variables
}
}
//-----------------------------------------------------------------------------
// Support Subroutines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// TouchSense_Update
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Configure the Crossbar and GPIO ports.
//
//
//-----------------------------------------------------------------------------
void TouchSense_Update (void)
{
UU16 timer_count_A, timer_count_B;
// Prepare Timer2 for the first TouchSense reading
TMR2CN &= ~0x80; // Clear overflow flag
while(!(TMR2CN & 0x80)); // Wait for overflow
timer_count_A.U16 = TMR2RL; // Record value
// Prepare Timer2 for the second TouchSense reading
TMR2CN &= ~0x80; // Clear overflow flag
while(!(TMR2CN & 0x80)); // Wait for overflow
timer_count_B.U16 = TMR2RL; // Record value
// Calculate the oscillation period
SW20_Timer_Count.U16 = timer_count_B.U16 - timer_count_A.U16;
// Change the CP0 Multiplexer to select switch on P2.1
CPT0MX = 0x8C; // Positive Mux: TouchSense Compare
// Negative Mux: P2.1 - TouchSense Switch
// Prepare Timer2 for the first TouchSense reading
TMR2CN &= ~0x80; // Clear overflow flag
while(!(TMR2CN & 0x80)); // Wait for overflow
timer_count_A.U16 = TMR2RL; // Record value
// Prepare Timer2 for the second TouchSense reading
TMR2CN &= ~0x80; // Clear overflow flag
while(!(TMR2CN & 0x80)); // Wait for overflow
timer_count_B.U16 = TMR2RL; // Record value
// Calculate the oscillation period
SW21_Timer_Count.U16 = timer_count_B.U16 - timer_count_A.U16;
// Change the CP0 Multiplexer to select switch on P2.0
CPT0MX = 0xC8; // Positive Mux: P2.0 - TouchSense Switch
// Negative Mux: TouchSense Compare
// Update the status variable for SW20
if(SW20_Timer_Count.U16 > (Get_Calibration() - SW21_SENSITIVITY))
{
SW20_Status = 0;
} else
{
SW20_Status = 1;
}
// Update the status variable for SW21
if(SW21_Timer_Count.U16 > (Get_Calibration() - SW21_SENSITIVITY))
{
SW21_Status = 0;
} else
{
SW21_Status = 1;
}
}
//-----------------------------------------------------------------------------
// Wait_MS
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters:
// 1) unsigned int ms - number of milliseconds of delay
// range is full range of integer: 0 to 65335
//
// This routine inserts a delay of <ms> milliseconds.
//-----------------------------------------------------------------------------
void Wait_MS(unsigned int ms)
{
char i;
TR0 = 0; // Stop Timer0
TMOD &= ~0x0F; // Timer0 in 8-bit mode
TMOD |= 0x02;
CKCON &= ~0x03; // Timer0 uses a 1:48 prescaler
CKCON |= 0x02;
TH0 = -SYSCLK/48/10000; // Set Timer0 Reload Value to
// overflow at a rate of 10kHz
TL0 = TH0; // Init Timer0 low byte to the
// reload value
TF0 = 0; // Clear Timer0 Interrupt Flag
ET0 = 0; // Timer0 interrupt disabled
TR0 = 1; // Timer0 on
while(ms--)
{
for(i = 0; i < 10; i++)
{
TF0 = 0;
while(!TF0);
}
}
TF0 = 0;
}
//-----------------------------------------------------------------------------
// Calibrate
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This routine will store the touch value in non-volatile Flash memory as
// the calibration threshold for the switch SW21.
//
// 1. Place a finger on the touch switch SW21, and hold it there.
// 2. Press switch SW2 (P0.7) for >1 sec and release using another finger.
// 3. Remove finger from SW21.
//-----------------------------------------------------------------------------
void Calibrate (void)
{
U8 EA_Save;
U8 switch_number;
YELLOW_LED = LED_ON;
RED_LED = LED_ON;
while (SW2 && SW3); // Wait till any switch is pressed
if(!SW2) // Decode which switch was pressed
{
switch_number = 0;
} else
{
switch_number = 1;
}
while (!SW2 || !SW3); // Wait till switches released
EA_Save = IE; // Preserve EA
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -