A discussion group for the PICMicro microcontroller. Also called the Microchip PIC, this list is dedicated to the use and abuse of this fine, simple, microcontroller. Close to topic posts are welcome, ie. general electronics.
16F870 byte swapping - Mark Adams - Jan 8 17:23:00 2006
Hello, I am working on a project where my PIC sends its analog input data
out the serial port. The code copies the High and Low analog result
registers to variables I defined like this. Analog1_H EQU 0x30 Analog1_L EQU
0x32 and so on for each of the five analog ports. When all of the analog
data has been saved it is sent out the serial port like this:
MOVF analog0_H,0 ;Copy low byte AD to W register
MOVWF TXREG ;Move data to transmit register
This repeats for each variable (word?) 10 times total.
On the receiving end of the serial cable the data seems like there is some
kind of shifting going on. what happens is the data for analog1 is seen in
word 1 and 3, for analog2 its in word 3 and 5, analog3 is in word 5 and 7,
analog4 is in word 7 and 9 and analog5 is in words 9 and 1. words 0,2,4,6
and 8 have no data.
If I substitute literal data instead of the variables I can receive the data
as I would expect.
MOVLW 0x01
MOVWF TXREG
MOVLW 0x02
MOVWF TXREG
MOVLW 0x03
MOVWF TXREG
Bla bla bla.....
Doing this I can receive the data values 1 through 10 in order.
I have used some commercial software that would let you access memory on the
word and byte level. So writing data to memory location 3 would write over
one byte of memory location 2. It seems like something of this nature is
happening and I am having trouble finding the information on how memory is
accessed.
How does the pic define and use its memory, what is a byte and a word and
how big is a memory location?
Thanks
Mark

(You need to be a member of piclist -- send a blank email to piclist-subscribe@yahoogroups.com )
Re: 16F870 byte swapping - rtstofer - Jan 8 18:08:00 2006
I think you should be testing TXIF between bytes. You aren't
waiting for the tranmit holding register to be empty.
Richard
--- In piclist@picl..., "Mark Adams" <markadams1971@y...>
wrote:
>
> Hello, I am working on a project where my PIC sends its analog
input data
> out the serial port. The code copies the High and Low analog result
> registers to variables I defined like this. Analog1_H EQU 0x30
Analog1_L EQU
> 0x32 and so on for each of the five analog ports. When all of the
analog
> data has been saved it is sent out the serial port like this:
>
> MOVF analog0_H,0 ;Copy low byte AD to W register
> MOVWF TXREG ;Move data to transmit register
>
> This repeats for each variable (word?) 10 times total.
>
> On the receiving end of the serial cable the data seems like there
is some
> kind of shifting going on. what happens is the data for analog1 is
seen in
> word 1 and 3, for analog2 its in word 3 and 5, analog3 is in word
5 and 7,
> analog4 is in word 7 and 9 and analog5 is in words 9 and 1. words
0,2,4,6
> and 8 have no data.
> If I substitute literal data instead of the variables I can
receive the data
> as I would expect.
>
> MOVLW 0x01
> MOVWF TXREG
> MOVLW 0x02
> MOVWF TXREG
> MOVLW 0x03
> MOVWF TXREG
> Bla bla bla.....
>
> Doing this I can receive the data values 1 through 10 in order.
>
> I have used some commercial software that would let you access
memory on the
> word and byte level. So writing data to memory location 3 would
write over
> one byte of memory location 2. It seems like something of this
nature is
> happening and I am having trouble finding the information on how
memory is
> accessed.
>
> How does the pic define and use its memory, what is a byte and a
word and
> how big is a memory location?
>
> Thanks
> Mark

(You need to be a member of piclist -- send a blank email to piclist-subscribe@yahoogroups.com )
RE: Re: 16F870 byte swapping - Mark Adams - Jan 8 18:20:00 2006
I am not using transmit interrupts. Instead I check the
following flag.
wait BTFSC TXSTA,
TRMT ;Check Transmit reg is empty
GOTO wait ;Loop until reg is
empty
Thanks
Mark
I think you should be
testing TXIF between bytes. You aren't
waiting for the tranmit holding
register to be empty.
Richard
--- In p...@yahoogroups.com, "Mark
Adams" <markadams1971@y...>
wrote:
>
> Hello, I am working on
a project where my PIC sends its analog
input data
> out the serial port.
The code copies the High and Low analog result
> registers to variables I defined
like this. Analog1_H EQU 0x30
Analog1_L EQU
> 0x32 and so on for each of the
five analog ports. When all of the
analog
> data has been saved it is sent
out the serial port like this:
>
> MOVF
analog0_H,0 ;Copy low byte AD to W register
> MOVWF
TXREG ;Move data to transmit
register
>
> This repeats for each variable (word?) 10 times total.
>
> On the receiving end of the serial cable the data seems like there
is some
> kind of shifting going on. what happens is the data for analog1 is
seen in
> word 1 and 3, for analog2 its in word 3 and 5, analog3 is in word
5 and 7,
> analog4 is in word 7 and 9 and analog5 is in words 9 and 1. words
0,2,4,6
> and 8 have no data.
> If I substitute literal data instead of
the variables I can
receive the data
> as I would expect.
>
> MOVLW 0x01
> MOVWF TXREG
> MOVLW 0x02
> MOVWF TXREG
> MOVLW 0x03
> MOVWF TXREG
> Bla bla bla.....
>
>
Doing this I can receive the data values 1 through 10 in order.
>
> I
have used some commercial software that would let you access
memory on the
>
word and byte level. So writing data to memory location 3 would
write over
>
one byte of memory location 2. It seems like something of this
nature is
>
happening and I am having trouble finding the information on how
memory is
>
accessed.
>
> How does the pic define and use its memory, what is a byte
and a
word and
> how big is a memory location?
>
>
Thanks
> Mark

(You need to be a member of piclist -- send a blank email to piclist-subscribe@yahoogroups.com )
Re: 16F870 byte swapping - rtstofer - Jan 8 18:55:00 2006
Sorry, that wasn't shown in your code snippets. When you wait for
TRMT, you are losing speed because you are waiting for the data to
be shifted out rather than just until the transmit holding register
has been sent to the shift register.
You don't have to use interrupts to make use of TXIF. Just test it
instead of TXSTA.
But, that won't solve your problem. Maybe when you store byte size
registers it would be better to store them in byte sized variables.
As I see it, you have allowed two bytes for each byte of data:
Analog1_H EQU 0x30
Analog1_L EQU 0x32
It's always a toss up: post all relevant code and hide the forest
with trees or post too little code and lose context. I don't have
an answer for that problem either. I know that I won't look at code
over a couple of dozen lines because it takes too much time to
digest.
Richard
--- In piclist@picl..., "Mark Adams" <markadams1971@y...>
wrote:
>
> I am not using transmit interrupts. Instead I check the following
flag.
>
> wait BTFSC TXSTA, TRMT ;Check Transmit reg is empty
> GOTO wait ;Loop until reg is empty
> Thanks
> Mark
> -----Original Message-----
> From: piclist@picl... [mailto:piclist@picl...]On
Behalf Of
> rtstofer
> Sent: Sunday, January 08, 2006 5:09 PM
> To: piclist@picl...
> Subject: [piclist] Re: 16F870 byte swapping
>
> I think you should be testing TXIF between bytes. You aren't
> waiting for the tranmit holding register to be empty.
>
> Richard
>
> --- In piclist@picl..., "Mark Adams" <markadams1971@y...>
> wrote:
> >
> > Hello, I am working on a project where my PIC sends its analog
> input data
> > out the serial port. The code copies the High and Low analog
result
> > registers to variables I defined like this. Analog1_H EQU 0x30
> Analog1_L EQU
> > 0x32 and so on for each of the five analog ports. When all of
the
> analog
> > data has been saved it is sent out the serial port like this:
> >
> > MOVF analog0_H,0 ;Copy low byte AD to W register
> > MOVWF TXREG ;Move data to transmit register
> >
> > This repeats for each variable (word?) 10 times total.
> >
> > On the receiving end of the serial cable the data seems like
there
> is some
> > kind of shifting going on. what happens is the data for
analog1 is
> seen in
> > word 1 and 3, for analog2 its in word 3 and 5, analog3 is in
word
> 5 and 7,
> > analog4 is in word 7 and 9 and analog5 is in words 9 and 1.
words
> 0,2,4,6
> > and 8 have no data.
> > If I substitute literal data instead of the variables I can
> receive the data
> > as I would expect.
> >
> > MOVLW 0x01
> > MOVWF TXREG
> > MOVLW 0x02
> > MOVWF TXREG
> > MOVLW 0x03
> > MOVWF TXREG
> > Bla bla bla.....
> >
> > Doing this I can receive the data values 1 through 10 in order.
> >
> > I have used some commercial software that would let you access
> memory on the
> > word and byte level. So writing data to memory location 3 would
> write over
> > one byte of memory location 2. It seems like something of this
> nature is
> > happening and I am having trouble finding the information on
how
> memory is
> > accessed.
> >
> > How does the pic define and use its memory, what is a byte and
a
> word and
> > how big is a memory location?
> >
> > Thanks
> > Mark
>
>
> to unsubscribe, go to http://www.yahoogroups.com and follow the
> instructions
>
> -------------------------------------------------------------------
---------
> --
> YAHOO! GROUPS LINKS
>
> a..
> -------------------------------------------------------------------
---------
> --

(You need to be a member of piclist -- send a blank email to piclist-subscribe@yahoogroups.com )
RE: Re: 16F870 byte swapping - Mark Adams - Jan 8 19:54:00 2006
No apoligies necessay. This is my first PIC
project and am greatfull for any input. I agree about posting code, it looses its format
and becomes hard to read, for me anyway. I had a problem with sending data where I
had to do a couple of delays between charecters or the data was lost. I will try
testing the TXIF bit maby it will help with that problem. Here ia an actual snippet for
anyone who cares to look at it. This code started as a template from Microchip. I
will try to initalize the variables with data rather than the actual analog data and see
if it will transmit correctly that way.
Start
of program
list p=16f870 ; list directive to define processor
#include <p16f870.inc> ; processor specific variable
definitions
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF &
_PWRTE_ON & _RC_OSC & _WRT_ENABLE_ON & _LVP_ON & _CPD_OFF
;*****
VARIABLE DEFINITIONS
w_temp EQU 0x71 ; variable used for
context saving
status_temp EQU 0x72 ; variable used for context
saving
looplen EQU 0x22
looplen2 EQU 0x24
analog0_h EQU
0x30
analog0_l EQU 0x32
analog1_h EQU 0x34
analog1_l EQU
0x36
analog2_h EQU 0x38
analog2_l EQU 0x3A
analog3_h EQU
0x3C
analog3_l EQU 0x3E
analog4_h EQU 0x40
analog4_l EQU
0x42
;*******************************************************************
; This
program configures asynchronus communications and the "A" port as analog inputs
; The main loop does
nothing. Whenever serial data is recieved (the data is not used) the interrupt
;
routine calls the program to start the analog conversions and send the results
; out
the serial port. A led is turned on on port "B"
when the interrupt routine is started and off
; when the interrupt routine exits
;******************************************************************
org
0x000 ; processor reset vector
;******************************************************************
clrf
PCLATH ; ensure
page bits are cleared
goto
Start ; go
to beginning of program
;********************************************************************
ORG
0x004 ; interrupt
vector location
;********************************************************************
movwf
w_temp ; save off
current W register contents
movf STATUS,w ; move
status register into W register
movwf status_temp ; save off contents of
STATUS register
; isr code can go here or be located as a call subroutine
elsewhere
clrf STATUS ;Memory bank 0
BSF PORTB, 0x02 ;Turn on led Visual aid
bcf INTCON,GIE ;Disable interrupts
btfss PIR1,RCIF ;See if interrupt was caused by serial
receive
goto END_ISR ;Exit ISR if not
bcf PIR1, RCIF ;Clear interrupt flag
movf RCREG,w ;Copy recived data to W this made system
stable. Not using this data at this time.
call
An_Dig_con ;Call subroutine
call
XMITDAT ;Call subroutine
END_ISR
movf status_temp,w ; retrieve copy of
STATUS register
movwf STATUS
; restore pre-isr STATUS register contents
swapf w_temp,f
swapf w_temp,w ;
restore pre-isr W register contents
BCF PORTB, 0x02
;Turn off led Visual aid.
retfie
; return from interrupt
;******************END OF
ISR**********************************
;****************INITALIZE
REGISTERS****************************
Start
BCF STATUS, RP0
BCF STATUS, RP1 ;Bank0
CLRF PORTB ;Initialize
PORT by;clearing output;data latches
CLRF PORTA
BSF STATUS, RP0 ;Select Bank 1
MOVLW 0x00
MOVWF TRISB ;Set PortB as Outputs
MOVLW 0x02
MOVWF ADCON1 ;Configure all
PORTA pins as Anlog
BSF ADCON1, ADFM ;SET bit for data justification to
right.
BSF TXSTA, BRGH ; Set High Speed Baud for rate
generator
MOVLW 0x20
MOVWF
SPBRG ; 20 from chart Complete ref manual with 5.0688 MH crystal
BCF TXSTA, SYNC
BCF STATUS, RP0 ;Bank0
BSF ADCON0,
ADCS1 ;Select clock rate for conversions
BSF ADCON0, ADON ;Turn on AD
converter
BSF RCSTA, SPEN ;Enable serial port
BSF RCSTA,
CREN ;Enable continous reception
BSF STATUS, RP0 ;Select
Bank 1
BSF PIE1, RCIE ;Enable Serial Recive Interrupt
BSF TXSTA, TXEN ;Enable serial transmission
BCF STATUS,
RP0 ;Select Bank 0
BSF INTCON, GIE ;Enable Interrupts
BSF INTCON, PEIE ;Enable Interrupt
;******************MAIN LOOP, ISR
INITIATES AD CONVERSION AND SER COM.**
Main
; CALL An_Dig_con ;uncomment to step
through
GOTO Main
;*************SUBROUTINE***************************
An_Dig_con
BCF STATUS, RP0 ;Select Bank 0
BCF
ADCON0, CHS0
BCF ADCON0, CHS1
BCF ADCON0,
CHS2 ;Select analog port 0
BSF ADCON0,
GO_DONE ;Start the analog conversion
wait4 BTFSC ADCON0,
GO_DONE ;Wait for conversion to end
GOTO wait4
MOVF ADRESH,0 ;Copy high byte AD to W register
MOVWF analog0_h ;Move W register to Analog storage
location
BSF STATUS, RP0 ;Select Bank 1
MOVF ADRESL,0 ;Copy low byte AD to W register
BCF STATUS, RP0 ;Select Bank 0
MOVWF
analog0_l ;Move W register to Analog storage location
MOVLW 0x08
ADDWF ADCON0,1 ;Add 8 to
select next analog channel
BSF ADCON0, GO_DONE ;Start
the analog conversion
wait5 BTFSC ADCON0, GO_DONE ;Wait for
conversion to end
GOTO wait5
MOVF
ADRESH,0 ;Copy high byte AD to W register
MOVWF
analog1_h ;Move W register to Analog storage location
BSF STATUS, RP0 ;Select Bank 1
MOVF
ADRESL,0 ;Copy low byte AD to W register
BCF
STATUS, RP0 ;Select Bank 0
MOVWF
analog1_l ;Move W register to Analog storage location
MOVLW 0x08
ADDWF ADCON0,1 ;Add 8 to
select next analog channel
BSF ADCON0, GO_DONE ;Start
the analog conversion
wait6 BTFSC ADCON0, GO_DONE ;Wait for
conversion to end
GOTO wait6
MOVF
ADRESH,0 ;Copy high byte AD to W register
MOVWF
analog2_h ;Move W register to Analog storage location
BSF STATUS, RP0 ;Select Bank 1
MOVF
ADRESL,0 ;Copy low byte AD to W register
BCF
STATUS, RP0 ;Select Bank 0
MOVWF
analog2_l ;Move W register to Analog storage location
MOVLW 0x08
ADDWF ADCON0,1 ;Add 8 to
select next analog channel
BSF ADCON0, GO_DONE ;Start
the analog conversion
wait7 BTFSC ADCON0, GO_DONE ;Wait for
conversion to end
GOTO wait7
MOVF
ADRESH,0 ;Copy high byte AD to W register
MOVWF
analog3_h ;Move W register to Analog storage location
BSF STATUS, RP0 ;Select Bank 1
MOVF
ADRESL,0 ;Copy low byte AD to W register
BCF
STATUS, RP0 ;Select Bank 0
MOVWF
analog3_l ;Move W register to Analog storage location
MOVLW 0x08
ADDWF ADCON0,1 ;Add 8 to
select next analog channel
BSF ADCON0, GO_DONE ;Start
the analog conversion
wait8 BTFSC ADCON0, GO_DONE ;Wait for
conversion to end
GOTO wait8
MOVF
ADRESH,0 ;Copy high byte AD to W register
MOVWF
analog4_h ;Move W register to Analog storage location
BSF STATUS, RP0 ;Select Bank 1
MOVF
ADRESL,0 ;Copy low byte AD to W register
BCF
STATUS, RP0 ;Select Bank 0
MOVWF
analog4_l ;Move W register to Analog storage location
RETURN
;*************SUBROUTINE***************************
XMITDAT
MOVF analog0_h,0 ;Copy high byte AD
to W register
;MOVLW 0x01
MOVWF
TXREG ;Move W register to Transmit Register
CALL
Datadelay ;Call subroutine
MOVF analog0_l,0 ;Copy low
byte AD to W register
;MOVLW 0x02
MOVWF
TXREG ;Move W register to Transmit Register
CALL
Datadelay ;Call subroutine
;*************************************************
MOVF
analog1_h,0 ;Copy high byte AD to W register
;MOVLW 0x03
MOVWF TXREG ;Move W register to Transmit Register
CALL Datadelay ;Call subroutine
MOVF
analog1_l,0 ;Copy low byte AD to W register
;MOVLW 0x04
MOVWF TXREG ;Move W register to Transmit Register
CALL Datadelay ;Call subroutine
;*************************************************
MOVF
analog2_h,0 ;Copy high byte AD to W register
;MOVLW 0x05
MOVWF TXREG ;Move W register to Transmit Register
CALL Datadelay ;Call subroutine
MOVF
analog2_l,0 ;Copy low byte AD to W register
;MOVLW 0x06
MOVWF TXREG ;Move W register to Transmit Register
CALL Datadelay ;Call subroutine
;*************************************************
MOVF
analog3_h,0 ;Copy high byte AD to W register
;MOVLW 0x07
MOVWF TXREG ;Move W register to Transmit Register
CALL Datadelay ;Call subroutine
MOVF
analog3_l,0 ;Copy low byte AD to W register
;MOVLW 0x08
MOVWF TXREG ;Move W register to Transmit Register
CALL Datadelay ;Call subroutine
;*************************************************
MOVF
analog4_h,0 ;Copy high byte AD to W register
;MOVLW 0x09
MOVWF TXREG ;Move W register to Transmit Register
CALL Datadelay ;Call subroutine
MOVF
analog4_l,0 ;Copy low byte AD to W register
;MOVLW 0x0A
MOVWF TXREG ;Move W register to Transmit Register
CALL Datadelay ;Call subroutine
RETURN ;Return to main
;***************SUBROUTINE*****************************
;I FOUND IF SENDING THE
SAME SERIAL DATA (CHARECTER)
;REPETEDLY THERE WAS NO NEED FOR A DELAY BETWEEN
CHARECTERS
;I ONLY WAITED FOR THE REGISTER TO BE EMPTY BEFORE
;SENDING THE NEXT
CHARECTER. HOWEVER IF THE VALUE OF
;THE DATA CHANGED IT WOULD BE CORRUPT AT THE PC IF
THE
;TWO DELAY LOOPS WERE NOT USED
Datadelay
wait BTFSC TXSTA,
TRMT ;Check Transmit reg is empty
GOTO
wait ;Loop untill reg is empty
MOVLW
0xFF
MOVWF looplen ;Load looplen to
decrement as a delay
Xr70 DECFSZ looplen,1 ;this prevents corrupt
data at PC
GOTO Xr70
MOVLW 0xFF
MOVWF looplen ;Load looplen to decrement as a delay
Xr71 DECFSZ looplen,1 ;this prevents corrupt data at PC
GOTO Xr71
RETURN
END
; directive 'end of program'
Thanks
Mark
Sorry, that wasn't shown in
your code snippets. When you wait for
TRMT, you are losing speed because you
are waiting for the data to
be shifted out rather than just until the transmit
holding register
has been sent to the shift register.
You don't have to
use interrupts to make use of TXIF. Just test it
instead of TXSTA.
But,
that won't solve your problem. Maybe when you store byte size
registers it
would be better to store them in byte sized variables.
As I see it, you have
allowed two bytes for each byte of data:
Analog1_H EQU 0x30
Analog1_L EQU
0x32
It's always a toss up: post all relevant code and hide the forest
with trees or post too little code and lose context. I don't have
an answer
for that problem either. I know that I won't look at code
over a couple of
dozen lines because it takes too much time to
digest.
Richard
--- In
p...@yahoogroups.com, "Mark Adams" <markadams1971@y...>
wrote:
>
> I am not using transmit interrupts. Instead I check the following
flag.
>
> wait BTFSC TXSTA, TRMT ;Check Transmit reg is empty
> GOTO wait ;Loop until reg is
empty
> Thanks
> Mark
>
-----Original Message-----
> From: p...@yahoogroups.com
[mailto:p...@yahoogroups.com]On
Behalf Of
> rtstofer
>
Sent: Sunday, January 08, 2006 5:09 PM
> To: p...@yahoogroups.com
> Subject: [piclist] Re: 16F870 byte swapping>
>
I think you should be testing TXIF between bytes. You aren't
>
waiting for the tranmit holding register to be empty.
>
>
Richard
>
> --- In p...@yahoogroups.com, "Mark Adams"
<markadams1971@y...>
> wrote:
> >
> > Hello, I am working on a project where my PIC sends its analog
> input data
> > out the serial port. The code
copies the High and Low analog
result
> > registers to
variables I defined like this. Analog1_H EQU 0x30
> Analog1_L EQU
> > 0x32 and so on for each of the five analog ports. When all of
the
> analog
> > data has been saved it is
sent out the serial port like this:
> >
> >
MOVF analog0_H,0 ;Copy low byte AD to W register
> > MOVWF
TXREG ;Move data to
transmit register
> >
> > This repeats for
each variable (word?) 10 times total.
> >
>
> On the receiving end of the serial cable the data seems like
there
> is some
> > kind of shifting going on. what
happens is the data for
analog1 is
> seen in
> > word 1 and 3, for analog2 its in word 3 and 5, analog3 is in
word
> 5 and 7,
> > analog4 is in word 7 and
9 and analog5 is in words 9 and 1.
words
> 0,2,4,6
> > and 8 have no data.
> > If I substitute
literal data instead of the variables I can
> receive the data
> > as I would expect.
> >
> > MOVLW 0x01
> > MOVWF TXREG
> > MOVLW 0x02
> > MOVWF TXREG
> > MOVLW 0x03
> > MOVWF TXREG
> > Bla bla bla.....
> >
>
> Doing this I can receive the data values 1 through 10 in order.
>
>
> > I have used some commercial software that would let you
access
> memory on the
> > word and byte level.
So writing data to memory location 3 would
> write over
> > one byte of memory location 2. It seems like something of this
> nature is
> > happening and I am having trouble
finding the information on
how
> memory is
>
> accessed.
> >
> > How does the pic
define and use its memory, what is a byte and
a
> word and
> > how big is a memory location?
> >
> > Thanks
>
> Mark
> >
> to unsubscribe, go to http://www.yahoogroups.com and follow the
> instructions>
>
-------------------------------------------------------------------
---------
> --
> YAHOO! GROUPS LINKS
>
> a.. >
-------------------------------------------------------------------
---------
> --

(You need to be a member of piclist -- send a blank email to piclist-subscribe@yahoogroups.com )
Re: 16F870 byte swapping - Chris - Jan 9 7:48:00 2006
--- In piclist@picl..., "Mark Adams" <markadams1971@y...>
wrote:
> MOVF analog0_H,0 ;Copy low byte AD to W register
> MOVWF TXREG ;Move data to transmit register
Try testing the TXIF bit for completion of a transmit, you don't
need to have interupts enabled or have interupt handler code in
place to test that bit, it's 'active' wether or not you have
interupts enabled.
I had a similar problem recently I had to restructure my . on the
face of it these two segments work the same but the second version
works where the first version gives a problem similar to yours.
(start with a wait for the last transmit to complete)
BTFSS TXIF
goto $-1
(now load txreg)
movf next_data_byte, 0
movwf TXREG
(wait for txreg to empty)
BTFSS TXIF
goto $-1
None of the above works well......in having to load the next
byte of data into 'w' before transmission an unecessary delay
is introduced. The code which cured it for me is now like this
(start by loading tyhe data to be sent into 'w')
movf next_data_byte, 0
(wait for the last transmit to complete)
BTFSS TXIF
goto $-1
(now load txreg and preload W with the next byte)
movwf TXREG
movf next_data_byte, 0
(wait for txreg to empty)
BTFSS TXIF
goto $-1
movwf TXREG
movf next_data_byte, 0
BTFSS TXIF
goto $-1
movwf TXREG
BY preloading 'w' with the next byte the dealy is elliminated. My
application was to send the serial output over a short range RF link
so it may differ, but it's worth trying. i think the delay causes a
timing error which makes the receiver lose it's synch WRT the start
and stop bit positions.
Chris

(You need to be a member of piclist -- send a blank email to piclist-subscribe@yahoogroups.com )
Re: Re: 16F870 byte swapping - Mark Adams - Jan 9 13:29:00 2006
I have implemented the TXIF bit and I was able to remove
the loops that created the delay between transmitting characters. The problem with the
data overlapping is still there if I am sending the analog data. If I load fixed data to
the variables I can receive them fine. The problem must be in the section of code
that reads the analog result registers. The High and low results are in different banks
but I thought the code accounted for that.
Thanks
Mark
----- Original Message ----
From: Chris
<f...@aol.com>
To: p...@yahoogroups.com
Sent: Monday, January 09, 2006
5:48:32 AM
Subject: [piclist] Re: 16F870 byte swapping
--- In
p...@yahoogroups.com, "Mark Adams" <markadams1971@y...>
wrote:
>
MOVF analog0_H,0 ;Copy low byte AD to W register
>
MOVWF TXREG ;Move data to
transmit registerTry testing the TXIF bit for completion of a transmit, you don't
need to have interupts enabled or have interupt handler code in
place to test that
bit, it's 'active' wether or not you have
interupts enabled.
I had a
similar problem recently I had to restructure my . on the
face of it these two
segments work the same but the second version
works where the first version gives a
problem similar to yours.
(start with a wait for the last transmit to
complete)
BTFSS TXIF
goto $-1
(now load txreg)
movf
next_data_byte, 0
movwf TXREG
(wait for txreg to empty)
BTFSS TXIF
goto $-1None of the above works well......in having to load the next
byte of
data into 'w' before transmission an unecessary delay
is introduced. The code which
cured it for me is now like this
(start by loading tyhe data to be sent into
'w')
movf next_data_byte, 0
(wait for the last transmit to complete)
BTFSS TXIF
goto $-1
(now load txreg and preload W with the next
byte)
movwf TXREG
movf next_data_byte, 0(wait for txreg to empty)
BTFSS TXIF
goto $-1
movwf TXREG
movf next_data_byte, 0
BTFSS TXIF
goto $-1
movwf TXREG
BY preloading 'w' with
the next byte the dealy is elliminated. My
application was to send the serial output
over a short range RF link
so it may differ, but it's worth trying. i think the
delay causes a
timing error which makes the receiver lose it's synch WRT the start
and stop bit positions.
Chris

(You need to be a member of piclist -- send a blank email to piclist-subscribe@yahoogroups.com )
Re: 16F870 byte swapping - Chris - Jan 9 14:07:00 2006
--- In piclist@picl..., Mark Adams <markadams1971@y...> wrote:
>
> I have implemented the TXIF bit and I was able to remove the loops
that created the delay between transmitting characters. The problem
with the data overlapping is still there if I am sending the analog
data. If I load fixed data to the variables I can receive them fine.
The problem must be in the section of code that reads the analog
result registers. The High and low results are in different banks but
I thought the code accounted for that.
>
> Thanks
> Mark
By default, the result in teh ADRESH and ADRESL registers are a
decimal between 0-255, just the same as if you preload the registers
with a fixed known decimal value. I would make sure I have read the
results from the a/d conversion into a pair of buffer registers
before even entering a data transmission routine, that would make
sure that any extra delay introduced by extra time taken to read a/d
result registers is taken out of the equation, though as far as I'm
aware they are read in one cycle the same as any register is.
My transmission routines now only ever transmit data from buffers,
not from actual peripheral registers. The buffers are preloaded with
the peripheral result registers before I call the transmit routine,
which keeps the transmission routine itself clean of any interuptions.
If you were merely waiting for an a/d conversion to occur before
transmitting the data I would say that was where the problem lay
because an a/d conversion may not complete in time to reload the
TXREG again but you don't appear to be doing that......I'm puzzled !!

(You need to be a member of piclist -- send a blank email to piclist-subscribe@yahoogroups.com )
Re: 16F870 byte swapping - rtstofer - Jan 9 17:17:00 2006
Two other things to consider: First, I have already mentioned that
the variables are BYTES, not WORDS. Second, look in the datasheet
at FSR and INDF. These are used for indirect addressing. More
important to you, you can point FSR at the first variable and
reference whatever FSR points at by reading/writing the INDF
register. Then you increment FSR to point at the next variable.
This will simplify your loop considerably.
In fact, I would start at the high channel and work down since the
loop would terminate when it reached zero.
FSR = address of last byte of array
for (channel = last_channel; channel > 0; --channel)
{ read_a2d(channel)
store low register to INDF
decrement FSR
store high register to INDF
decrenemt FSR
}
Also, I noticed a strange way of putting the channel number into the
a/d channel register. It seems you were adding the channel to
something. I'd take another look at that.
Richard

(You need to be a member of piclist -- send a blank email to piclist-subscribe@yahoogroups.com )
RE: Re: 16F870 byte swapping - Mark Adams - Jan 10 6:21:00 2006
The
problem seems to be resolved. Here is some text from the reference
manual.
The A/D conversion time per bit is defined as TAD. A minimum wait of 2 TAD is required before the next acquisition
starts.
I
think this is about 12 micro seconds in my case. I will make some tests to check accuracy
and try to optimize the time.
After selecting the next analog channel to convert I call a subroutine to kill
some time so the Analog converter can do its
thing.
Thanks
Mark
--- In p...@yahoogroups.com, Mark Adams
<markadams1971@y...> wrote:
>
> I have implemented the TXIF bit and
I was able to remove the loops
that created the delay between transmitting
characters. The problem
with the data overlapping is still there if I am sending the
analog
data. If I load fixed data to the variables I can receive them fine.
The problem must be in the section of code that reads the analog
result registers.
The High and low results are in different banks but
I thought the code accounted for
that.
>
> Thanks
> MarkBy default,
the result in teh ADRESH and ADRESL registers are a
decimal between 0-255, just the
same as if you preload the registers
with a fixed known decimal value. I would make
sure I have read the
results from the a/d conversion into a pair of buffer registers
before even entering a data transmission routine, that would make
sure that
any extra delay introduced by extra time taken to read a/d
result registers is taken
out of the equation, though as far as I'm
aware they are read in one cycle the same
as any register is.
My transmission routines now only ever transmit data from
buffers,
not from actual peripheral registers. The buffers are preloaded with
the peripheral result registers before I call the transmit routine,
which keeps
the transmission routine itself clean of any interuptions.
If you were merely
waiting for an a/d conversion to occur before
transmitting the data I would say that
was where the problem lay
because an a/d conversion may not complete in time to
reload the
TXREG again but you don't appear to be doing that......I'm puzzled !!

(You need to be a member of piclist -- send a blank email to piclist-subscribe@yahoogroups.com )
RE: Re: 16F870 byte swapping - Mark Adams - Jan 10 6:22:00 2006
I will
look into the indirect addressing. I agree the code could be significantly reduced with
some loops. Being my first project I like to start with what I understand to make the
project work, then modify it so I can see how the changes affect it.
There
are 4 channel select bits in the ADCON0 register, the least significant is register
bit <3>. I am using a 28 pin device so only 3 of these bits pertain to me.
When I enter the analog conversion routine I clear these bits
BCF ADCON0, CHS0
BCF ADCON0, CHS1
BCF ADCON0,
CHS2
This
selects channel 0.
Then to
increment to the next channel I add 8 to the register. This sets and clears the proper
bits to increment sequentially through all five input channels.
MOVLW
0x08
ADDWF ADCON0,1 ;Add 8 to select next analog
channel
Two other things to
consider: First, I have already mentioned that
the variables are BYTES, not
WORDS. Second, look in the datasheet
at FSR and INDF. These are used for
indirect addressing. More
important to you, you can point FSR at the first
variable and
reference whatever FSR points at by reading/writing the INDF
register. Then you increment FSR to point at the next variable.
This
will simplify your loop considerably.
In fact, I would start at the high
channel and work down since the
loop would terminate when it reached zero.
FSR = address of last byte of array
for (channel = last_channel; channel > 0;
--channel)
{ read_a2d(channel)
store low register to INDF
decrement FSR
store high register to INDF
decrenemt FSR
}
Also, I noticed a strange way of putting the channel number into the
a/d
channel register. It seems you were adding the channel to
something. I'd
take another look at that.
Richard

(You need to be a member of piclist -- send a blank email to piclist-subscribe@yahoogroups.com )