Jump to content

External Switches And The Picdem2 Plus

Recommended Posts

I am new to boostc and I am trying to modify the example "BUTTON TEST" under the post "pic Micro Programming In Boostc For Beginners" except using a 18F4520 (from my PICDEM2 Plus) using Port A for my switches and port B for my output LEDs I am just trying to turn on the corresponding LED for the switch that is pressed. the only switch that ever works is the one associated with ra4. I verified that all of the LEDs work with the ra4 switch and I was wondering if there is something wrong with my code? Thanks!



#include <system.h>

#include <string.h>

#include <icd2.h> // only required if using ICD2

#include <stdio.h>

#include <lcd_driver.h> // LCD template code




// Settings for the GREEN PICDEM 2 Plus Demo Board


#define LCD_ARGS 1, /* Interface type: mode 0 = 8bit, 1 = 4bit(low nibble), 2 = 4bit(upper nibble) */ \

0, /* Use busy signal: 1 = use busy, 0 = use time delays */ \

PORTD, TRISD, /* Data port and data port tris register */ \

PORTD, TRISD, /* Control port and control port tris register */ \

4, /* Bit number of control port is connected to RS */ \

5, /* Bit number of control port is connected to RW */ \

6 /* Bit number of control port is connected to Enable */





// Configuration Registers for PIC18F4520


#ifdef _PIC18


#pragma DATA _CONFIG2L, _BOREN_ON_2L & _BORV_3_2L & _PWRT_ON_2L

#pragma DATA _CONFIG2H, _WDT_OFF_2H & _WDTPS_128_2H



#pragma DATA _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L & _CP2_OFF_5L & _CP3_OFF_5L


#pragma DATA _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L & _WRT2_OFF_6L & _WRT3_OFF_6L








#pragma CLOCK_FREQ 4000000 // Sets Clock Frequency


#define button1 porta.1

#define button2 porta.2

#define button3 porta.3

#define button4 porta.4



void main()



trisa=0x1E; // set porta pins 1~4as input.

trisb=0; // set portb pins as output.

portb=0; // set portb pins to low.



while(1) // infinite loop.




portb.0 = 1;




portb.1 = 1;




portb.2 = 1;




portb.3 = 1;




portb = 0;





Link to post
Share on other sites

You have fell into the standard trap of not setting the ADCON1 to turn the default analog inputs into digital inputs. Try adding adcon1 = 0x0f when initialising.





Edited by Reynard
Link to post
Share on other sites

Edit2: Reynard has found your problem. You should also set CMCOM appropriately to disable the comparators on this port rather than relying on the POR/BOR default value.

(Was: 'Reynard has found part of your problem. you'll also need to set cmcom appropriately to disable the comparitors on this port.' - Thanks Reynard for picking up my error:- CMCON defaults to 0x07 on POR/BOR so it will work even if you don't explicitly set it)


If you look at the PIC18F4520 datasheet DS39631E - page 105, you'll see a suitable assembler sequence to initialise port A for digital I/O. You need to duplicate this in C.

N.B. the line 'MOVWF 07h ; Configure comparators' in example 10-1 is an error. it should be 'MOVLW 07h ; Configure comparators'


Also is your PICDEM 2 Plus definitely the GREEN ROHS version? The old pre ROHS RED ones had RA1-3 connected to the LCD. As they are outputs to the LCD, it would be extremely difficult to use them for switch inputs as well.


Finally, what pull-up resistors are you using for your switches? Pin RA4 has a pull-up resistor on board for switch S2, but the other pins are floating and you *MUST* provide suitable pull-ups if you want sensible results.


Edit: The RoHS (Green) PICDEM2 Plus Schematic can be found *HERE* for anyone else following this thread.

Edited by IanM
Link to post
Share on other sites
Ah! Yes But, No But !


CMCON is set to 0x07 on RESET dude.






<eats crow> :-)


You are correct and assuming the OP has enough digital experience to connect switches appropriately, the additional line: adcon1=0x0f; should be sufficient to get his code working.

I'm editing my earlier post accordingly.

BUT . . .


*AARGH* assuming reset values!


It's set to 0x07 till they shrink the die or respin the mask and issue a PICnnFnnnnA variant!

IIRC Microchip have had serious errata on the comparators in older PICs and that's one peripheral I never assume will 'just work'!


Trawling through the data sheet and all the errata to see what parts of your initiallisation code one can omit is *rarely* worthwhile and is IMHO not *good* programming practice. I'd only rely on initial POR/BOR values if I needed to minimize code size because of PIC or compiler code space limits and if there was no budget for increasing the code space.


Did you have a look at the RoHS PICDEM 2 schematic? If the OP hasn't fitted pullup resistors and there is even a few uA leakage across the switches, they'll still be stuck at zero even after he initialises ADCON1. If he had the old PICDEM2, the internal pull-ups in the LCD module would let switches on RA1-3 work without external pull-ups, but that doesn't work on the RoHS version as they moved the LCD control to a different port!

Link to post
Share on other sites

Hi Ian,


Well, you have to read and believe the manual at some point. You cannot initialise every register in a PIC of this size just in case the RESET did not do what it said it would in the manual.


Some PICs do have an errata sheet as long as your arm which is sad, but they should also be read along with the manual.


As for the switches; I don't know how they are wired up. Do they just short to ground, do they switch between 0V and +5V using SPDT, do they come through some logic such as RS flip-flop for debouncing etc. etc.


I use an EasyPIC5 board when I am playing around with PICs. It has a nice grachic display and touch screen interface on it. A good all round board.





Link to post
Share on other sites

I agree you cant initialise *every* register, but you should initialise important ones. Failing to do so is equivalent to using an uninitialised variable in C, which of course should be zero but I've seen some interesting bugs when a variable or its storage gets reused . . . .


As the PIC18F4520 data sheet DS39631E - page 105, example 10-1 code example for initialising Port A explicitly sets CMCON, I'd do the same unless a search of the errata and application notes found advice *NOT* to set it.


Feel free to differ, this sort of defensive coding is much like religion or politics :-)


As for wiring the switches:


With TTL logic, it was always 'natural' to implement a switch outputting logic '0' with the switch going to ground with a pull-up resistor to the supply. The asymmetric input made it much more difficult to wire the switch to output logic '1'. This carried over into early microcontroller design practice and is something of a standard. If its for a demo board where there is a risk the user may configure that pin as an output, a series resistor should be included to prevent damage if the button is held down while the pin is outputting '1'. e.g. see RA4 on the PICDEM 2 Plus schematic.


Switching between +5V and ground with a SPDT switch is rarely done and costs more. (Unless a protection resistor is included, the direct connection of +5V to an input pin increases the risk of latch-up, especially since the switch toggle provides an easy path for ESD to reach the pin.) It is of course unavoidable if you want to use a centre off switch to input a tri-state value but a series resistor and small capacitor to ground both provide protection and make the tristate code simpler.


A fully de-bounced in hardware switch is rarely seen nowadays as debouncing in software/firmware is essentially free if the design has any spare processing power.

It's still essential if working with discrete logic and is useful if manually pulsing a processors clock or interrupt pins.


I would hope the OP has some variant of a simple button with pull-up or pull-down as appropriate but as you point out we don't know. . .


He does say that the only one that works is RA4 which would lead me to think he is expecting logic '1' when the switch is pressed to turn the LED on otherwise as without setting ADCON1, RA1-3 read as '0' he'd probably have complained that three of his LEDS were on all the time . . . .

Link to post
Share on other sites

There is more than one way to skin at cat and I doubt if any of them is the correct way.


You should initialise the important registers, but what are the important register ? Port A supports several peripherals like ADC, USB, timer input etc. Should you initialise all of them just to make sure they are in the correct state.


The example is just that. An example. It is not the definitive method of initialising Port A.


I am sure the OP will use the appropriate method of interfacing his switches depending on the final application.





Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...