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

📄 f93x_captouchsense_switch.c

📁 C8051F9XX单片机人体感应按键的示例程序
💻 C
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
// 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 + -