View previous topic :: View next topic |
Author |
Message |
Zezem
Joined: 02 Mar 2017 Posts: 7
|
Problems with SFRs |
Posted: Wed Jan 30, 2019 10:13 am |
|
|
My code compiles fine but if I do things like:
PORTB = 0xFF;
or
PORTC = 0x15;
the ports don't actually change. This worked with an old compiler v4.128 but when I use v5.065 I get all sorts of problems
code has been simplified as much as possible...
PIC18F2620
sf_regs.h
Code: |
#ifndef SF_REGS_H
#define SF_REGS_H
/* register files */
#BYTE PORTA = 0xF80
#BYTE PORTB = 0xF81
#BYTE PORTC = 0xF82
#BYTE LATA = 0xF89
#BYTE LATB = 0xF8A
#BYTE LATC = 0xF8B
#BYTE TRISA = 0xF92
#BYTE TRISB = 0xF93
#BYTE TRISC = 0xF94
#BYTE PIE1 = 0xF9D
#BYTE PIR1 = 0xF9E
#BYTE IPR1 = 0xF9F
#BYTE PIE2 = 0xFA0
#BYTE PIR2 = 0xFA1
#BYTE IPR2 = 0xFA2
#BYTE EECON1 = 0xFA6
#BYTE EECON2 = 0xFA7
#BYTE EEDATA = 0xFA8
#BYTE EEADR = 0xFA9
#BYTE RCSTA = 0xFAB
#BYTE TXSTA = 0xFAC
#BYTE TXREG = 0xFAD
#BYTE RCREG = 0xFAE
#BYTE SPBRG = 0xFAF
#BYTE T3CON = 0xFB1
#BYTE TMR3L = 0xFB2
#BYTE TMR3H = 0xFB3
#BYTE CCP2CON = 0xFBA
#BYTE CCPR2L = 0xFBB
#BYTE CCPR2H = 0xFBC
#BYTE CCP1CON = 0xFBD
#BYTE CCPR1L = 0xFBE
#BYTE CCPR1H = 0xFBF
#BYTE ADCON1 = 0xFC1
#BYTE ADCON0 = 0xFC2
#BYTE ADRESL = 0xFC3
#BYTE ADRESH = 0xFC4
#BYTE SSPCON2 = 0xFC5
#BYTE SSPCON1 = 0xFC6
#BYTE SSPSTAT = 0xFC7
#BYTE SSPADD = 0xFC8
#BYTE SSPBUF = 0xFC9
#BYTE T2CON = 0xFCA
#BYTE PR2 = 0xFCB
#BYTE TMR2 = 0xFCC
#BYTE T1CON = 0xFCD
#BYTE TMR1L = 0xFCE
#BYTE TMR1H = 0xFCF
#BYTE RCON = 0xFD0
#BYTE WDTCON = 0xFD1
#BYTE LVDCON = 0xFD2
#BYTE OSCCON = 0xFD3
#BYTE T0CON = 0xFD5
#BYTE TMR0L = 0xFD6
#BYTE TMR0H = 0xFD7
#BYTE STATUS = 0xFD8
#BYTE FSR2L = 0xFD9
#BYTE FSR2H = 0XFDA
#BYTE PLUSW2 = 0xFDB
#BYTE PREINC2 = 0xFDC
#BYTE POSTDEC2 = 0xFDD
#BYTE POSTINC2 = 0xFDE
#BYTE INDF2 = 0xFDF
#BYTE BSR = 0xFE0
#BYTE FSR1L = 0xFE1
#BYTE FSR1H = 0xFE2
#BYTE PLUSW1 = 0xFE3
#BYTE PREINC1 = 0xFE4
#BYTE POSTDEC1 = 0xFE5
#BYTE POSTINC1 = 0xFE6
#BYTE INDF1 = 0xFE7
#BYTE WREG = 0xFE8
#BYTE FSR0L = 0xFE9
#BYTE FSR0H = 0xFEA
#BYTE PLUSW0 = 0xFEB
#BYTE PREINC0 = 0xFEC
#BYTE POSTDEC0 = 0xFED
#BYTE POSTINC0 = 0xFEE
#BYTE INDF0 = 0xFEF
#BYTE INTCON3 = 0xFF0
#BYTE INTCON2 = 0xFF1
#BYTE INTCON1 = 0xFF2
#BYTE INTCON = 0xFF2
#BYTE PRODL = 0xFF3
#BYTE PRODH = 0xFF4
#BYTE TABLAT = 0xFF5
#BYTE TBLPTRL = 0xFF6
#BYTE TBLPTRH = 0xFF7
#BYTE TBLPTRU = 0xFF8
#BYTE PCL = 0xFF9
#BYTE PCLATH = 0xFFA
#BYTE PCLATU = 0xFFB
#BYTE STKPTR = 0xFFC
#BYTE TOSL = 0xFFD
#BYTE TOSH = 0xFFE
#BYTE TOSU = 0xFFF
/* port bit definitions */
#bit PA0 = PORTA.0 // PIN 2
#bit ENT = PORTA.1 // PIN 3
#bit UP = PORTA.2 // PIN 4
#bit PA3 = PORTA.3 // PIN 5
#bit DN = PORTA.4 // PIN 6
#bit INHIBIT = PORTA.5 // PIN 7
#bit PB0 = PORTB.0 // PIN 21
#bit PB1 = PORTB.1 // PIN 22
#bit PB2 = PORTB.2 // PIN 23
#bit PB3 = PORTB.3 // PIN 24
#bit PB4 = PORTB.4 // PIN 25
#bit PB5 = PORTB.5 // PIN 26
#bit PB6 = PORTB.6 // PIN 27
#bit PB7 = PORTB.7 // PIN 28
#bit A0 = PORTC.0 // PIN 11
#bit PWM_1 = PORTC.1 // PIN 12
#bit CS1 = PORTC.2 // PIN 13
#bit SCL = PORTC.3 // PIN 14
#bit SDA = PORTC.4 // PIN 15
#bit DSP_NOTALK = PORTC.5 // PIN 16
#bit DSP_NOALERT= PORTC.6 // PIN 17
#bit CS2 = PORTC.7 // PIN 18
#bit ALERT_TRIS = TRISC.6 //PIN 17
/* MSSP module */
// SSPSTAT (Read only)
#bit BF = SSPSTAT.0
#bit UA = SSPSTAT.1
#bit R_W = SSPSTAT.2
#bit S = SSPSTAT.3
#bit P = SSPSTAT.4
#bit D_A = SSPSTAT.5
// SSPCON1 (Read or Write)
#bit SSPM0 = SSPCON1.0
#bit SSPM1 = SSPCON1.1
#bit SSPM2 = SSPCON1.2
#bit SSPM3 = SSPCON1.3
#bit CKP = SSPCON1.4
#bit SSPEN = SSPCON1.5
#bit SSPOV = SSPCON1.6
#bit WCOL = SSPCON1.7
// SSPCON2 (Read or Write)
#bit SEN = SSPCON2.0
#bit RSEN = SSPCON2.1
#bit PEN = SSPCON2.2
#bit RCEN = SSPCON2.3
#bit ACKEN = SSPCON2.4
#bit ACKDT = SSPCON2.5
#bit ACKSTAT = SSPCON2.6
#bit GCEN = SSPCON2.7
// PIR1 (Peripheral Interrupt Request)
#bit SSPIF = PIR1.3
// PIE1 (Peripheral Interrupt Enable)
#bit SSPIE = PIE1.3
#endif /* SF_REGS_H */
|
main.c
Code: |
#include "sf_regs.h"
#include "defines.h"
#include "lcd.c"
#use delay(clock=4000000) // 4MHz crystal
#use i2c(slave, scl=PIN_C3, sda=PIN_C4, address=0x4A, FORCE_HW)
#include "FaultCodes.h"
#include "DisplayProcessor_Declarations.h"
#include "PersistDataFunctions.c"
int8 counter = 0;
void main()
{
PORTB = counter;
delay_ms(1000);
counter++;
}
|
|
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 480 Location: Montenegro
|
|
Posted: Wed Jan 30, 2019 10:24 am |
|
|
Maybe like this:
output_b (value)
Regards,
Samo |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jan 30, 2019 10:24 am |
|
|
The PIC comes up from power-on-reset as all input pins. If you're going
to do direct i/o, you need to set the TRIS to be outputs on PortB. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Wed Jan 30, 2019 10:32 am |
|
|
also top 2 bit of port B are for ICSP, so be sure to properly isolate them.
1st line in program has to be processor #include.... missing in post.
Jay |
|
|
gaugeguy
Joined: 05 Apr 2011 Posts: 303
|
|
Posted: Wed Jan 30, 2019 10:36 am |
|
|
output_b () is definitely the preferred way.
If you want to use direct register access you need to read the PIC data sheet to understand why you should use LATB instead of PORTB in addition to setting TRISB. |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Wed Jan 30, 2019 10:37 am |
|
|
The compiler's default behaviour is to automatically set the tris for you, but I think that only happens if you use the built-in functions such as output_b(). By directly writing to the PORTB register, the compiler might not be automatically setting the tris for you.
The old compiler version might have been doing so, and that may be why it worked on the older compiler, but a newer version obviously no longer functions the same way.
Another thing that might be playing a role in what you're seeing is that the old way of directly accessing SFRs is as you have shown in your post:
Code: | #byte PORTB = 0xf81 |
This requires you having to look up SFR addresses yourself from the processor's data sheet. The compiler now offers a new method whereby you don't have to look up the SFR addresses yourself: getenv
Code: | #byte PORTB = getenv("SFR:PORTB") |
I'm wondering if you change your PORTB assignment to use the getenv method, will your code start to work? Will the compiler recognize that you want to write to the port and automatically set the tris for you? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Wed Jan 30, 2019 12:10 pm |
|
|
All have been said, but i'll put them into one post:
No, the 'old compiler' would not have set tris.
You need to set this.
You should always 'write' to LATB, not PORTB. The actual outpuit latch is
LATB, and the chips are _meant_ to automatically write to LATB, if you
write to PORTB, but it is now documented for quite a few chips, that this
does not always work. So write to LATB instead.
Generally as a comment, as has already been said, used names, rather
than looking the ports up yourself:
#byte LATB=getenv("SFR:LATB")
Further as a comment, and again has already been said, simply use
the compiler's output_b function. Generally you should only use register
names in the very few cases where you absolutely must bypass the
compiler's normal operation. 99.9% of CCS code will never use even
one register access. The output_b function will correctly write to
LATB which is probably why it works. If you want access with your
own control of TRIS, then use fast_io. |
|
|
|