📄 f93x_captouchsense_tune.c
字号:
//-----------------------------------------------------------------------------
// F93x_CapTouchSense_Tune.c
//-----------------------------------------------------------------------------
// Copyright 2007 Silicon Laboratories, Inc.
// http://www.silabs.com
//
// Program Description:
//
// This program can be used to determine the effect of supply voltage
// on the sensitivity of capacitive touch sense switches. It prints
// the oscillation period to a UART terminal.
//
// When using touch sense switches, the oscillation period of the RC
// relaxation oscillator can be used to determine when the switch
// has been pressed. The oscillation period will increase when the
// switch capacitance increases (indicating a user's finger is placed
// on the switch).
//
//
// How To Test:
//
// 1) Ensure that jumpers are placed on J12 of the C8051F930 target board
// that connect P0.4/TX to the RXD signal, P0.5/RX to the TXD signal,
// and VDD/DC+ to VIO.
// 2) Connect a USB cable from the development board to a PC
// 3) Specify the target baudrate in the constant <BAUDRATE>.
// 4) Open Hyperterminal, or a similar program, and connect to the target
// board's USB port (virtual com port).
// 5) Download and execute code on an 'F930 target board.
// 6) Touch the "Touch Sense Switches" connected to P2.0 and P2.1 and see
// the corresponding oscillation period displayed on the UART Terminal.
// The oscillation period is given in system clocks.
//
//
// Target: C8051F930
// Tool chain: Generic
// Command Line: None
//
// Release 1.0
// -Initial Revision (FB)
// -6 SEP 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 SW20_THRESHOLD 1000 // Threshold for SW20
#define SW21_THRESHOLD 1000 // Threshold for SW21
//-----------------------------------------------------------------------------
// 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 UART0_Init (void);
void PORT_Init (void);
void TouchSense_Init (void);
void Wait_MS(unsigned int ms);
void TouchSense_Update(void);
//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------
void main (void)
{
PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer
// enable)
PORT_Init(); // Initialize Port I/O
SYSCLK_Init (); // Initialize Oscillator
UART0_Init(); // Initialize UART0
TouchSense_Init(); // Initialize Comparator0 and
// Timer2 for use with TouchSense
printf("\n\nOscillation Period:\n\n");
while(1)
{
Wait_MS(25);
TouchSense_Update();
printf("\rSW20: %5d, SW21: %5d",
SW20_Timer_Count.U16, SW21_Timer_Count.U16 );
YELLOW_LED = SW20_Status;
RED_LED = SW21_Status;
}
}
//-----------------------------------------------------------------------------
// 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
}
//-----------------------------------------------------------------------------
// 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;
}
//-----------------------------------------------------------------------------
// Initialization Subroutines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// TouchSense_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Configure Comparator 0 and Timer 2 for use with Touchsense.
//-----------------------------------------------------------------------------
void TouchSense_Init (void)
{
// Initialize Comparator0
CPT0CN = 0x8F; // Enable Comparator0; clear flags
// select maximum hysterisis
CPT0MD = 0x0F; // Comparator interrupts disabled,
// lowest power mode
CPT0MX = 0xC8; // Positive Mux: P2.0 - TouchSense Switch
// Negative Mux: TouchSense Compare
// Initialize Timer2
CKCON |= 0x10; // Timer2 counts system clocks
TMR2CN = 0x16; // Capture mode enabled, capture
// trigger is Comparator0.
// Start timer (TR2 = 1).
SW20_Status = 1; // Set switch status to finger not
SW21_Status = 1; // detected.
}
//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Configure the Crossbar and GPIO ports.
//
// P0.2 digital open-drain SW2
// P0.3 digital open-drain SW3
// P0.4 digital push-pull UART TX
// P0.5 digital open-drain UART RX
//
// P1.5 digital push-pull Red LED
// P1.6 digital push-pull Yellow LED
//
// P2.0 analog open-drain Touch Sense Switch
// P2.1 analog open-drain Touch Sense Switch
//
//
//-----------------------------------------------------------------------------
void PORT_Init (void)
{
// Configure TouchSense switches
P2MDIN &= ~0x03; // P2.0, P2.1 are analog
P2MDOUT &= ~0x03; // P2.0, P2.1 are open-drain
P2 |= 0x03; // P2.0, P2.1 latches -> '1'
// Configure Hardware Switches
P0MDIN |= 0x0C; // P0.2, P0.3 are digital
P0MDOUT &= ~0x0C; // P0.2, P0.3 are open-drain
P0 |= 0x0C; // Set P0.2, P0.3 latches to '1'
// Configure LEDs
P1MDIN |= 0x60; // P1.5, P1.6 are digital
P1MDOUT |= 0x60; // P1.5, P1.6 are push-pull
// Configure UART
P0MDOUT |= 0x10; // Enable UTX as push-pull output
// Configure Crossbar
XBR0 = 0x01; // Enable UART on P0.4(TX) and P0.5(RX)
XBR2 = 0x40; // Enable crossbar and weak pull-ups
}
//-----------------------------------------------------------------------------
// SYSCLK_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This routine initializes the system clock to use the internal precision
// oscillator at its maximum frequency and enables the missing clock
// detector.
//
//-----------------------------------------------------------------------------
void SYSCLK_Init (void)
{
OSCICN |= 0x80; // Enable the precision internal osc.
RSTSRC = 0x06; // Enable missing clock detector and
// leave VDD Monitor enabled.
CLKSEL = 0x00; // Select precision internal osc.
// divided by 1 as the system clock
}
//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Configure the UART0 using Timer1, for <BAUDRATE> and 8-N-1.
//-----------------------------------------------------------------------------
void UART0_Init (void)
{
SCON0 = 0x10; // SCON0: 8-bit variable bit rate
// level of STOP bit is ignored
// RX enabled
// ninth bits are zeros
// clear RI0 and TI0 bits
if (SYSCLK/BAUDRATE/2/256 < 1) {
TH1 = -(SYSCLK/BAUDRATE/2);
CKCON &= ~0x0B; // T1M = 1; SCA1:0 = xx
CKCON |= 0x08;
} else if (SYSCLK/BAUDRATE/2/256 < 4) {
TH1 = -(SYSCLK/BAUDRATE/2/4);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 01
CKCON |= 0x01;
} else if (SYSCLK/BAUDRATE/2/256 < 12) {
TH1 = -(SYSCLK/BAUDRATE/2/12);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 00
} else {
TH1 = -(SYSCLK/BAUDRATE/2/48);
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 10
CKCON |= 0x02;
}
TL1 = TH1; // Init Timer1
TMOD &= ~0xf0; // TMOD: timer 1 in 8-bit autoreload
TMOD |= 0x20;
TR1 = 1; // START Timer1
TI0 = 1; // Indicate TX0 ready
}
//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -