SPI - The basics


Closed Thread
Results 1 to 19 of 19

Hybrid View

  1. #1
    Join Date
    Aug 2010
    Posts
    11

    Default SPI - The basics

    Greetings to all and thanks for a very thorough user forum. I am very new to pics, picbasic and microcontrollers. I won't pretend to understand 1/2 of what I have read but some of it must have sunk in as I am 1/2 way through a project. I am building a PID controller and can successfully read in 2 AI channels, display their values on an LCD and create the output value for the PID.
    Now for control I realize I can use PWM or a DAC chip. I have (regretfully??) chosen the later of the two and am now stuck. I cant really find sufficient documentation and code examples. I am using a 16F877A and need to get the DAC conversion through a MCP4812.
    So before a I beg for any direct answers - I would love some pointers as to where to get the relevant code/ pinout/ examples to learn from.

    I do have one other anomaly that has no caused me too much grief yet, but I fear it is coming as I might need it to get through this DAC section. When I try to use the ASM ... ENDASM within my code - it will not compile!!!!

    Thanks to any whom might be able to give some guidance

  2. #2
    Join Date
    Aug 2010
    Posts
    11

    Default

    Okay, maybe I can focus this on where exactly I am getting lost. The MCP4812 needs the data brought in a specific format. That is bits 15:12 are formatting information for the data and bits 11:0 are the 12 bit digital (or 10 bit ...) information that is being transfered.
    As I understand it, the SEROUT command will send 8 bit packets and I am not sure how to get the cofiguration data combined with the actual data??????? and, combine this as 1 - 16 bit packet???????

  3. #3
    Join Date
    Jul 2003
    Posts
    2,405

    Default

    For SPI use SHIFTOUT. Something like this should work;
    Code:
    A VAR WORD
    B VAR WORD
     
    CS VAR PORTB.0  ' chip select
    SCK VAR PORTB.1 ' clock
    SDI VAR PORTB.2 ' data
    LDAC VAR PORTB.3 ' load DAC
     
    HIGH CS   
    LOW SCK
    HIGH LDAC
     
    A = %0001111111111100 ' channel A, 2x, active, max output
    B = %1001111111111100 ' channel B, 2x, active, max output
     
    Main:
      LOW CS ' enable writes
      SHIFTOUT SDI,SCK,0,[A\16]
      HIGH CS 
      PAUSE 5
     
      LOW CS
      SHIFTOUT SDI,SCK,0,[B\16]
      HIGH CS
     
      LOW LDAC ' load both DAC outputs
      PAUSE 5
      HIGH LDAC
     
      PAUSE 5000
      GOTO Main
      END
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  4. #4
    Join Date
    Aug 2010
    Posts
    11

    Default

    Thanks Bruce. I will give this a go in the next day or two and let you know if I had some success!

  5. #5
    Join Date
    Aug 2010
    Posts
    11

    Default

    Thanks Bruce - I now have some level of success !??!

    I was stuck for a while with only getting a Vref output from the 4812 - no matter what 10 bit information I loaded it was the same. I just had to change the mode on the SHIFTOUT command to a 1 or MSB first and it fell in line.

    For this example, you are predefining the 10 bits for conversion in A and B. How would I load up 'A' with the same first 4 bits but then the next 12 (10) bits varying, based on my PID loop output?

    Thanks again ...

  6. #6
    Join Date
    Jul 2003
    Posts
    2,405

    Default

    There are several ways to do it, but I would probably go for something like this;

    The upper 4-bits for DAC channel A, with 2x gain, with A active, will remain constant. So create a constant like ASel CON 4096. This would be the following in 16-bit binary: %0001000000000000.

    The lower 12-bits, with the 2 least significant bits ignored, + ASel would be your value to send to the DAC to adjust the channel A output.

    Just use a word variable. Load your word variable with any value from 0 to 1023, then shift this left x 2 so the 2 LSBs are 0, then add the ASel constant for the value to shiftout.

    Say your word var is ChanA, and it's = 501. ChanA = (ChanA << 2) + ASel.

    501d = %0000000111110101. Shifted left x 2 it's %0000011111010100. When you add the ASel constant, it ends up being %0001011111010100.
    Last edited by Bruce; - 1st September 2010 at 17:00.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts