Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

16 bit SPI advice needed

Status
Not open for further replies.

BobW

Active Member
My project of the week (if I'm lucky) involves interfacing a PIC16F1703 to an Analog Devices ADIS16203 digital inclinometer. Both are SPI capable. However, the ADIS16203 works strictly in 16 bit words, and the PIC16F1703 SPI documentation only discusses 8 bit byte transfer. I assume that I just need to read two successive bytes over SPI to get the full 16 bit word from the inclinometer, but I can also see where things could easily go awry (given my past experience with odd serial protocols). In past projects, when things were a bit non-standard, I would just bit bang the data, rather than try to figure out how to set up all of the config registers and config bits. That's what I'd do here (and probably will bit bang it for initial testing), but eventually I want to get this working in an interrupt routine, so I'll have to use the actual SPI port.

Does anyone here have experience with 16 bit SPI, and tips or example code to share?

Edit: I should mention that this will be programmed in assembly language.
 
Hi Bob,

I have done it only a few times. Just like you suggest, you exchange 8 bits at a time. One chip I used was the AK8963 e-compass with a 16F1783. That did a sequential read of several 8-bit registers. Probably closest to what you are doing was reading the AS5048A rotary encoder from AMS. I used a 16F1519 for that. Here's a snippet of the read code. If more will help, let me know, and I will clean up the rest. I typically write a lot of comments to myself, which maybe shouldn't be put in public. Note, bits 15 and 14 were for parity and error, respectively, and had to be stripped off before calculating the encoder result. Here's a link to the datasheet: https://ams.com/eng/Products/Magnetic-Position-Sensors/Angle-Position-On-Axis/AS5048A (Can't link directly to the DS. Just click on the link there.)

Code:
;setup serial port
     MOVLB     4              ;SPI controls in Bank4                       |B4
     CLRF      SSPSTAT        ;CKE=0, SMP=0 (sample at middle)                                       |B4
     MOVLW     b'00100000'    ;
     MOVWF     SSPCON1        ;CKP=0,master clk =Fosc/x (see below),
;SPEN <5> enabled
;04.25.15 tried all 3 settings for <3,0>, Fosc/64 did not work, others did,
;hung up on waiting for the BF flag bit. 0001=Fosc/16 should work wtih
;all Fosc up to 32 MHz.  0000=Fosc/4. AS5048 internal clock is ca. 5 MHz. ˜˜
  
GetSPI    
     MOVLB     2              ;                                            |B2
     BCF       CSn            ;!CS                                         |B2
     MOVLB     4              ;                                            |B4
     MOVLW     0xFF           ;alternative to zeros                        |B4                    |B4
     MOVWF     SSPBUF         ;                                            |B4
;    CLRF      SSPBUF         ;initiates duplex communication              |B4
                          
GetBUFF
;NB:Polling SSPSTAT,BF seems to work as well as polling PIR1,SSPIF and
;doesn't require bank switching.  
     btfss     SSPSTAT,BF
     goto      $-1
     movf      SSPBUF,w
     movwf     SPI_H
     CLRF      SSPBUF
     btfss     SSPSTAT,BF
     goto      $-1
     movf      SSPBUF,w
     movwf     SPI_L    
     movlb     2              ;                                           |B2
     bsf       CSn            ;set !SS(CSn)high                           |B2
;    movlb    4                                                           |B4
;    BCF       SSPCON1,SSPEN  ;disable SPI port leave running             |B4

ErrTest
     BTFSC     SPI_H,6        ;checks error bit and returns if set
     GOTO      Test0
     BCF       SPI_H,7        ;clears parity bit so print not effected 08.01.15
     BSF       SPI_H,7    
;SET BIT<7> TO FLAG HIGH (MSB) BYTE WHEN SENDING EUSART TO STEPPER
;insert save data steps here
     nop
;     DelayCy   (150*msecs)
;     DelayCy   (150*msecs)
     call      RegPrnt
     goto      GetSPI

John

EDIT: Just noticed the last 2 steps in the error test section. Ignore one or both. I was using that particular draft of the whole code to drive a stepper motor synchronously to the movement of the encoder input.
 
Last edited:
Thanks John. Much appreciated. I'm completely brain dead tonight, so I'll give your code a good looking over tomorrow.
BTW, there's no such thing as too many comments.
 
Not much help but to drive a 16bit DAC fast I had to resort to a PIC24F with a 16 bit SPI controller, beware not all 16 bit mcu's have 16 bit SPI only those with fifo buffers!
 
Not much help but to drive a 16bit DAC fast I had to resort to a PIC24F with a 16 bit SPI controller, beware not all 16 bit mcu's have 16 bit SPI only those with fifo buffers!
I use MCP's 12bit DAC... Same protocol as the 16bit.. I use two 8bit SPI transfers with no issue at all using pic16 and pic18...

SPI has 4 modes.... You just need to make sure the correct mode is selected or you can loose a bit in the middle..
 
Yes, it's perfectly fine to send two 8 bit bytes, it's the way it's most often done - there seems little advantage in using 16 bit mode on the 24F series, so I don't bother.

Even if you do, it leaves the identical 'problem' of how do you do 32 bit transfers :D
 
Well I did use the word FAST!!
True... The speed will come from the abilities of the pic24 over the pic16 and pic18.

To run at 8MHz on a small pic, you have to run at top speed, but the pic32 and pic24 can have different peripheral speeds.. I am testing a small SPI screen on a pic18... I can't achieve max speed ( 10MHz) only 8 or 16MHz..

Between 8 and 10 there is little difference I know, but it doesn't work at 16!!
 
True... The speed will come from the abilities of the pic24 over the pic16 and pic18.

To run at 8MHz on a small pic, you have to run at top speed, but the pic32 and pic24 can have different peripheral speeds.. I am testing a small SPI screen on a pic18... I can't achieve max speed ( 10MHz) only 8 or 16MHz..

Between 8 and 10 there is little difference I know, but it doesn't work at 16!!

Tell me about it!! :D

On my PIC18F18877, running at 32MHz, I have to run the SPI at div16 (2MHz), it doesn't work at all at div4 (8MHz) - dropping the clock speed to 16MHz allows the use of div4 (4MHz), but at the lower clock speed it runs slightly slower anyway.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top