Searching \ for '[PIC:] My first program, 18F452, please critique' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/devices.htm?key=18F
Search entire site for: 'My first program, 18F452, please critique'.

Exact match. Not showing close matches.
PICList Thread
'[PIC:] My first program, 18F452, please critique'
2004\03\10@081605 by David Bearrow

picon face
This is a conglomerate of many different examples I read on the PIClist
website (there are no 18FXXX examples that I could see so I had to convert
the code, it was a good learning experience) and what I could glean from
the datasheet. All it does is depending on whether I switch RB4 of port B
between VCC and VSS (through 1k resister) it will run the appropriate
routine. I'm looking for constructive criticism. (the timing part is not
accurate, but it delays enough to work). It compiles and runs perfectly.



;-----------------------------------------------------------------------;
; ROT&CNT.ASM   Switch between rotating and counting on LEDs (RD0-RD7)  ;
;-----------------------------------------------------------------------;
        LIST P=PIC18F452
        INCLUDE "p18f452.inc"
        __CONFIG    _CONFIG1H, _OSCS_OFF_1H & _XT_OSC_1H
                __CONFIG    _CONFIG2L, _BOR_ON_2L & _BORV_20_2L & _PWRT_ON_2L
                __CONFIG    _CONFIG2H, _WDT_OFF_2H & _WDTPS_128_2H
                __CONFIG    _CONFIG3H, _CCP2MX_ON_3H
                __CONFIG    _CONFIG4L, _STVR_ON_4L & _LVP_OFF_4L &
_DEBUG_OFF_4L
                __CONFIG    _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L &
_CP2_OFF_5L & _CP3_OFF_5L
                __CONFIG    _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H
                __CONFIG    _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L &
_WRT2_OFF_6L & _WRT3_OFF_6L
                __CONFIG    _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H &
_WRTD_OFF_6H
                __CONFIG    _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L &
_EBTR2_OFF_7L & _EBTR3_OFF_7L
                __CONFIG    _CONFIG7H, _EBTRB_OFF_7H

                CBLOCK 0x020
                        CNT1
                        CNT2

                ENDC

                goto begin
                ORG 0x008                       ;interupt vector

                movlw B'11111111'
                MOVWF TMR0L             ;load timer0 with 255 so as to get
a 16us delay
                BCF INTCON, TMR0IF      ;clear timer overflow interupt
flag
                RETFIE                  ;return from interupt

begin:
                 ORG 0x010              ; start a program memory location zero

                CLRF PORTD                              ;clear tristate
buffer
                movlw B'00000000'
                MOVWF TRISA                     ;set up all bits of PORT A
as outputs
                MOVWF TRISC                     ;set up all bits of PORT C
as outputs
                MOVWF TRISD                     ;set up all bits of PORT D
as outputs
                MOVWF TRISE                     ;set up all bits of PORT E
as outputs
                 movlw B'00010000'       ; RB4 input, all other output (my
switch)
                MOVWF TRISB
                movlw B'01000001'
                MOVWF T0CON                     ;set timer0 as 8 bit,
internal clk, prescale 1:4
                movlw B'11111111'
                MOVWF TMR0L                     ;load timer0 with 255 so
as to get a 16us delay
                                                                ;Delay =
(256 - TMR0 * prescaler)
                                                ;-----------------------------------------
                                                        ;          Clock
Frequency / 4

                BSF INTCON, GIE                 ;enable interupts
                BSF INTCON, TMR0IE              ;enable timer 0 overflow
interupt
                movlw B'00000001'
                MOVWF PORTD

;-----------------------------------------------------------------------;
;                      This is the main program                         ;
;-----------------------------------------------------------------------;

loop:
                 btfsc PORTB, RB4     ; check rb4
                goto ROTATE         ; rb4 = 1
                goto BINCNT         ; rb4 = 0
ROTATE:
                 Rrncf PORTD, 1        ; rotate right port D
                CALL Delay
                 goto loop
BINCNT:
                INCF PORTD, 1      ; add 1 to port D
                CALL Delay
                 goto loop

Delay:
                MOVLW B'11111111'
                MOVWF CNT2
DELAY2:
                MOVLW B'11110100'
                MOVWF CNT1
                DECFSZ CNT2
                GOTO DELAY1
                GOTO FINISH
DELAY1:
                BSF T0CON, TMR0ON          ;start timer0
                DECFSZ CNT1
                GOTO DELAY1
                GOTO DELAY2
FINISH:
                return


        end                          ; end of program

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email spam_OUTlistservTakeThisOuTspammitvma.mit.edu with SET PICList DIGEST in the body

2004\03\10@174342 by Jinx

face picon face
This is a clip from a similar current (working) project that also has
a short ISR at the bottom of code space

        org     0x00000
        goto    init

        org     0x00018
        goto    isr

        org     0x00020

isr      bcf     pir1,tmr1if   ;clear flag
        incf    t2_count      ;bump counter
        movlw   .36
        xorwf   t2_count,w    ;test for limit
        skpz                  ;yes
        retfie                ;no
        bcf     intcon,gie
        bsf     timeout
        bra     done_2s       ;2-second timeout completed

init     clrf    intcon
        bsf     intcon,int0ie ;enable INTB0

You should also be using some context saving in your ISR (my
program calls the ISR on specific occassions and context saving
isn't necessary)

BUT....... I'm not sure why you have that ISR - it doesn't actually do
anything constructive. In fact it may trash the value in W that a delay
loop was using. I presume you thought it would be part of the delay
process, but you have the loops for that. In my example, I do use the
timer to create a delay by incrementing a counter

Have the timer or the loops, not both, it'll just make a sticky mess

> DELAY1:
>                  BSF T0CON, TMR0ON          ;start timer0
>                  DECFSZ CNT1
>                  GOTO DELAY1

Here you need to TMR0ON just once (can be anywhere outside
the loop)

> ROTATE:
>                   Rrncf PORTD, 1        ; rotate right port D
>                  CALL Delay
>                   goto loop
> BINCNT:
>                  INCF PORTD, 1      ; add 1 to port D
>                  CALL Delay
>                   goto loop

In general I prefer to use a shadow register when doing this
sort of thing with port pins. You should read up on read-modify-
write and LATD to see why direct manipulation of multiple pins
of the same port can cause problems

rotate   rrncf   d_shadow
        movf    d_shadow,w
        movwf   portd
        call  delay
        bra    loop

bincnt   incf    d_shadow
        movf    d_shadow,w
        movwf   portd
        call    delay
        bra     loop

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email .....listservKILLspamspam@spam@mitvma.mit.edu with SET PICList DIGEST in the body

2004\03\10@182004 by Jinx

face picon face
PS, here's some info on read-modify-write

http://www.piclist.com/techref/readmodwrite.htm

and the problem as seen on a Scenix SX18 at 50MIPS

http://home.clear.net.nz/pages/joecolquitt/sx_pins2.html

The SX was simply too fast for the external hardware and
pin changes needed slowing down. Note where the pin
voltages don't follow the code and where they do

setb=set bit=bsf
clrb=clear bit=bcf
jmp=goto or bra
mov=movff

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email listservspamKILLspammitvma.mit.edu with SET PICList DIGEST in the body

2004\03\10@194441 by David Bearrow

picon face
At 04:44 PM 3/10/04, you wrote:
>BUT....... I'm not sure why you have that ISR - it doesn't actually do
>anything constructive. In fact it may trash the value in W that a delay

I was determined to understand interrupts and included it in my delay as a
lesson to myself. Gonna go for an accurate 1 second delay next.

{Quote hidden}

OK, thanks for the advice.

{Quote hidden}

I will look it up.

Dave

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email .....listservKILLspamspam.....mitvma.mit.edu with SET PICList DIGEST in the body

2004\03\10@201216 by David Bearrow

picon face
At 05:20 PM 3/10/04, you wrote:
>PS, here's some info on read-modify-write
>
>http://www.piclist.com/techref/readmodwrite.htm
>
>and the problem as seen on a Scenix SX18 at 50MIPS
>
>http://home.clear.net.nz/pages/joecolquitt/sx_pins2.html
>
>The SX was simply too fast for the external hardware and
>pin changes needed slowing down. Note where the pin
>voltages don't follow the code and where they do
>
>setb=set bit=bsf
>clrb=clear bit=bcf
>jmp=goto or bra
>mov=movff

It doesn't get any clearer than those scope results. If I manipulate LATD
instead of PORTD is it possible to get the same problems?

Dave

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email EraseMElistservspam_OUTspamTakeThisOuTmitvma.mit.edu with SET PICList DIGEST in the body

2004\03\10@202428 by Jinx

face picon face
> I was determined to understand interrupts and included it in my
> delay as a lesson to myself

That's a good idea, but I think it got muddled up with the loops
that were also there for delay purposes

> Gonna go for an accurate 1 second delay next

That should be quite easy to do. Especially using a hex value
crystal with a timer. A hex value crystal is one that can be
divided by 16 or 256 for example (like 3.2768 or 19.6608). In
that case you can just let the timer free-run (with or without a pre-
scaler) and count rollovers (ie when its IF gets set). For decimal
crystals like 4MHz or 10MHz, it's a little different as the timer
needs to be reloaded (preferably by adding to) on rollover

http://www.piclist.com/techref/microchip/time.htm

Choice of crystal kind of depends on what you want to do, and
if perhaps some function has a high priority for accuracy. For
instance, a couple of general examples, a 4MHz crystal will give
you an accurate 1us instruction time. An 18.432MHz makes for
an accurate RS232 baud rate

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email listservspamspam_OUTmitvma.mit.edu with SET PICList DIGEST in the body

2004\03\10@213521 by Jinx

face picon face
> It doesn't get any clearer than those scope results. If I
> manipulate LATD instead of PORTD is it possible to get the
> same problems ?

The relationship between PORT TRIS and LAT can take a little
getting to grips with. This is how I understand it, although I have to
admit not really getting involved with LAT much. If anyone has
anything to add or correct, please do

=============

The last value written to PORT is in LAT. eg LATD holds the
contents that are to be written out if a pin is configured as an
output

But, a read of PORT (which may be caused by a read-modify-
write instruction) over-writes what is in LAT. This can be trouble
if PORT is a mix of inputs and outputs, because PORT writes to
LAT (see below)

When a pin is configured as an input and PORT is read, the
corresponding bit in PORT is the state of the external pin. The
PORT register writes to the LAT register

So, if four pins on Port D are inputs and four are outputs and you
want one of the output pins to go high, then you'd set the bit high
in the PORTD register. So far so good

However, now the PIC reads PORTD (as part of the r-m-w process),
which in effect reads the value of the four input pins and the value out
of LATD for the four output pins and then modifies the bit and writes
this back to PORTD

This data is then put into the LATD register. If the four input pins had
highs on their inputs then there will be five set bits in the LATD register
instead of the intended one. This may be important if any of those i/p
pins are changed at  later time to o/p. Instead of a 0 for that pin in LAT,
there could be a 1. You may have expected a 0 to be in LAT because
of a previous operation like CLRF PORTD

Bottom line is that there is the possibility of problems if you assume
the state of LAT, most definitely when changing the state of TRIS. You
should keep track of what your s/w may do inadvertently to pins. For
s/w that doesn't change TRIS after initialisation, it's probably nothing
to worry about

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email @spam@listservKILLspamspammitvma.mit.edu with SET PICList DIGEST in the body

2004\03\11@024223 by Jan-Erik Soderholm

face picon face
Hi.
This is my view on the LAT/PORT/TRIS issue.
Probably more or less the same thing, but in
slightly different wording.


{Quote hidden}

Actualy, a read of PORT *always* reads the state of the external
pin no matter how TRIS is configured.
The question is *how* the pin is driven.

When configured as an input, the pin is (mainly) driven by an
external source. I say mainly, becuse you have to
take things like passive pullups (internal source) into account.

When configured as an output, the pin is (mainly) driven by
the value in LAT. I say mainly since you have take
things like capacitive loads (potential timing/race issues) into
account. And the pin could be shorted to Vdd or Vcc, of course.

Still, a read from PORT always reads the level of the
physical/external pin no matter how TRIS is configured.

> PORT register writes to the LAT register

And on the 18-series a write to the PORT and a write to LAT
is actualy the same thing. A read from those regs are not
the same thing.

So read-modify-write instructions using LAT (instead of PORT)
should be safe (or *are* safe according to the data sheets).

> Bottom line is that there is the possibility of problems if you assume
> the state of LAT, most definitely when changing the state of TRIS. You
> should keep track of what your s/w may do inadvertently to pins. For
> s/w that doesn't change TRIS after initialisation, it's
> probably nothing to worry about

Besides of the timing/race issues with capcitive loads. Isn't that
maybe the main issue with r-m-w instructions anyway ?

Best Regards
Jan-Erik.

--
http://www.piclist.com hint: To leave the PICList
KILLspampiclist-unsubscribe-requestKILLspamspammitvma.mit.edu

2004\03\11@031204 by hael Rigby-Jones

picon face
{Quote hidden}

This is not quite correct.  All writes to a port must by definition go to
the data latch (LATx), even if you are actually writing to PORTx i.e.
although you can read the pin states via PORTx you always change their state
through LATx.  The big problem comes from writing to PORTx, whereby the pins
are read, the value modified and then written back to the data latch.

The older parts did not have to capability to read the data latches
directly, only the output pins which as many people have discovered isn't
always the same thing.  With the introduction of the LATx SFR's, R-M-W
problems on the ports are pretty much a thing of the past.  You can set or
clear a bit in the LATx register, safe in the knowledge that no other bits
will be affected, even if their associated pins are configured as inputs.

The general rule to using ports on an 18F part is to write to LATx and read
from PORTx.  This way the values written to the data latch can be relied on
to stay the way they are, even if TRISx is being manipulated.

The LATx SFR's are probably one of the most useful additions to the 18F
series of devices if bit bashing is your thing.

Regards

Mike





=======================================================================
This e-mail is intended for the person it is addressed to only. The
information contained in it may be confidential and/or protected by
law. If you are not the intended recipient of this message, you must
not make any use of this information, or copy or show it to any
person. Please contact us immediately to tell us that you have
received this e-mail, and return the original to us. Any use,
forwarding, printing or copying of this message is strictly prohibited.
No part of this message can be considered a request for goods or
services.
=======================================================================
Any questions about Bookham's E-Mail service should be directed to
TakeThisOuTpostmasterEraseMEspamspam_OUTbookham.com.

--
http://www.piclist.com hint: To leave the PICList
RemoveMEpiclist-unsubscribe-requestspamTakeThisOuTmitvma.mit.edu

2004\03\11@032449 by Jinx

face picon face
> > When a pin is configured as an input and PORT is read, the
> > corresponding bit in PORT is the state of the external pin.

> Actually, a read of PORT *always* reads the state of the external
> pin no matter how TRIS is configured

Yes, that's quite true. I'd been talking to David just previously
about r-m-w with outputs so I'd hoped he spotted the implication.
The answer was starting to get convoluted and wordy (and I was
using the dreaded fuzzy monitor) so I left it

> So read-modify-write instructions using LAT (instead of PORT)
> should be safe (or *are* safe according to the data sheets).

The text in, for example, DS39564B (18FXX2 d/s) is a little
simplistic

"The data latch (LAT register) is useful for read-modify-write
operations on the value the that the I/O pins are driving"

which is a bit tough on a newbie without background knowledge

> > should keep track of what your s/w may do inadvertently to pins

> Besides of the timing/race issues with capacitive loads. Isn't
> that maybe the main issue with r-m-w instructions anyway ?

Oh, absolutely. Something as simple as the insertion of a NOP
or two can make all the difference, even when not considering
LAT. You really need to tailor the s/w to suit the h/w it's interfaced
to, especially with very short instruction times

--
http://www.piclist.com hint: To leave the PICList
piclist-unsubscribe-requestEraseMEspam.....mitvma.mit.edu

2004\03\11@041335 by Jinx

face picon face
> >The last value written to PORT is in LAT. eg LATD holds the
> >contents that are to be written out if a pin is configured as an
> >output
>
> This is not quite correct. All writes to a port must by definition go
> to the data latch (LATx), even if you are actually writing to PORTx
> i.e. although you can read the pin states via PORTx you always
> change their state through LATx. The big problem comes from
> writing to PORTx, whereby the pins are read, the value modified
> and then written back to the data latch

Isn't that what I (hoped to have) said ? I tried to differentiate
between i/p and o/p and driving and reading

"The last value written to PORT is in LAT. eg LATD holds the
contents that are to be written out if a pin is configured as an
output"    <- here I was assuming an all-output port

"But, a read of PORT (which may be caused by a read-modify-
write instruction) over-writes what is in LAT. This can be trouble
if PORT is a mix of inputs and outputs, because PORT writes to
LAT"

That would have been better written without the parentheses. IOW
writing to PORT is a r-m-w action

We need a picture with some examples ;-)

--
http://www.piclist.com hint: To leave the PICList
EraseMEpiclist-unsubscribe-requestspammitvma.mit.edu

2004\03\11@043901 by hael Rigby-Jones

picon face
{Quote hidden}

Very probably.  My only excuse is it was my birthday yesterday and my dad
came around in the evening with a bottle of 15 year old malt.  Would have
been rude not to sample it and I am now suffering slightly...

>"The last value written to PORT is in LAT. eg LATD holds the
>contents that are to be written out if a pin is configured as an
>output"    <- here I was assuming an all-output port
>
>"But, a read of PORT (which may be caused by a read-modify-
>write instruction) over-writes what is in LAT. This can be
>trouble if PORT is a mix of inputs and outputs, because PORT
>writes to LAT"

I read this as "by reading a PORT, you are corrupting the contents of the
LAT register".  I think I was confused by "over-writes", over-rides would
perhaps be clearer?

Regards

Mike




=======================================================================
This e-mail is intended for the person it is addressed to only. The
information contained in it may be confidential and/or protected by
law. If you are not the intended recipient of this message, you must
not make any use of this information, or copy or show it to any
person. Please contact us immediately to tell us that you have
received this e-mail, and return the original to us. Any use,
forwarding, printing or copying of this message is strictly prohibited.
No part of this message can be considered a request for goods or
services.
=======================================================================
Any questions about Bookham's E-Mail service should be directed to
RemoveMEpostmasterTakeThisOuTspamspambookham.com.

--
http://www.piclist.com hint: To leave the PICList
EraseMEpiclist-unsubscribe-requestspamspamspamBeGonemitvma.mit.edu

2004\03\11@044110 by Jan-Erik Soderholm

face picon face
Jinx wrote :

> "The last value written to PORT is in LAT. eg LATD holds the
> contents that are to be written out if a pin is configured as an
> output"    <- here I was assuming an all-output port

But it's correct even on non-all-output port, isn't it ?

> "But, a read of PORT (which may be caused by a read-modify-
> write instruction) over-writes what is in LAT...

Ahem, it's the *write-back* to PORT that might over-write
LAT, not the *read* as such (as in a "MOVF PORTx, W").

If you take out the "which may be...", like in :

> "But, a read of PORT (caused by a read-modify-write instruction!)
>  over-writes what is in LAT (in the write-back phase)...

then it's a bit clearer, IMHO.

> That would have been better written without the parentheses. IOW
> writing to PORT is a r-m-w action

Not *all* writes (as in e.g. a "MOVWF PORTx" instruction), is it ?

Interesting topic ! :-)
Jan-Erik.

--
http://www.piclist.com hint: To leave the PICList
RemoveMEpiclist-unsubscribe-requestKILLspamspammitvma.mit.edu

2004\03\11@045601 by Jinx

face picon face
> Interesting topic ! :-)

It is, it is. But text doesn't seem to be making it clear. I'll
have a look at putting a diagram together that shows
what will happen to PORT and LAT in various situations

--
http://www.piclist.com hint: To leave the PICList
piclist-unsubscribe-requestSTOPspamspamspam_OUTmitvma.mit.edu

2004\03\11@075540 by David Bearrow

picon face
At 03:57 AM 3/11/04, you wrote:
> > Interesting topic ! :-)
>
>It is, it is. But text doesn't seem to be making it clear. I'll
>have a look at putting a diagram together that shows
>what will happen to PORT and LAT in various situations

The datasheet for the PIC18FXX2 says: The Data Latch Register (LATx) is
also memory mapped. Read-Write-Modify operations on the LATx register reads
and writes the latched output value for PORTx.

It sure would have been nice of Microchip to have put in a footnote
explaining the details that you folks brought up. That statement in the
datasheet isn't very informative. After I read it I experimented with LATx
and at the slow speeds I was running with the LED blink program I didn't
see any difference between LATx and PORTx.

But let me see if I understand you guys correctly, its better to only do
reads from PORTx and if I want to write or do a Read-Modify-Write then work
with LATx and no shadow register is nescesary on PICs with LATx.

Dave

--
http://www.piclist.com hint: To leave the PICList
spamBeGonepiclist-unsubscribe-requestSTOPspamspamEraseMEmitvma.mit.edu

2004\03\11@090510 by Jan-Erik Soderholm

face picon face
David Bearrow wrote :

> But let me see if I understand you guys correctly, its better
> to only do reads from PORTx and if I want to write or do a
> Read-Modify-Write then work with LATx and no shadow
> register is nescesary on PICs with LATx.
>
> Dave

Hi.
We have two basic scenarios here.

The first is when we, for any reason, have to fiddle
with the TRIS bits during runtime, that is, changing
a pin from input to output (not the other way around).
(This is not that common, usualy pins stays as input *or*
output.)
Anyway, in this case it's "just" to make sure
that you set the LATx to whatever they should be before
switching the pin from input to output. If you have a
application where you changes the TRIS bits during runtime,
you have probably already thought of this...

The other case, is when an output pin isn't at the
level set by LATx. Let's take an example. You have two
output pins, pin1 and pin2. You'd like to set/clear each of them
using the BCF/BSF instructions. One of the pins
is loaded with some capacitance (doesn't have to
be much at high speed ! A few 100's of pF maybe).
Now, lets say both pins are cleared (0V) and you'd
like to set both high. One way would be to :

 BSF  PORTx, pin1
 BSF  PORTx, pin2

Now let's what happens here.

The first BSF reads all *8* bits from PORTx, sets pin1,
and re-writes all *8* bits to PORTx (or rather LATx).
So far everyting is just fine...

The second BSF again reads all *8* bits from PORTx,
sets pin2, and re-writes all *8* bits to PORTx (or rather LATx).

Now the problem is that between this two instruction, due
to the capacitive load, the pin1 have not had time to reach
a logical "high" level before the read phase of the second BSF.
So a logical "low" will be read, and also re-written to LATx,
effectivily canceling out the first BSF. That is the r-m-w
problem.

Solutions :

On *any* PIC :
1. Use a shadow register. Or
2. Use a delay between the two BSF's, so the external
capacitive load have had time to charge up in between.

On 18-series PICs :
1 and 2 as above and
3. Use LATx instead of PORTx for bit handling instructions.

Note that this is a dynamic (race condition) problem.
A prototype running at a slower speed can work just fine, but
not when tested at a higher speed.

Does it make any sense ?

Jan-Erik.

--
http://www.piclist.com hint: To leave the PICList
KILLspampiclist-unsubscribe-requestspamBeGonespammitvma.mit.edu

2004\03\11@201654 by Carey Fisher - NCS

face picon face
>Solutions :

>On *any* PIC :
>1. Use a shadow register. Or
>2. Use a delay between the two BSF's, so the external
>capacitive load have had time to charge up in between.

>On 18-series PICs :
>1 and 2 as above and
>3. Use LATx instead of PORTx for bit handling instructions.

>Note that this is a dynamic (race condition) problem.
>A prototype running at a slower speed can work just fine, but
>not when tested at a higher speed.

>Does it make any sense ?

>Jan-Erik.


I've read this thread, other threads, articles posted in various places
including piclist.com & Microchip.com and I've read and re-read the data
sheet for the 18F452.  Here's my conclusion and please tell me if it's
wrong:

If you always read from PORTx and always write to LATx, you won't get bit by
the Read-Modify-Write situation.

Right?

Carey Fisher

--
http://www.piclist.com hint: To leave the PICList
EraseMEpiclist-unsubscribe-requestspamEraseMEmitvma.mit.edu

2004\03\11@214122 by David Bearrow

picon face
At 08:03 AM 3/11/04, you wrote:
>Solutions :
>
>On *any* PIC :
>1. Use a shadow register. Or
>2. Use a delay between the two BSF's, so the external
>capacitive load have had time to charge up in between.
>
>On 18-series PICs :
>1 and 2 as above and
>3. Use LATx instead of PORTx for bit handling instructions.
>
>Note that this is a dynamic (race condition) problem.
>A prototype running at a slower speed can work just fine, but
>not when tested at a higher speed.
>
>Does it make any sense ?

Yes, its very clear now. Thank you.


I think to be safe I will always use a shadow register.

Dave

--
http://www.piclist.com hint: To leave the PICList
@spam@piclist-unsubscribe-request@spam@spamspam_OUTmitvma.mit.edu

2004\03\12@031341 by Jan-Erik Soderholm

face picon face
Carey Fisher - NCS

> If you always read from PORTx and always write to LATx, you
> won't get bit by the Read-Modify-Write situation.
> Right?

Well, yes, but note that some instructions
both reads and write to the same FSR in the same
instruction, like BCF/BSF. If you concider those
as "write-only" instructions, then yes. :-)

And, you still might have the case of capacitive loading
on (output) pins that makes the READ from PORTx reading
the wrong state (that is, not what's in LATx). If you
have this rece condition, you might still need the
shadow register to hold a "copy" of your output status.

Jan-Erik.

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads

2004\03\12@034738 by hael Rigby-Jones

picon face
>
>Carey Fisher - NCS
>
>> If you always read from PORTx and always write to LATx, you
>won't get
>> bit by the Read-Modify-Write situation. Right?
>
>Well, yes, but note that some instructions
>both reads and write to the same FSR in the same
>instruction, like BCF/BSF. If you concider those
>as "write-only" instructions, then yes. :-)

>{Original Message removed}

2004\03\12@054234 by Howard Winter

face
flavicon
picon face
David,

Just a few style points if you don't mind (I spotted that your Interrupt routine doesn't do anything -
including affecting the delays, but it's already been mentioned by someone else).

You don't set the origin at the start of the program - the compiler will assume zero I'm sure, but it's
probably best to put in  ORG 0x000  anyway to make sure, and to make it quicker to spot the actual start of
the program.

You start out well with comments describing what's going on, and this is excellent:

   MOVWF TMR0L      ;load timer0 with 255 so as to get a 16us delay
                    ;Delay = (256 - TMR0 * prescaler)
                    ;-----------------------------------------
                    ;          Clock Frequency / 4

but you seem to have got bored with that by the time you got to the Main Loop:

   MOVLW B'11110100'
   MOVWF CNT1

so I (and perhaps you!) can't see what you're doing there.  I think this is another timing value, but how
long?

You use Binary for all your literals, which in some cases is appropriate, but in others it would be easier if
you'd used hex or decimal, for example:

    movlw B'00010000'       ; RB4 input, all other output (my switch)
    MOVWF TRISB

is right because you're dealing with bits and you can easily see which one is set, but:

    MOVLW B'11110100'
    MOVWF CNT1

is hard to read because it's representing a number (of counter-ticks, I presume) and expressing it in decimal
would make it easier to understand - try decreasing it by 5, and you'll see what I mean!  :-)

In this section:

    btfsc PORTB, RB4     ; check rb4
    goto ROTATE         ; rb4 = 1
    goto BINCNT         ; rb4 = 0
ROTATE:

You could have saved an instruction by flipping the test:

    btfss PORTB, RB4    ; check rb4
    goto BINCNT         ; rb4 = 0
ROTATE:                 ; rb4 = 1

now there may be occasions where you don't want this, for example if you want to keep the same number of
cycles in each path, but I don't think that's an issue here.

You are very inconsistent in your use of case, with this being the best example:

    Rrncf PORTD, 1        ; rotate right port D
    CALL Delay
    goto loop

where you've used Proper, UPPER, and lower case for the instructions and parameters all in three lines :-)
Please pick a style and stick to it - it's much faster to read when it's all the same.  My own "Standard" is
to use UPPER case for the instructions and special registers like ports, and Proper case for labels and my own
variables, so this is how I would have written it:

   RRNCF PORTD, 1        ; Rotate Right Port D
   CALL Delay
   GOTO Loop

But this is very personal and could well start a flame war!  :-)  My point is not that you should do it my
way, but to pick a style and stick with it.

Please don't take any of this as personal criticism - I'm trying to help you write more readable programs, and
(as I used to tell people in my team) almost all programs have much more time spent reading than writing them,
so saving a few keystrokes as you're writing will cost you, or someone else, much more later.  (I can just
hear my former colleagues groaning:  "He's not STILL banging on about that, is he?" :-)

Cheers,

Howard Winter
St.Albans, England

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads

2004\03\12@080829 by David Bearrow

picon face
At 04:41 AM 3/12/04, you wrote:
>but you seem to have got bored with that by the time you got to the Main Loop:
>
>     MOVLW B'11110100'
>     MOVWF CNT1
>
>so I (and perhaps you!) can't see what you're doing there.  I think this
>is another timing value, but how
>long?

The 2 delay sections were an inexact attempt to force the interrupt to
occur CNT1 * CNT2. I had set timer0 to 255 so it would force the interrupt
after 1 tick which I had calculated to .000016 seconds. So I thought I
needed to force the interrupt 62500 times to get approximately a second. So
I created 2 nested counters. CNT1 loaded with 244 and CNT2 loaded with 256.
It didn't turn out as exact as I thought it would be but it worked ok, it
runs a little bit faster than 1 second. I have been shown a better way now,
to start the timer at 0 and count the rollovers.

{Quote hidden}

I keep the windows calculator open while programming (it has a great
hex/dec/oct/bin converter) but I see your point and will take your advice.


{Quote hidden}

This was the result of copying and pasting 5 different code examples from
the PIClist archives and combining them. There are an amazing number of
styles. In the future I will examine more closely my style.

>Please don't take any of this as personal criticism - I'm trying to help
>you write more readable programs, and
>(as I used to tell people in my team) almost all programs have much more
>time spent reading than writing them,
>so saving a few keystrokes as you're writing will cost you, or someone
>else, much more later.  (I can just
>hear my former colleagues groaning:  "He's not STILL banging on about
>that, is he?" :-)


These are the types of comments I was looking for. It will help me to
improve my skills and start me off on the right foot. Thank you very much
for your time.

David Bearrow
Dallas, TX, USA

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads

2004\03\12@084654 by Carey Fisher - NCS

face picon face
>Carey Fisher - NCS

>> If you always read from PORTx and always write to LATx, you
>> won't get bit by the Read-Modify-Write situation.
>> Right?

>Well, yes, but note that some instructions
>both reads and write to the same FSR in the same
>instruction, like BCF/BSF. If you concider those
>as "write-only" instructions, then yes. :-)

>And, you still might have the case of capacitive loading
>on (output) pins that makes the READ from PORTx reading
>the wrong state (that is, not what's in LATx). If you
>have this rece condition, you might still need the
>shadow register to hold a "copy" of your output status.

>Jan-Erik.

But, generally, in fact most of the time, if I'm reading PORTx I don't care
what's in LATx since I'm using the port as an input, no?
Carey

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads

More... (looser matching)
- Last day of these posts
- In 2004 , 2005 only
- Today
- New search...