PIC18F452, chip interfering with DIP switch

Started by scubagreg7777777 December 4, 2004


Hi everyone,

I'm pretty new to PICS, but will do my best to characterize my problem
and provide as much pertinent info as possible. I perplexed as to
what is going on with my PIC. I am using an 18f452 on a PICDEM 2 Plus
board, and my own PCB that I milled.

Here is the problem:

I have a 4-bit, high asserting DIP switch, with its input being sent
to PORTC.RC1 through PORTC.RC4.

Using an oscilliscope on the output I can observe that the switch is
indeed workin, switching from ~0v to ~5v. However, as soon as I plug
the PIC18F452 into the board, the DIP switch no longer responds (still
viewing the output on a scope), and stays a flat ~0v, regardless of
how the DIP is asserted. As soon as I pop the chip out, the switch
is back to normal, and switches from 0v to 5v.

Furthermore, If I touch a PORTC pin with a 5v connection, the software
behaves how it should, and outputs on PORTD. It seems that the DIP
switches simply stop working.

I am using a 160ohm resistor, and there isn't too much else about my
setup. I have been able to repeat this behaviour on both the PICDEM 2
Plus board, and my own PCB. Below is a picture of my setup, and I
have attached a copy of my code (using MCC18 compiled with MPLAB 6.4).

I have switched out PICS, but not resistors (they're soldered in, and
I do not have access to a soldering kit right now.

What really baffles me, is that as soon as I put my chip in, the
switch dies, and no longer works. If anyone has suggestions, PLEASE
let me know.

(also, as a bonus, if someone could explain why this is happening, I
would be very interested in learning how to fix this problem, and why
it happened)

Thanks in advance,

Greg (DIP setup)

5v
|
|
/
\
/ (160 ohm resistor)
\
|
|--------- output to PORTC
|

/
/ (switch)
/
|
|
|
----- (ground)
--

Code:
--------

/* Include Libraries */
#include <p18f452.h> /* for TRISB and PORTB declarations */
#include <adc.h> /* A/D library */
#include <stdlib.h> /* Standard Library */ /**********************************************/
/* Function Prototypes */

int checkSpeed( void );
int checkDip( void ); /***********************************************/
/* Variable Declaration */
/* */

/* main() */
int temp = 0; // temp variabe used in checkSpeed()
int test = 0; // test variable used in main to determine if Ra1 is
detecting high load (temp)

int dipVal = 0; // value returned from checkDip() function call
int speedVal = 0; // speed setting returned from checkSpeed()
function call
int onTime = 0; // max amount of time a particular channel/light
can be turned on
int offTime = 0; // amount of time a channel/light will be turned off
int delayCounter = 0; // counter variable, useed in output
display engine for on and off time
int speedCounter = 1; // used in nested loop to get around max
numeric value -- full explanation in dev notes
int curOutput = 1; // current chanel being output /* checkSpeed() */
int a2dSpeed = 0 ; // value obtained from a2d conversion
int userInputSpeed = 0; // speed setting, inferred from a2dSpeed
value, returned to main
// 1 = slow, 2 = medium, 3 = fast /* checkDip() */
int inputSum = 0; // final, base-10 value of user input via DIP /* customLight() */ /* delay() */
int i = 0; // counter, used for delay loop
int j = 1; // counter, used for number of loops -- speed control

void main( void )
{

/* Initialize Configuration */
TRISA = 1; // configs PORTA for INPUT -- used for checkSpeed()
TRISC = 1; // configs PORTC for INPUT -- used for checkDip()
TRISD = 0; // configs PORTD for OUTPUT -- used for light output
/* configure A/D convertors */
/* detailled explanation is located at: p 16-18 in
MPLAB-C18-Libraries.pdf */
/* ADC_FOSC_32 -> a/d clock source uses FOSC/32
ADC_RIGHT_JUST -> result in least significant bits
ADC_8ANA_0REF -> VREF+ = Vdd and VREF- = Vss (both analog)
ADC_CH# -> the channel being used
ADC_INT_OFF -> disable interrupts */

/* ADC_CH0 -> speed */
OpenADC( ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_8ANA_0REF,ADC_CH0 &
ADC_INT_OFF ); /* checkSpeed() */ /* main program */
while(1)
{

/* (re)initialize values */
speedVal = 0;
dipVal = 0; /* obtain user input */
dipVal = checkDip(); // determine DIP setting

if(dipVal == 0)
PORTD = 0;

if(dipVal == 1)
{
PORTD = 1;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;
PORTD = 0;
}

if(dipVal == 2)
{
PORTD = 1;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;
PORTD = 0;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;
PORTD = 1;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;
PORTD = 0;
}

if(dipVal == 3)
{
PORTD = 1;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;
PORTD = 0;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;

PORTD = 1;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;
PORTD = 0;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;

PORTD = 1;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;
PORTD = 0;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;
} if(dipVal == 4)
{
PORTD = 1;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;
PORTD = 0;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;

PORTD = 1;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;
PORTD = 0;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;

PORTD = 1;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;
PORTD = 0;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;

PORTD = 1;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;
PORTD = 0;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;
}

if(dipVal == 5)
{
PORTD = 1;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;
PORTD = 0;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;

PORTD = 1;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;
PORTD = 0;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;
PORTD = 1;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;
PORTD = 0;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;
PORTD = 1;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;
PORTD = 0;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;
PORTD = 1;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;
PORTD = 0;
while(speedVal < 24000) speedVal++;
while(speedVal > 3) speedVal--;

}

/* reset */
PORTD = 0;
speedVal = 0; while(speedVal < 24000) speedVal++;
speedVal = 0; while(speedVal < 24000) speedVal++;
speedVal = 0; while(speedVal < 24000) speedVal++;
speedVal = 0; while(speedVal < 24000) speedVal++;
speedVal = 0; while(speedVal < 24000) speedVal++;
speedVal = 0; while(speedVal < 24000) speedVal++;
speedVal = 0; while(speedVal < 24000) speedVal++;
speedVal = 0; while(speedVal < 24000) speedVal++;
speedVal = 0; while(speedVal < 24000) speedVal++;
speedVal = 0; while(speedVal < 24000) speedVal++;
speedVal = 0; while(speedVal < 24000) speedVal++;
speedVal = 0; while(speedVal < 24000) speedVal++;
speedVal = 0; while(speedVal < 24000) speedVal++;
speedVal = 0; while(speedVal < 24000) speedVal++;
speedVal = 0; while(speedVal < 24000) speedVal++;

} /* end while(1) */ } /* end main() */

/***************************************************
Function: checkSpeed()
Arguments: none
Return: int userInputSpeed -> digitized value of user's speed selection
(1 = slow, 2 = medium, 3 = fast)
I/O Pins Used: PORTA -> RA0

Description: checkSpeed() checks PORTA.RA0 and through a series of if
statements,
converts the voltage into one of 3 values and returns this
value
****************************************************/
int checkSpeed ( void)
{

/* AtoD Conversion */
/* CloseADC() is not used, as nowhere in the MCC18 libraries
documentation, or PIC18F452 datasheet
does it suggest leaving an A/D converter on is harmful or
discouraged. Opening the A/D converter
once (in main()'s init period, and leaving it open saves some
computational time
*/
SetChanADC( ADC_CH0 ); // Open channel 0

/* research timing constraings when using SetChanADC function call */
/* p187 - 188 in pic18f452 datasheet */
while(temp < 1200) // temporary solution
temp++;

ConvertADC(); // Start conversion
while( BusyADC() ); // Wait for completion
a2dSpeed = ReadADC(); // Read result /* The PICDEM 2 PLUS board has a 5k pot in series with a 470 ohm resistor.
The range detected by the A/D convertor is 0x000 to 0x3FF. In base10
this range is 0 to 1023. Therefore, the A/D conversion is broken up
into 3 groups, with threshold points at 341, 682, and 1023.
(1023/3 = 341)
(1 signifies slow / 2 signifies medium / 3 signifies fast)
*/ /* Interpret a2d value into slow/medium/fast speed */
if( a2dSpeed <= 341) // slow setting
userInputSpeed = 1;
else if( (a2dSpeed <= 682) && (a2dSpeed >= 342) ) // medium setting
userInputSpeed = 2;
else if ( (a2dSpeed <= 1023) && (a2dSpeed >= 683) ) // fast setting
userInputSpeed = 3;
else
userInputSpeed = -1; // signifies error w/ a2d conversion return userInputSpeed; /* return obtained value */

} /* end checkSpeed() */ /***************************************************
Function: checkDip()
Arguments: none
Return: int inputSum -> base ten digitized value of user's DIP switch
selection
I/O Pins Used: PORTC -> RC1, RC2, RC3, RC4

Description: checkDip() uses checks pins RC1 through RC4 for high or
low voltages.
Then, through a series of if statements, assigns a corrosponding base
10 value to inputSum and returns this number
****************************************************/
int checkDip( void )
{

/* (re)initialize variables to avoid potential troubles */
inputSum = 0; // final, digital, value of DIP switch, returned
to main() /* note that ports RC1 through RC4 are used */
/* Rc1 is connected to the least significant DIP switch */
/* Rc4 is connected to the most significant DIP switch */

if( PORTCbits.RC1 == 1) // ensure Rc1 (pin #16) is connected to
least significant bit ofDIP switch
inputSum = inputSum + 1;

if( PORTCbits.RC2 == 1) // ensure Rc2 (pin #17) is connected to 2nd
lowest bit of DIP switch
inputSum = inputSum + 2;

if( PORTCbits.RC3 == 1) // ensure Rc3 (pin #18) is connected to
3rd lowest bit of DIP switch
inputSum = inputSum + 4;

if( PORTCbits.RC4 == 1) // ensure Rc4 (pin #23) is connected to
4th lowest bit of DIP switch
inputSum = inputSum + 8; return inputSum; // return value

} /* end checkDip() function call */



Yahoo mail is coming slow again. I don't do C, but from what I can
see, I think your problem is the TRIS settings. Each bit of the port
is set with TRIS, not the entire port. Therefore setting TRISB = 1
sets bit 0 to input and bits 1-7 to outputs. If you want bits 1-4 as
inputs and the rest outputs the value would be b'00011110', 1Eh, or 30
decimal.

Good luck,
Chad
--- scubagreg7777777 <> wrote:

>
>
> Hi everyone,
>
> I'm pretty new to PICS, but will do my best to characterize my
> problem
> and provide as much pertinent info as possible. I perplexed as to
> what is going on with my PIC. I am using an 18f452 on a PICDEM 2
> Plus
> board, and my own PCB that I milled.
>
> Here is the problem:
>
> I have a 4-bit, high asserting DIP switch, with its input being sent
> to PORTC.RC1 through PORTC.RC4.
>
> Using an oscilliscope on the output I can observe that the switch is
> indeed workin, switching from ~0v to ~5v. However, as soon as I plug
> the PIC18F452 into the board, the DIP switch no longer responds
> (still
> viewing the output on a scope), and stays a flat ~0v, regardless of
> how the DIP is asserted. As soon as I pop the chip out, the switch
> is back to normal, and switches from 0v to 5v.
>
> Furthermore, If I touch a PORTC pin with a 5v connection, the
> software
> behaves how it should, and outputs on PORTD. It seems that the DIP
> switches simply stop working.
>
> I am using a 160ohm resistor, and there isn't too much else about my
> setup. I have been able to repeat this behaviour on both the PICDEM
> 2
> Plus board, and my own PCB. Below is a picture of my setup, and I
> have attached a copy of my code (using MCC18 compiled with MPLAB
> 6.4).
>
> I have switched out PICS, but not resistors (they're soldered in, and
> I do not have access to a soldering kit right now.
>
> What really baffles me, is that as soon as I put my chip in, the
> switch dies, and no longer works. If anyone has suggestions, PLEASE
> let me know.
>
> (also, as a bonus, if someone could explain why this is happening, I
> would be very interested in learning how to fix this problem, and why
> it happened)
>
> Thanks in advance,
>
> Greg > (DIP setup)
>
> 5v
> |
> |
> /
> \
> / (160 ohm resistor)
> \
> |
> |--------- output to PORTC
> |
>
> /
> / (switch)
> /
> |
> |
> |
> ----- (ground)
> -- >
>
> Code:
> --------
>
> /* Include Libraries */
> #include <p18f452.h> /* for TRISB and PORTB declarations */
> #include <adc.h> /* A/D library */
> #include <stdlib.h> /* Standard Library */ > /**********************************************/
> /* Function Prototypes */
>
> int checkSpeed( void );
> int checkDip( void ); > /***********************************************/
> /* Variable Declaration */
> /* */
>
> /* main() */
> int temp = 0; // temp variabe used in checkSpeed()
> int test = 0; // test variable used in main to determine if Ra1 is
> detecting high load (temp)
>
> int dipVal = 0; // value returned from checkDip() function
> call
> int speedVal = 0; // speed setting returned from checkSpeed()
> function call
> int onTime = 0; // max amount of time a particular channel/light
> can be turned on
> int offTime = 0; // amount of time a channel/light will be turned
> off
> int delayCounter = 0; // counter variable, useed in output
> display engine for on and off time
> int speedCounter = 1; // used in nested loop to get around max
> numeric value -- full explanation in dev notes
> int curOutput = 1; // current chanel being output > /* checkSpeed() */
> int a2dSpeed = 0 ; // value obtained from a2d conversion
> int userInputSpeed = 0; // speed setting, inferred from a2dSpeed
> value, returned to main
> // 1 = slow, 2 = medium, 3 = fast > /* checkDip() */
> int inputSum = 0; // final, base-10 value of user input via DIP > /* customLight() */ > /* delay() */
> int i = 0; // counter, used for delay loop
> int j = 1; // counter, used for number of loops -- speed control
>
> void main( void )
> {
>
> /* Initialize Configuration */
> TRISA = 1; // configs PORTA for INPUT -- used for checkSpeed()
> TRISC = 1; // configs PORTC for INPUT -- used for checkDip()
> TRISD = 0; // configs PORTD for OUTPUT -- used for light output >
> /* configure A/D convertors */
> /* detailled explanation is located at: p 16-18 in
> MPLAB-C18-Libraries.pdf */
> /* ADC_FOSC_32 -> a/d clock source uses FOSC/32
> ADC_RIGHT_JUST -> result in least significant bits
> ADC_8ANA_0REF -> VREF+ = Vdd and VREF- = Vss (both analog)
> ADC_CH# -> the channel being used
> ADC_INT_OFF -> disable interrupts */
>
> /* ADC_CH0 -> speed */
> OpenADC( ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_8ANA_0REF,ADC_CH0 &
> ADC_INT_OFF ); /* checkSpeed() */ > /* main program */
> while(1)
> {
>
> /* (re)initialize values */
> speedVal = 0;
> dipVal = 0; > /* obtain user input */
> dipVal = checkDip(); // determine DIP setting >
>
> if(dipVal == 0)
> PORTD = 0;
>
> if(dipVal == 1)
> {
> PORTD = 1;
> while(speedVal < 24000) speedVal++;
> while(speedVal > 3) speedVal--;
> PORTD = 0;
> }
>
> if(dipVal == 2)
> {
> PORTD = 1;
> while(speedVal < 24000) speedVal++;
> while(speedVal > 3) speedVal--;
> PORTD = 0;
> while(speedVal < 24000) speedVal++;
> while(speedVal > 3) speedVal--;
> PORTD = 1;
> while(speedVal < 24000) speedVal++;
> while(speedVal > 3) speedVal--;
> PORTD = 0;
> }
>
> if(dipVal == 3)
> {
>
=== message truncated === =====
My software has no bugs, only undocumented features.
__________________________________