Pic18 CTMU demo code

Discussion in 'Embedded Systems and Microcontrollers' started by nsaspook, Dec 15, 2011.

  1. nsaspook

    Thread Starter AAC Fanatic!

    Aug 27, 2009
    2,907
    2,167
    The CTMU module available on some newer PIC18 chips is a bag full of tricks.
    http://ww1.microchip.com/downloads/en/AppNotes/01375a.pdf

    This simple C18 PIC18F46K22 demo only uses the capacitive touch function to read a single touch pad, return a button pressed flag and a proximity value.
    First image:

    The basic application is in this Microchip app-note.
    http://ww1.microchip.com/downloads/en/AppNotes/01250a.pdf

    This version uses timer0 interrupts instead of delay loops and the ADC interrupt to signal the conversion so it runs as a background process updating a 'button pressed' flag and result variables.

    Device setup:

    Code ( (Unknown Language)):
    1.  
    2. int ctmu_setup(unsigned char current)
    3. {
    4.   //CTMUCONH/1 - CTMU Control registers
    5.   CTMUCONH = 0x00; //make sure CTMU is disabled
    6.   CTMUCONL = 0x90;
    7.   //CTMU continues to run when emulator is stopped,CTMU continues
    8.   //to run in idle mode,Time Generation mode disabled, Edges are blocked
    9.   //No edge sequence order, Analog current source not grounded, trigger
    10.   //output disabled, Edge2 polarity = positive level, Edge2 source =
    11.   //source 0, Edge1 polarity = positive level, Edge1 source = source 0,
    12.   //CTMUICON - CTMU Current Control Register
    13.   CTMUICON = 0x01;       //.55uA, Nominal - No Adjustment default
    14.   charge_time=TIMERCHARGE_BASE;   // slower
    15.   if (current == 0x02) {
    16.    CTMUICON = 0x02;  //5.5uA, Nominal - No Adjustment
    17.    charge_time=TIMERCHARGE_BASE_X10; // faster
    18.   }
    19.   /**************************************************************************/
    20.   //Set up AD converter;
    21.   /**************************************************************************/
    22.   // Configure AN0 as an analog channel
    23.   ANSELAbits.ANSA0=1;
    24.   TRISAbits.TRISA0=1;
    25.   // ADCON2
    26.   ADCON2bits.ADFM=1; // Results format 1= Right justified
    27.   ADCON2bits.ACQT=1; // Acquition time 7 = 20TAD 2 = 4TAD 1=2TAD
    28.   ADCON2bits.ADCS=2; // Clock conversion bits 6= FOSC/64 2=FOSC/32
    29.   // ADCON1
    30.   ADCON1bits.PVCFG0 =0; // Vref+ = AVdd
    31.   ADCON1bits.NVCFG1 =0; // Vref- = AVss
    32.   // ADCON0
    33.   ADCON0bits.CHS=0;  // Select ADC channel
    34.   ADCON0bits.ADON=1;  // Turn on ADC
    35.   PIE1bits.ADIE=1; // enable ADC int
    36.  return 0;
    37. }
    38.  
    isr code (with debug code flags and leds on outputs) :
    Code ( (Unknown Language)):
    1.  
    2. #pragma interrupt high_handler
    3. void high_handler (void)
    4. {
    5.         if ( INTCONbits.TMR0IF ) {        // check timer0 irq
    6.    if (!CTMUCONHbits.IDISSEN) {      // charge cycle timer0 int, because not shorting the CTMU voltage.
    7.     CTMUCONLbits.EDG1STAT = 0;       // Stop charging touch circuit
    8.     TIME_CHARGE=FALSE;        // clear charging flag
    9.     CTMU_WORKING=TRUE;        // set working flag, doing touch ADC conversion
    10.     // configure ADC for next reading
    11.     ADCON0bits.CHS=0;         // Select ADC channel
    12.     ADCON0bits.ADON=1;         // Turn on ADC
    13.     ADCON0bits.GO=1;         // and begin A/D conv, will set adc int flag when done.
    14. //    LATCbits.LATC7=!LATCbits.LATC7;     // blink led
    15.    } else {           // discharge cycle timer0 int, because CTMU voltage is shorted
    16. //    LATCbits.LATC6=!LATCbits.LATC6;     // blink led
    17.     CTMUCONHbits.IDISSEN = 0;       // end drain of touch circuit
    18.     TIME_CHARGE=TRUE;        // set charging flag
    19.     CTMU_WORKING=TRUE;        // set working flag, doing
    20.           WriteTimer0 ( charge_time );     // set timer to charge rate time
    21.     CTMUCONLbits.EDG1STAT = 1;       // Begin charging the touch circuit
    22.    }
    23.             // clr  TMR0 int flag
    24.          INTCONbits.TMR0IF = 0;         //clear interrupt flag
    25.   }
    26.   if (PIR1bits.ADIF) {         // check ADC irq
    27.    PIR1bits.ADIF = 0;          // clear ADC int flag
    28. //   LATCbits.LATC5=!LATCbits.LATC5;      // blink led
    29.    Vread = ADRES;           // Get the value from the A/D
    30.    Vread= (Vread >>3)&0x007f;       // toss lower bit noise and mask
    31.    if(Vread < (touch_base - TRIP)) {     // see if we have a pressed button
    32.     switchState = PRESSED;
    33.     LATCbits.LATC4=OFF;
    34.    } else if(Vread > (touch_base - TRIP + HYST)) {
    35.     switchState = UNPRESSED;
    36.     LATCbits.LATC4=ON;
    37.    }
    38.    CTMU_ADC_UPDATED=TRUE;        // New data is in Vread, set to FALSE in main program flow
    39.    CTMU_WORKING=FALSE;         // clear working flag, ok to read Vread.
    40.    // config CTMU for next reading
    41.    CTMUCONHbits.CTMUEN = 1;        // Enable the CTMU
    42.    CTMUCONLbits.EDG1STAT = 0;        // Set Edge status bits to zero
    43.    CTMUCONLbits.EDG2STAT = 0;
    44.    CTMUCONHbits.IDISSEN = 1;        // drain charge on the circuit
    45.          WriteTimer0 ( TIMERDISCHARGE );      // set timer to discharge rate
    46.   }
    47.         if ( PIR1bits.TMR2IF ) {
    48.                 PIR1bits.TMR2IF = 0;       // clear TMR2 int flag
    49.   }
    50. }
    51.  
    52.  
    Timer0 is set to send a interrupt when the count is done, a small 'charge' value is set/counter started and the CTMU constant current device is enabled. When the timer0 interrupt happens the CTMU current device is stopped and a ADC conversion to read the touch-pad/finger capacitor charge voltage value is started. The ADC has been configured to send a interrupt when the conversion is done. The ADC section of the ISR code reads the ADC value, sets the CTMU discharge flag, shorts the touch-pad ADC input to ground to zero the voltage and sets timer0 again with a longer 'discharge' value. When timer0 again sends a interrupt the ISR looks at the CTMU discharge flag, opens the ground to the touch-pad and reloads timer0 with the 'charge' value and enables the current device again to restart the process.

    The o-scope trace below explains the sequence.
    Second image:

    The demo 'rgbled template code' just reads the touch-pad values and flashes the random RGB outputs as the pad is touched. I'll post a few pictures later.
     
    Last edited: Dec 20, 2011
  2. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    I actually won't be surprised when they introduce on chip VGA with HDMI output.
     
  3. nsaspook

    Thread Starter AAC Fanatic!

    Aug 27, 2009
    2,907
    2,167
  4. nsaspook

    Thread Starter AAC Fanatic!

    Aug 27, 2009
    2,907
    2,167
    CTMU touch demo code updated.
     
  5. kirankumar8951

    New Member

    Aug 5, 2014
    3
    0
    Hi Nsaspook

    I am trying to interface pic18f44k22 with capacitance touch key, before that i am trying to understand your attached zip code and other detail.

    Problem faced: unable to build your code
    Error [1105] symbol 'CCP_5_SEL_TMR12' has not been defined
    Error [1105] symbol 'T2_PS_1_1' has not been defined
    Error [1105] symbol 'T2_POST_1_8' has not been defined
    Warning [2058] call of function without prototype

    Details required:
    1)Please give the circuit diagram of your program.
    2)the above symbols are defined in timers.h file but why it is still showing error?
    3)I am new to this pic micro controller and capacitance touch so can you please share more details about this project ?
    4) which compiler has been used in this project?

    I appreciate your work in this thread.

    Regards
    Kiran Kumar
     
Loading...