Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] PIC18F25K22 Can't seem to set all PORTA, PORTB and PORTC to all digital I/O outputs

Status
Not open for further replies.

Hoffman

Newbie level 3
Joined
Jun 19, 2015
Messages
3
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
94
NOTE: TMR1 is working correctly and blinking the LEDs it is supposed to.
I seem to have tried without success to initialize all pins of PORTA, PORTB, PORTC, to be just I/O pins set for only input-output mode.

In this program, every PORTB pin seems to blink properly except for PORTB.0 PORTB.1 and PORTB.6.

PORTB.0 INT0IE is working as INT0 , PORTB.1 lights on reset but then doesn't blink flash.
PORTB.6 will turn off a visible fraction of a second after it and PORTB.7 are both turned off by code?
So, obviously some mysterious MCU operation has hijacked control of bbit1 an bbit6!
*/

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
//----------------------
 // Target: PIC18F45K22 Hi-Tech 9.80 or  XC8 v1.34 compiler compatible code
 // #include <xc.h>  //only for XC compiler, using Hi-Tech
 // PIC configuration words
#include <htc.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <P18f25k22.h>
#include <stdint.h>
 
__PROG_CONFIG(1,0x8800); //Internal Osc Block at 16MHz,IES0 enabled-
//#pragma config FOSC   = INTIO67 wks with XC not 9.80
#pragma config FCMEN    = OFF
#pragma config IESO     = ON  //originally set to off
#pragma config BOREN    = OFF
#pragma config WDTEN    = OFF
#pragma config WDTPS    = 1024
#pragma config PBADEN   = OFF //PORTB is I/O at reset not A2D
#pragma config HFOFST   = ON
#pragma config LVP      = OFF
#pragma config STVREN   = ON
#pragma config XINST    = OFF
#pragma config PWRTEN   = OFF
#pragma config BORV     = 190
#pragma config MCLRE    = EXTMCLR
#pragma config CCP2MX   = PORTC1
#pragma config CCP3MX   = PORTB5
#pragma config T3CMX    = PORTC0
#pragma config P2BMX    = PORTD2
#pragma config PLLCFG   = OFF
#pragma config PRICLKEN = OFF
               //Bit   7      6          5        4       <3:0>
               //    IESO   FCMEM     PRICLKEN  PLLCFG    OSC SELECT
               // Int-Ext   FailSafe            no effect 0010 Xtal
               // ClkSwEn   Clock Mon           HFINTOSC  1000 INTHFOSC
               //    1=En   0=off       0=Dis      x      1000
               //OSCCON SCS=0 else no 64MHz PLL operation
/*
__PROG_CONFIG(1,0x8800); //Internal Osc Block at 16MHz,IES0 enabled-
__PROG_CONFIG(2,0x0);    //BOREN and WDTEN both disabled
__PROG_CONFIG(3,0xBD00); //PBADEN disabled PORTB<5:0>are I/O not A2d at reset
__PROG_CONFIG(4,0x81);   //bit3 =0 LVP disabled   default =0x85
*/
__PROG_CONFIG(5,0xC00F); //CONFIG5 to CONFIG7 just set Read and Write protects
__PROG_CONFIG(6,0xE00F); //All mem reads and writes are enabled, no protect
__PROG_CONFIG(7,0x400F); //Default BulkErase settings for CONFIG4--CONFIG7
 
 
#pragma config IESO=1;   //Needs to be=1 for SCS to work to set clk source
#pragma config PBADEN=0;             
#pragma config WDTEN=0;  //WatchDog Enable Disabled   0003=0x3F ater erase
 
#define Off           0
#define OFF           0
#define off           0
#define On            1
#define ON            1
#define on            1
#define None          0
                               //Break the ports down to their bits
#define PB(port,bit)  ((unsigned) & (port)*8 + (bit))
static bit abit0 @ PB(PORTA,0);
static bit abit1 @ PB(PORTA,1);
static bit abit2 @ PB(PORTA,2);
static bit abit3 @ PB(PORTA,3);
static bit abit4 @ PB(PORTA,4);
static bit abit5 @ PB(PORTA,5);
static bit abit6 @ PB(PORTA,6);
static bit abit7 @ PB(PORTA,7);
 
static bit bbit0 @ PB(PORTB,0);
static bit bbit1 @ PB(PORTB,1);
static bit bbit2 @ PB(PORTB,2);
static bit bbit3 @ PB(PORTB,3);
static bit bbit4 @ PB(PORTB,4);
static bit bbit5 @ PB(PORTB,5);
static bit bbit6 @ PB(PORTB,6);
static bit bbit7 @ PB(PORTB,7);
 
static bit cbit0 @ PB(PORTC,0);
static bit cbit1 @ PB(PORTC,1);
static bit cbit2 @ PB(PORTC,2);
static bit cbit3 @ PB(PORTC,3);
static bit cbit4 @ PB(PORTC,4);
static bit cbit5 @ PB(PORTC,5);
static bit cbit6 @ PB(PORTC,6);
static bit cbit7 @ PB(PORTC,7);
 
static double        ttemp=0;
 
 
void interrupt high_priority(void)
{
  if (INT0IF)
   { INT0IF = 0;
     bbit3=1;
     bbit4=0;
   }
  if (TMR1IF) //at 64MHz approx 18.5mSec with H=0x80 L=0
   {   TMR1ON = 0;
       TMR1IF = 0;
       TMR1H = 0x80;
       TMR1L = 0x0;
       TMR1ON = 1;
       if(bbit2==0)
        { bbit2=1;
        }
       else bbit2=0;
   }
}
 
void interrupt low_priority lp(void)
{
     INT0IF=0;
     bbit3=0;
     bbit4=1;
 
  if (TMR1IF) //at 64MHz takes 37mSec for rollover with H=0,L=0
   {
       TMR1ON = 0;
       TMR1IF = 0;
       TMR1H  = 0x0;
       TMR1L  = 0x0;
       TMR1ON = 1;
       if(bbit2==0)
        { bbit2=1;
        }
       else bbit2=0;
   }
}// end of Low priority interrupt
 
#define _XTAL_FREQ 64000000L
#define FCYC (_XTAL_FREQ/4L)
 
void Init_TIMER1( void )
{ // TIMER1 overflows at 65536 clocks
  T1CON  = 0;  // stop TIMER1
  TMR1IE = 0;  // disable TIMER1 interrupt for now
  T1GCON = 0;  // disable TIMER1 gate input
  TMR1H  = 0;  // set TIMER1 initial count value
  TMR1L  = 0;
  //TICON settings TICKPS,TMR1CS don't work with 9.80
  //TMR1ON  =TICON<0>=0 TMR1ON=off
  //T1RD16  =TICON<1>=0 do not set TMR1 H,L with one 16bit word
  //T1SYNC  =TICON<2>=0 sync external clock input with system clock
  //                    T1SYNC=0 was setting in SETINT
  //TISOSCEN=TICON<3>=0 Dedicated 2ndary Osc disabled
  //TMR1CKPS=TICON<5:4>=0x10 1/4 prescaler of system clock
  //TMR1CS  =TICON<7:6>=0x01 TMR1 uses system clock,0x00=sysclk/4 instructClk
  T1CON  = 0b0110100;
   
  TMR1IP = 1;    // select high priority interrupt level //
  TMR1IF = 0;    // clear TIMER1 interrupt request //
  TMR1IE = 1;    // enable TIMER1 interrupt //
  PEIE   = 1;    // enable peripheral interrupts //
  TMR1ON = 1;    // start TIMER1 //
}
 
void Init_PIC( void )
{
    INTCON = 0;     // disable interrupts //
    INTCON2 = 0xF5;
    INTCON3 = 0xC0;
    PIE1 = 0;
    PIE2 = 0;
    PIE3 = 0;
    OSCTUNE=0x1F; //Highest Internal OSC Freq OSCTUNE<0:5> set freq.
                  //OSCTUNE<5:0>set freq 011111 =16MHz PLLEN=bit6
    // Turn on the PLL //
                  //OSCTUNEbits.PLLEN = 1; //also works 9.80
    PLLEN=1; //if=1 Fosc=Fosc*4
    //OSCCON =0x70; //Selects Int Osc Block 16Mhz internal clock source
    //OSCCON bit7 IDLEN=0 Enter Sleep,=1 Enter Idle
    //OSCCON<1:0> SCS..SCS=1x IntSysClk, 01=SecOsc SOSC,00=Clk set by CONFIG1
    OSCCON = 0b01110000; // Enter Sleep mode for sleep, not IDLE
                         // set internal oscillator to 16MHz,
                         // use primary clock set by CONFIG1H<3:0>
 
    // disable ADC inputs //
    ANSELA = 0;
    ANSELB = 0;
    ANSELC = 0;
    ANSELD = 0;
    ANSELE = 0;
   
    // disable Comparators //
    CM1CON0 = 0;
    CM2CON0 = 0;
 
    // make all available GPIOs outputs and set low //
    LATA  = 0x00;
    TRISA = 0x00; // originally RA6,RA7 as inputs //
    LATB  = 0x01;
    TRISB = 0x01; //INT0 Sw on bbit0
    LATC  = 0x00;
    TRISC = 0x00; // originally  RC0,RC1 as inputs //
    LATD  = 0x00;
    TRISD = 0x00;
    LATE  = 0x00;
    TRISE = TRISE & ~0x07; // touch only PORTE direction bits //
}
//------------------------------main-----------------------------------------
 
void main(void)
{
  Init_PIC();
  Init_TIMER1();
  IPEN   = 1; //Priority interrupts enabled
              //RCONbits.IPEN = 1; //also works 9.80
  LATB  =1;
  TRISB =1;   //INT0IE sw on bbit0
  INT0IF=0;
  INT0IE=1;
  PEIE=1;     //Needed for TMRx interrupts
  PIE1=1;     //Not Needed for TMRx
  PIE2=1;     //Not Needed for TMRx
  GIEL=1;
  GIEH=1; //Ok to use INTCONbits.GIE = 1; to enable all interrupts     
 
//===================================================================
  Start:
  for(ttemp=0;ttemp<60000;ttemp++)//a few secs, timed loop at 16MHz *4
   { INT0IE=1;
 
     bbit1 =1;
                //bbit2 blinks
     bbit5 =1;
     bbit6 =1;
     bbit7 =1;
     TMR1IP=1;
   }
  for(ttemp=0;ttemp<60000;ttemp++) //a few seconds at 16MHz *4
   {
     INT0IE=0;
 
     bbit1 =0;
 
     bbit5 =0;
     bbit6 =0;
     bbit7 =0;
     TMR1IP=0;
   }
  goto Start;
}

 
Last edited by a moderator:

If you cannot toggle the port bits, then simplify your program significantly, down to the port initialisations for one port (say PORTA) and then in your main loop (which should be a 'while(1)' or similar loop - don't use goto's!) just toggle the LATA bits and check with a scope that they are going up and down.
Once you get that working, then add back in the rest of your code.
By the way, you need tho check that pins are not being used for another purpose, especially while you are debugging. For example for PORTB B6 and B7 are used for the programmer/debugger so they will not be available while you are debugging.
I don't understand why you are making such a job out of setting the config bits by using 2 completely different techniques. Just use the #pragma statements. With using different approach you could well be setting conflicting settings.
Why are you using 3 different defines for different capitalisations of "on" and"off"! If you must use this technique, then choopse one and use it throughout!
Susan
 

In this program, every PORTB pin seems to blink properly except for PORTB.0 PORTB.1 and PORTB.6.

Code:
// make all available GPIOs outputs and set low //
LATA  = 0x00;
TRISA = 0x00; // originally RA6,RA7 as inputs //
LATB  = 0x01;
TRISB = 0x01; //INT0 Sw on bbit0
Code:
LATB  =1;
TRISB =1;   //INT0IE sw on bbit0
INT0IF=0;
INT0IE=1;

In the code you have set TRISB to 1 at two places and hence PORTB.0 is input pin and can't work as Output pin for LED.
 

You can't set TRSID, LATD, PORTD and ANSELD because your chip doesn't have that port. Is your timer code correct ? Is your config bits related to FOSC correct ?

You have to configure FOSC for HSPLL as you are using 16MHz with 4xPLL. Have you done that. Later after configuring FOSC you have used

Code:
#pragma config PLLCFG = OFF

Without PLL you won't get 16 MHz x 4 = 64 MHz. It seems you have calculated Timer Interrupt value based on 64 MHz clock.
 
Last edited:

Thanks to everyone for your help. I have found the problem: attempting to write to outputs directly instead of using LATCx. With use of LATCx everything works fine.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top