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 */ |
|
PIC18F452, chip interfering with DIP switch
Started by ●December 4, 2004
Reply by ●December 4, 20042004-12-04
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. __________________________________ |