Sign in

username:

password:



Not a member?

Search piclist



Search tips

Subscribe to piclist



piclist by Keywords

12F675 | 16F628 | 16F84 | 16f877 | 16F877A | 16F88 | 18F458 | ADC | AVR | Bootloader | CAN | CCS | CRC | EAGLE | EEPROM | ICD | ICSP | IDE | JDM | LED | Macros | Microchip | MPLAB | PCB-CAD | PIC10F | Pic12f675 | PIC16F84 | PIC16F84A | PIC16F877 | PIC18 | PIC18F452 | PicBasic | PICC | PICSTART | PWM | RS-485 | RS232 | SMT | SPI | UART | USART | USB | Wireless | Wisp628 | Xilinx

Discussion Groups

Discussion Groups | Piclist | RE: Re: 16F870 byte swapping

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
-----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




(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
-----Original Message-----
From: p...@yahoogroups.com [mailto:p...@yahoogroups.com]On Behalf Of rtstofer
Sent: Sunday, January 08, 2006 5:55 PM
To: p...@yahoogroups.com
Subject: [piclist] Re: 16F870 byte swapping

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

-----Original Message-----
From: p...@yahoogroups.com [mailto:p...@yahoogroups.com]On Behalf Of Chris
Sent: Monday, January 09, 2006 1:07 PM
To: p...@yahoogroups.com
Subject: [piclist] Re: 16F870 byte swapping

--- 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
 
 
-----Original Message-----
From: p...@yahoogroups.com [mailto:p...@yahoogroups.com]On Behalf Of rtstofer
Sent: Monday, January 09, 2006 4:17 PM
To: p...@yahoogroups.com
Subject: [piclist] Re: 16F870 byte swapping

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 )