Archive for the ‘Embedded Systems’ Category

Microchip PIC16F883 Anomolies And Other Odd Behaviours

Saturday, May 16th, 2009

Recently we completed a development project which made use of the Microchip Technologies PIC16F883 microcontroller. This is a newer style PIC flash micro that includes a low voltage flash programming mode and some other enhancements to its power management and oscillator blocks. We like PIC micros because they are inexpensive, reasonably power thrifty, and normally very easy to use. We stepped on a couple of land mines with the 883 however. The first had to do with that low voltage programming mode. The documentation for this part states that the standard HV programming mode will override the low voltage programming mode. This simply isn’t true.  The documentation is confusing because it does not show the PGM pin on the standard connection diagram for the in-system programming interface. The parts are shipped from the factory with the internal configuration bit for low voltage programming enabled. Because of this, inserting the parts in a programming socket you’ve been using for something like a PIC16F685, for example, will FAIL unless you ground the PGM pin. After turning off the low voltage programming bit, the PGM pin can then be used as an ordinary GPIO pin and your HV programming issues will go away.  It’s also necessary to add a pull down resistor to the PGM pin on the board you install the 16F883 in to prevent T=0 problems with programming at manufacturing time.  The Microchip documentation is not at all clear about this so be careful.

Another stumbling block was sleep/wake. Since the 16F883 is code compatible with other parts in this series such as the 16F685, and the data sheet listed the same example code as for the 16F685, we had to struggle a bit with the 16F883 when it refused to wake up after entering sleep mode.  We never did get a satisfactory answer back from the Microchip forum about this so are publishing this here for your enjoyment and perusal.  Here is the sleep entry code for the 16F883, our first attempt:

MAIN_sleep_entry
	BANKSEL	PORTA
	clrf	PORTA
	BANKSEL TRISC
	clrf	TRISC	    ;all to outputs
	movlw	H'20'	    ;only enable bit 5
	movwf	IOCB
	bcf	PIE1,TMR1IE ;stop timer 1 ints while here in this bank...
	bcf	PIR1,TMR1IF ;case we come here from interrupt routine...
	bcf	INTCON,T0IE ;make sure timer 0 can't hit us either...
	BANKSEL	T2CON
	bcf	T2CON,TMR2ON ;stop timer
	BANKSEL PORTA
	clrf	PORTC
	clrf	PORTB
	movf	PORTB,W	    ;dummy read to clear state change ff's
	movf	PORTB,W		;again for good measure...
	bcf	INTCON,RBIF
	bsf	INTCON,RBIE ;arm wake up detection
	bsf	INTCON,GIE
	clrwdt
	BANKSEL WDTCON
	bcf	WDTCON,SWDTEN
	bcf	INTCON,T0IF
	bcf	INTCON,INTF
	bcf	INTCON,RBIF
	nop
	sleep

This is the same code sequence previously used for the 16F685, but for some reason the 16F883 would never wake up.  After trying several things, without success, we added this code right before sleep entry:

	.....
        bcf	INTCON,RBIF
	btfsc	INTCON,RBIF
	goto	$2
	nop
	sleep

Since we still went to sleep, obviously the RBIF flag was getting cleared, later verified by stepping through with the ICD2 debugger.  But it still looked for all the world like the RBIF flag was still setting prior to sleep entry.  So we tried another hack.  At the dispatcher at the top of the interrupt service routine we added a handler for the wake interrupt:

	...
	btfsc	INTCON,RBIF
	goto	SLEEP_WAKE
	goto	IRQ_DONE	;wild interrupts are ignored

SLEEP_WAKE
	bcf	INTCON,RBIF	;this might be causing problems
	goto	IRQ_DONE	;

Sure enough, after handling the RBIF flag inside interrupt context, the wakeup circuitry was armed and we could now wake the 16F883.  So what’s going on here?  The RBIF flag can obviously be cleared from normal context but it won’t stay  cleared unless it’s cleared inside interrupt context.  This isn’t the way the 16F685 behaves and sounds like we have the makings of a nice little hardware bug here.  Comments?

Applying the Quantum Touch QT1081 Touch Controller

Tuesday, March 17th, 2009

We had a customer come to us recently with a design proposal for a small portable device.  The product concept included a small LCD display, a couple LED’s, and a mylar keypad with 8 buttons.  I had been looking for a project which I could use as a vehicle to check out the Quantum QT1081 8 channel touch controller.  (Quantum is now owned by Atmel, see here.)  Because the product is lightweight, and may be either hand held or placed on a table when used, the force required to activate a typical mylar keypad seemed like it would interfere with the use of the product.  Plus there’s the cost of fabricating the keypad.  The button array of a capacitive touch keypad can simply be created on a standard single sided printed circuit board, and requires no force to activate.  Because a finger touch can be reliably sensed from several mm away, in this product the copper pads are on the back of the switch array, which is overlaid with a layer of plastic on which the key legends are printed.  Because of the dielectric characteristics of FR4 material used to make printed circuit boards, the board helps to “focus” the electric field coming off the pad.  As a result, the sensitivity to touch on the back side of the board is increased.

I found with the QT1081 chip that key presses were very reliable, with no issues with double hits, etc., that one might encounter with a mylar keypad.  The sensitivity of each key pad is easily adjusted to compensate for the differing amounts of stray capacitance associated with each key pad.  Best of all, the power consumption is very low.  A system using a PIC16F883 processor running at 4MHz with the QT1081 detecting a single key consumes only 2.4mA from a 3.0V supply.  An overview of the operation of digital capacitive touch technology can be found here.

Adjusting QT1081 key touch sensitivity

A datasheet for the QT1081 may be found here.  Please download this and turn to page 6, as figure 1.1 contains a reference schematic which will be used for the remainder of this discussion.  The values shown for the resistors and capacitors connected to the SNS** pins are good starting values.  The 1M resistors that are used to set the AT1081 operating modes will affect the sensitivity of their respective key inputs.  I discovered that SNS pins that were pulled to ground were less affected than SNS pins that were pulled off to VDD.  The values for CS0 through CS7 are MINIMUM values it seems.  I found that with the CS* capacitors set to 1000pF (1nF), keys with option resistors pulled off to VDD would not reliably detect a touch.  However, increasing CS slightly for those inputs to 2000pF resulted in working keys.  The datasheet claims that capacitors as large as 50nF (0.05μF) can be used for sensing capacitors.  Power consumption increases as larger values are used for CS.  Use no more capacitance for CS than necessary to achieve reliable operation.  Capacitor selection is discussed in section 3.3, page 11, of the datasheet.

Capacitive touch opens up many new design possibilites.  Other touch controllers in Quantum’s product line include slider bar and wheel sensors with up to 256 discrete positions that can be sensed.  Elimination of mechanical switches can be a huge win in terms of product styling and reliability, as well as cost reduction.  Because the Quantum components use a digital algorithm they are able to adapt to long term changes in the capacitance of the button array, such as water droplets on the sensing surface.  This reduces issues with “stuck” keys.