View previous topic :: View next topic |
Author |
Message |
FCP
Joined: 19 May 2010 Posts: 13
|
Port D as Input problem |
Posted: Wed May 19, 2010 6:30 pm |
|
|
Hi,
I need help seting up the port D as an input for a PIC18F44J11. I have configure the port with the following code:
Code: |
#use FAST_IO(D)
#byte PORTD = 0xf83
set_tris_d(ALL_IN);
port_d_pullups(TRUE);
|
it compiles without any trouble, but when I try to read the port I do not get the value that setup in the pins.
Thank you. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed May 19, 2010 6:59 pm |
|
|
1. How are you setting up the value on the pins ? What external circuits
provide the values ? What are the voltage levels on the pins ?
2. How are you testing this ? How do you know it fails ?
3. Post a short but complete test program (that is compilable)
that demonstrates the problem.
4. Is this a Proteus project ? Or is done on a hardware board ?
5. What is your CCS compiler version ? |
|
|
FCP
Joined: 19 May 2010 Posts: 13
|
|
Posted: Thu May 20, 2010 8:18 am |
|
|
Quote: | 1. How are you setting up the value on the pins ? What external circuits
provide the values ? What are the voltage levels on the pins ? |
It has a 8 bit DIP switch connected to the port, one side to ground and the other to the port pins, no other hardware.
Quote: | 2. How are you testing this ? How do you know it fails ? |
I have tested several options, but the most conclusive ones are a) checking the contents of the PORTD and LATD register with the debugger (PCWH compiler from CCS), b) comparing the value of the read and branching to a different location if it matches (the circuit has two different LED's that light according to the branch.
Quote: | 3. Post a short but complete test program (that is compilable)
that demonstrates the problem. |
#include "18f44j11.h"
#FUSES HS, WDT, PROTECT, DSBOR, WDT2048
#ZERO_RAM
#use DELAY(CLOCK=7372800)
#use FAST_IO(A)
#use FAST_IO(B)
#use FAST_IO(C)
#use FAST_IO(D)
#byte PORTA = 0xf80 // Port addresses
#byte PORTB = 0xf81
#byte PORTC = 0xf82
#byte PORTD = 0xf83
#define ALL_OUT 0x00
#define ALL_IN 0xff
#define COMM_LED PIN_A0
#define CTB_LED PIN_A1
#define DATA PIN_B0
#define CLOCK PIN_B1
#define UPDATE PIN_B2
#define CLEAR PIN_B3
#define MODE PIN_B4
#define SENSE PIN_B5
void main(void) {
unsigned int8 address;
int i ;
setup_port_a(NO_ANALOGS); //no analog inputs
set_tris_a(ALL_OUT); //all outputs
set_tris_b(0x60); //XERR input; rest outputs
set_tris_c(0x84); //RX, TARGET inputs; rest outputs
set_tris_d(ALL_IN);
port_d_pullups(TRUE);
output_low(CTB_LED);
output_low(COMM_LED);
output_low(DATA);
output_low(CLOCK);
output_low(UPDATE);
output_low(MODE);
address = ~PORTD;
if(address > 0x7f) {
output_high(CTB_LED);
}
else {
output_high(COMM_LED);
}
}
Quote: | 4. Is this a Proteus project ? Or is done on a hardware board ? |
It is a hardware board, and other than not reading port D, everything else is working.
Quote: | 5. What is your CCS compiler version ? |
4.107 |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Thu May 20, 2010 8:45 am |
|
|
Your problem (other than not using code tags) may well be that as soon as you have read the port and turned on the output the pic goes to sleep and turns it off again
address = ~PORTD;
if(address > 0x7f) {
output_high(CTB_LED);
}
else {
output_high(COMM_LED);
}
Put
while(true);
at the end to stop it from going to sleep.
better still, encase the main routine around a loop
Code: |
while(true)
{
address = ~PORTD;
if(address > 0x7f) {
output_high(CTB_LED);
output_low(COMM_LED);
}
else {
output_lowCTB_LED);
output_high(COMM_LED);
}
}
|
|
|
|
FCP
Joined: 19 May 2010 Posts: 13
|
|
Posted: Thu May 20, 2010 9:24 am |
|
|
I made the follwing changes to the code, but the result was still the same, Not able to read port D.
Code: | #include "18f44j11.h" // CPU definitions, must be followed by...
//#device *=16 // ...enable 16-bit (!) data pointers
#FUSES HS, WDT, PROTECT, DSBOR, WDT2048 // PIC fuse settings
#ZERO_RAM // Wipe RAM for safety
#use DELAY(CLOCK=7372800) // CPU clock frequency 7.3728 MHz
/****************************************************************************/
/* IO configuration */
/****************************************************************************/
#use FAST_IO(A)
#use FAST_IO(B)
#use FAST_IO(C)
#use FAST_IO(D)
/****************************************************************************/
/* Port definitions */
/****************************************************************************/
#byte PORTA = 0xf80 // Port addresses
#byte PORTB = 0xf81
#byte PORTC = 0xf82
#byte PORTD = 0xf83
#byte RPOR6 = 0xecc // Peripheral pin selection (CLEAR)
#define ALL_OUT 0x00 // All output TRIS value
#define ALL_IN 0xff // All input TRIS value
#define COMM_LED PIN_A0
#define CTB_LED PIN_A1
#define DATA PIN_B0
#define CLOCK PIN_B1
#define UPDATE PIN_B2
#define CLEAR PIN_B3
#define MODE PIN_B4
#define SENSE PIN_B5
/****************************************************************************/
/* Data type definitions */
/****************************************************************************/
#define BOOL short
#define OFF 0
#define ON 1
/****************************************************************************/
/* Main program routine */
/****************************************************************************/
void main(void) {
unsigned int8 address;
int i;
setup_port_a(NO_ANALOGS); //no analog inputs
set_tris_a(ALL_OUT); //all outputs
set_tris_b(0x60); //XERR input; rest outputs
set_tris_c(0x84); //RX, TARGET inputs; rest outputs
set_tris_d(ALL_IN);
port_d_pullups(TRUE);
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_16, 255, 15);
RPOR6 = 14;
set_pwm1_duty(8);
output_low(CTB_LED); //switch off the controller timer bit LED
output_low(COMM_LED); //switch off communication LED
output_low(DATA);
output_low(CLOCK);
output_low(UPDATE);
output_low(MODE);
while(TRUE) {
output_low(CTB_LED);
output_low(COMM_LED);
delay_ms(100);
address = ~PORTD;
if(address > 0x7f) {
output_high(CTB_LED);
delay_ms(100);
}
else {
output_high(COMM_LED);
delay_ms(100);
}
restart_wdt();
}
} |
Thank you. |
|
|
FCP
Joined: 19 May 2010 Posts: 13
|
|
Posted: Thu May 20, 2010 10:00 am |
|
|
BTW, I have five samples of the hardware and all behave the same way. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu May 20, 2010 2:47 pm |
|
|
Quote: |
5. What is your CCS compiler version ?
4.107
|
I tried to compile your latest code with vs. 4.107 and I get this error:
Quote: |
*** Error 12 "PCH_Test.c" Line 56(20,21): Undefined identifier -- port_d_pullups
|
So how can you test this program if it doesn't compile ? |
|
|
FCP
Joined: 19 May 2010 Posts: 13
|
|
Posted: Thu May 20, 2010 3:05 pm |
|
|
In the CCS compiler go to "Tools", "Device Editor", select PIC18F44J11 in the "MCU Part" list. Then go to "Other Features", and from the drop-down list of "Pullups" select B,D,E. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu May 20, 2010 3:21 pm |
|
|
I don't have that version of the compiler. I only have the command line
version.
Since you added this feature to the compiler, how do we know that it's
generating the correct ASM code to do it ?
Compile this little test program and post the .LST file code that it
generates. Make sure the .LST file is in "CCS format", so it shows
the numerical register addresses. Don't use "Symbolic" format.
Code: |
#include <18F44J11.h>
#Fuses HS, NOWDT, NOPROTECT
#use delay(clock=7372800)
#use FAST_IO(D)
#byte PORTD = 0xf83
#define ALL_IN 0xff
//============================
void main(void)
{
int8 address;
set_tris_d(ALL_IN);
port_d_pullups(TRUE);
address = ~PORTD;
while(1);
} |
|
|
|
FCP
Joined: 19 May 2010 Posts: 13
|
|
Posted: Thu May 20, 2010 3:50 pm |
|
|
Here it is:
Code: | CCS PCH C Compiler, Version 4.107, 52671 20-May-10 14:40
Filename: C:\FelixC\Projects\VMS Parking\Sensors\Ultrasonic\Wired\Port D Test2.lst
ROM used: 50 bytes (0%)
Largest free fragment is 16326
RAM used: 5 (0%) at main() level
5 (0%) worst case
Stack: 0 locations
*
0000: GOTO 0004
.................... #include "18f44j11.h" // CPU definitions, must be followed by...
.................... //////// Standard Header file for the PIC18F44J11 device ////////////////
.................... #device PIC18F44J11
.................... #list
....................
.................... #FUSES HS, NOWDT, NOPROTECT // PIC fuse settings
.................... #use DELAY(CLOCK=7372800) // CPU clock frequency 7.3728 MHz
....................
.................... #use FAST_IO(D)
....................
.................... #byte PORTD = 0xf83
....................
.................... #define ALL_IN 0xff // All input TRIS value
....................
.................... /****************************************************************************/
.................... /* Main program routine */
.................... /****************************************************************************/
.................... void main(void) {
0004: CLRF FF8
0006: BCF FD0.7
0008: CLRF FEA
000A: CLRF FE9
000C: MOVLW FF
000E: MOVLB F
0010: MOVWF x48
0012: BCF FC2.6
0014: BCF FC2.7
0016: MOVF x49,W
0018: ANDLW E0
001A: IORLW 1F
001C: MOVWF x49
001E: CLRF FD2
0020: CLRF FD1
.................... unsigned int8 address;
....................
.................... set_tris_d(ALL_IN);
0022: MOVLW FF
0024: MOVWF F95
.................... port_d_pullups(TRUE);
0026: BSF F86.7
.................... address = ~PORTD;
0028: MOVFF F83,05
002C: COMF 05,F
....................
.................... while(1);
002E: BRA 002E
.................... }
0030: SLEEP
Configuration Fuses:
Word 1: F4A0 NODEBUG NOXINST STVREN NOWDT NOPROTECT CPUDIV6
Word 2: FFDC HS WDT32768 FCMEN IESO PRIMARY NOLPT1OSC T1DIG
Word 3: F9FF IOL1WAY MSSPMSK7 DSWDT2147483648 DSWDT DSBOR RTCOSC_T1 DSWDTOSC_INT
Word 4: F1CF NOWPCFG WPBEG WPDIS WPFP |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu May 20, 2010 4:01 pm |
|
|
Quote: | .................... port_d_pullups(TRUE);
0026: BSF F86.7
|
As I suspected, this address is incorrect. The RDPU pull-up bit is in the
PortE register, and it's address is 0xF84. The compiler is using the wrong
register address.
To fix this problem, go back into the Device Editor and undo the changes
that you did. Disable PortD pullups. Then add the lines shown in bold
below to your program. Now the port_d_pullups() function will work.
Quote: |
#include <18F44J11.h>
#Fuses HS, NOWDT, NOPROTECT
#use delay(clock=7372800)
#use FAST_IO(D)
#byte PORTD = 0xf83
#define ALL_IN 0xff
#byte PORTE = 0xF84
#bit RDPU = PORTE.7
#define port_d_pullups(x) RDPU=x
//============================
void main(void)
{
int8 address;
set_tris_d(ALL_IN);
port_d_pullups(TRUE);
address = ~PORTD;
} |
|
|
|
FCP
Joined: 19 May 2010 Posts: 13
|
|
Posted: Thu May 20, 2010 4:17 pm |
|
|
Now is working, thank you PCM programmer.
I hope CCS is monitoring the forum and will fix the entry for the corresponding IC. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu May 20, 2010 4:21 pm |
|
|
Quote: | I hope CCS is monitoring the forum |
They don't. You can write a detailed email report to them.
1. Tell them the PIC, 18F44J11 and your compiler version.
2. Explain how you had to add port_d_pullups() using the Device Editor,
when it should be already supported.
3. Explain how when you did add it, the compiler used the wrong register
address.
If you don't want to email them, let me know and I'll do it. |
|
|
FCP
Joined: 19 May 2010 Posts: 13
|
|
Posted: Thu May 20, 2010 4:23 pm |
|
|
I will send them an e-mail, and once again, thank you. |
|
|
|