Reply
Posts: 4
Registered: ‎12-13-2016

F700: Capacitive Sense (CS0) wrongly detects unused pins

Hey,

 

I 'm using a F700 Board. There I use the CS0 to detect caapcity changes.

I'm scanning _ALL_ the pins from P2.0 till P6.5 (on purpose).

 

I plugged in Capacities at P3.0 till P3.7 and at P5.0 till P5.7.

 

When I  run the CS0, I get results at the 10th and 20th Pin as well as the 26th till 35th Pin.

Also the Returnvalue from the board seems  to be bell-shaped.

 

My questions:

1) how to I get a precise detection on the correct pins?

2) how do I make sure, all pins are detected at the same level (Capacities have all the same length)

3) Is it just a coincidence, that very often

//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------

#include <compiler_defs.h>
#include <C8051F700_defs.h>            // SFR declarations
#include <stdio.h>

//-----------------------------------------------------------------------------
// Pin Declarations
//-----------------------------------------------------------------------------
SBIT (LED,    SFR_P1, 0);              // '0' means ON, '1' means OFF


//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------

#define SYSCLK      24500000           // SYSCLK frequency in Hz
#define BAUDRATE      115200           // Baud rate of UART in bps //was 115200
#define LED_ON           0
#define LED_OFF          1

#define SWITCH_THRESHOLD 0x4A00			// was 4A00

//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------

void SYSCLK_Init (void);
void UART0_Init (void);
void PORT_Init (void);
void OSCILLATOR_Init (void);
void CS0_Init (void);
void PCA0_Init (void);
INTERRUPT_PROTO(CS0_ComparatorInterruptServiceRoutine, INTERRUPT_CS0_GRT);


//-----------------------------------------------------------------------------
// Generic UART definitions to support both Keil and SDCC
//-----------------------------------------------------------------------------

#ifdef SDCC
#include <sdcc_stdio.h>
#endif

char *GETS (char *, unsigned int);

#ifdef __C51__
#define GETS gets
#endif

#ifdef SDCC
#include <sdcc_stdio.c>
#endif


//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------

void main (void)
{
   U8 inputcharacter;                  // Used to store character from UART

   WDTCN = 0xDE;                       // Disable watchdog timer
   WDTCN = 0xAD;

   PORT_Init();                        // Initialize Port I/O
   
   SYSCLK_Init ();                     // Initialize system clock
   UART0_Init();                       // Initialize UART0
   OSCILLATOR_Init ();                 // Initialize Oscillator
   CS0_Init();                         // Initialize capacitive touch sense
                                       // to be used as a wake-up source
   PCA0_Init();                        // Initialize PCA to control LED
   
   EA = 1;                             // Enable global interrupts

   while (1)
  {

   };
}

//-----------------------------------------------------------------------------
// Initialization Subroutines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Configure the Crossbar and GPIO ports.
//
// P0.4   digital   push-pull    UART TX
// P0.5   digital   open-drain   UART RX
//
//-----------------------------------------------------------------------------
void PORT_Init (void)
{
   // Save the current SFRPAGE
   U8 SFRPAGE_save = SFRPAGE;

   SFRPAGE = CONFIG_PAGE;

   P0MDOUT |= 0x10;                    // Enable UTX as push-pull output
   XBR0    = 0x01;                     // Enable UART on P0.4(TX) and P0.5(RX)
   XBR1    = 0x40;                     // Enable crossbar and weak pull-ups
   P1MDOUT |= 0x01;                    // P1.0 is push-pull
   P2MDIN = 0x00;                      // P2.0-P6.5 gemaess Datasheet Seite 200 alle inputs analog gesetzt
   P3MDIN = 0x00;
   P4MDIN = 0x00;
   P5MDIN = 0x00;
   P6MDIN = 0x00;
                                       
   XBR1    = 0x41;                     // Enable crossbar and enable
                                       // weak pull-ups, 1 PCA channel
   SFRPAGE = SFRPAGE_save;
}

//-----------------------------------------------------------------------------
// 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)
{
   // Save the current SFRPAGE
   U8 SFRPAGE_save = SFRPAGE;

   SFRPAGE = CONFIG_PAGE;

   OSCICN |= 0x83;                     // 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

   SFRPAGE = SFRPAGE_save;
   
}

//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Configure the UART0 using Timer1, for <BAUDRATE> and 8-N-1.
//-----------------------------------------------------------------------------
void UART0_Init (void)
{
   // Save the current SFRPAGE
   U8 SFRPAGE_save = SFRPAGE;

   SFRPAGE = CONFIG_PAGE;

   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;
   #elif (SYSCLK/BAUDRATE/2/256 < 4) 
      TH1 = -(SYSCLK/BAUDRATE/2/4);
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 01
      CKCON |=  0x01;
   #elif (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;
   #endif

   TL1 = TH1;                          // Init Timer1
   TMOD &= ~0xf0;                      // TMOD: timer 1 in 8-bit autoreload
   TMOD |=  0x20;
   TR1 = 1;                            // START Timer1
   TI0 = 1;                            // Indicate TX0 ready

   SFRPAGE = SFRPAGE_save;
}

//-----------------------------------------------------------------------------
// Oszillator_Init
//-----------------------------------------------------------------------------
//
void OSCILLATOR_Init (void)
{   
   U8 SFRPAGE_save = SFRPAGE;          // Save the current SFRPAGE

   SFRPAGE = CONFIG_PAGE;

   OSCICN |= 0x80;                     // Enable the precision internal osc.
   CLKSEL = 0x00;                      // Select internal internal osc.
                                       // divided by 1 as the system clock

   SFRPAGE = SFRPAGE_save;

}
//-----------------------------------------------------------------------------
// PCA0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// This function initializes one PCA channel to 8-bit PWM mode.
//
//-----------------------------------------------------------------------------
void PCA0_Init(void)
{
   U8 SFRPAGE_save = SFRPAGE;
   SFRPAGE = CONFIG_PAGE;
   PCA0CN    = 0x40;
   PCA0MD    = 0x00;
   PCA0CPM0  = 0x42;
   SFRPAGE = SFRPAGE_save;
}
//-----------------------------------------------------------------------------
// CS0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// This function enables capacitive touch sense peripheral CS0 and the
// CS0 comparator.  The function enables the auto-scan feature and configures
// the start of conversion source to be CS0BUSY.
//-----------------------------------------------------------------------------
void CS0_Init (void)
{
   U8 SFRPAGE_save = SFRPAGE;          // Save the current SFRPAGE


   SFRPAGE = LEGACY_PAGE;

//   CS0CF = 0x70;                       // Conversion enabled on CS0BUSY (autoscan) // overflow
 	CS0CF = 0x02; 

   									         
   CS0CN = 0x80;                       // Enable CS0, comparator 

   CS0CN |= 0x10;                      // Set CS0BUSY to begin conversions
   EIE2 |= 0x01;                       // conversion complet interrupt
   CS0TH = SWITCH_THRESHOLD;           // Set comparator threshold value


   CS0MD1 &= ~0x7;                      // Setze analog-Gain auf 1 (Default: 8, Seite 94);
//   CS0MD1 |= 0x01;                      // Setze analog-Gain auf 2


   SFRPAGE = CONFIG_PAGE;
//   CS0SS = 0x00;                       // Set channel 0 as autoscan  starting channel
//   CS0SE = 0x25;                       // Set channel 37 as autoscan end channel (datasheet 97)


   SFRPAGE = SFRPAGE_save;
}


//-----------------------------------------------------------------------------
// Interrupt Service Routines
//-----------------------------------------------------------------------------
INTERRUPT(CS0_ComparatorInterruptServiceRoutine, INTERRUPT_CS0_GRT)
{
   static S16 counter;
   CS0CN &= ~0x01;                     // Acknowledge interrupt



//printf("Channel %d (high %d, low %d)\n", (int)CS0MX, (int)CS0DH, (int)CS0DL);


   CS0CN |= 0x10;                      // Set CS0Busy to start another scan
}



INTERRUPT(CS0_ConversionInterruptServiceRoutine, INTERRUPT_CS0_EOC)
{
   
   CS0CN &= ~0x01;                     // Acknowledge interrupt
   
       printf("%02d %05d\n", (int)CS0MX, (unsigned int)CS0D);		//Kanal und Wert jeweils mit führenden Nullen,
	   																//um Länge zu vereinheitlichen	
//		printf(" %d  %x\n", (int)CS0MX, CS0D);  		//Werte aus CS0 als Hex-Werte

//     printf("Channel %d Value %d\n", (int)CS0MX, (unsigned int)(CS0D);		//debug-Version mit Text


   // Go to next channel
   ++ CS0MX;
   if (CS0MX >= 38)
   {
     // Reset to first channel
	 CS0MX = 0;
   }


   CS0CN |= 0x10;                      // Set CS0Busy to start another scan
}

//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------

2 channels return the same value?

 

Best regards,

Dominik

Highlighted
Posts: 8,109
Registered: ‎08-13-2003

Re: F700: Capacitive Sense (CS0) wrongly detects unused pins

[ Edited ]
INTERRUPT(CS0_ConversionInterruptServiceRoutine, INTERRUPT_CS0_EOC)
{   
   CS0CN &= ~0x01;                     // Acknowledge interrupt   
       printf("%

NEVER, ever do a printf in an ISR .

 

the reason for the 'doubles' is, most likely overrun

a good way would be to store the values in an array in the IS and print from that array in main.  if you have an overrun, so what, two neighbor values will be about the same

erik