LockedPIC32 -> SPI-> MAX7301 code example

Author
islemeco
New Member
  • Total Posts : 18
  • Reward points : 0
  • Joined: 2011/02/02 12:09:48
  • Location: 0
  • Status: offline
2011/02/15 06:31:12 (permalink)
0

PIC32 -> SPI-> MAX7301 code example


Hi, 
I am a user of a PIC32 Starter Kit,could you give me some example spi c program? I want to use it with Max7301,which is an I/O expander.Please give me some advice about this.

I Post my code and hope somebody can give me some advice about this.

Thank you in advance

!!!!!HEADER FILE!!!!!!
CSPI.H

#ifndef __CSPI_H_
#define __CSPI_H_

//---------- TYPDEF ----

typedef unsigned char        byte;  
typedef unsigned short int   word;    
typedef unsigned long        dword;   
typedef signed char          int8;     
typedef signed int           int16;   
typedef long                 int32; 
typedef unsigned char        uint8; 
typedef unsigned  int        uint16; 
typedef unsigned long        uint32; 


extern int rData;
extern void Init_MAX7301();

extern uint16 MAX7301_Read (unsigned char ucCommand);

extern uint16 MAX7301_Write (unsigned char ucCommand, unsigned int uiValue);

#endif
/* EOF */


!!!!!C-FILE!!!!!!

#include "plib.h"
#include "proc/p32mx795f512l.h"
#include "CSPI.H"

//With these settings PIC32 will run at 80MHz and peripherial bus at Fpb = 10MHz

#pragma config FNOSC    = PRIPLL    
#pragma config FPLLIDIV = DIV_2          
#pragma config FPLLMUL  = MUL_20     
#pragma config FPLLODIV = DIV_1      
#pragma config FPBDIV   = DIV_8     
#pragma config FWDTEN   = OFF     
#pragma config WDTPS    = PS1    
#pragma config FCKSM    = CSDCMD        
#pragma config OSCIOFNC = OFF       
#pragma config POSCMOD  = XT       
#pragma config IESO     = OFF          
#pragma config FSOSCEN  = OFF           
#pragma config CP       = OFF           
#pragma config BWP      = OFF         
#pragma config PWP      = OFF            
#pragma config ICESEL   = ICS_PGx2      
#pragma config DEBUG    = OFF           

// * * * Hardware * * *

// * * * I/O definitions * *
#define SPI_OUT     PORTDbits.RD0     /* 
#define SPI_IN      PORTCbits.RC4     /* 
#define SPI_CLK     PORTDbits.RD10    /* 
#define SPI_CS      PORTDbits.RD9     /* 
             
void SPI(int t, int p)

PORTDbits.RD9=p;
TRISDbits.TRISD9 = t;
//LATDbits.LATD9=l; 



// SPI peripheral configurations  
#define SPI_CONF      0x8420  //SPI on, 16-bit master,CKE=0,CKP=0  //is this OK?????????? 


#define SPI_BAUD    63     // clock divider Fpb/(2 * (63+1)) , so 10MHz/ (2*(63+1))=78.125KHz

void Init_MAX7301()
{
/* Config Register */
MAX7301_Write (0x04,0x01);  

// Mask the Transition Register
// MAX7301_Write (0x06,0xFF);

/*set P12-P21 output*/
MAX7301_Write(0x0B, 0x55);  // P12..P15 Outp 
//MAX7301_Write(0x0C, 0x55);// P16..P19 Outp
//MAX7301_Write(0x0D, 0xA5);// P20..P21 Outp

/*set P12-P21 logic high
MAX7301_Write(0x4C, 0xFF);   Do I need to DO?
MAX7301_Write(0x54, 0x03); 
*/

/*Set the shutdown/run bit,normal operation*/ 
MAX7301_Write(0x04, 0x01); 

/* Config Register*/
MAX7301_Write (0x04,0x81); 
}

uint16 MAX7301_Write (unsigned char ucCommand, unsigned int uiValue)
{
SPI(1,0 );
//SPI_CS = 0;                      // Set CS low controlled by hardware
 SPI1BUF = ((unsigned int) (ucCommand << 8)) + uiValue & ~0x8000;   // write to buffer for TX; First D15,D0 last; D15 low-> write command
 
//while( !SPI1STATbits.SPITBE);  IS this OK??  // wait for transfer complete //while TX buffer is full
// SPI_CS = 1;   // Set CS High 
SPI(0,1);
rData = SPI1BUF;                          
return rData;                                                // read the received value

}//writeSPI2

uint16 MAX7301_Read (unsigned char ucCommand)
{           

 SPI_CS = 0;                 // Set CS low controlled by hardware
SPI1BUF  =  ((unsigned  int)(ucCommand << 8)) | 0x8000;       // D15 high-> read command; MSB must be high for Read
                                                                      
while( !SPI1STATbits.SPIRBF);                                                   // wait until single-word transfer bit is set                                                    
SPI_CS = 1;                                                                              // Set CS High 
rData = MAX7301_Write(0x00,0x00);                                      // Dummy No - OP Write Access to shift Data                               
return rData; 
}

int rData;

int main()
{
IEC0CLR=0x03800000; // disable all interrupts
SPI1CON = 0; // Stops and resets the SPI1.
rData=SPI1BUF; // clears the receive buffer
IFS0CLR=0x03800000;//clear any existing event
IPC5CLR=0x1f000000; // clear the priority
IPC5SET=0x0d000000; // Set IPL=3, Subpriority 
IEC0SET=0x03800000; // Enable Rx, Tx and Error interrupts
SPI1STATCLR=0x40; // clear the Overflow
SPI1CON=0x8420; // SPI ON, 16 bits transfer, Slave mode
// from now on, the device is ready to receive and transmit data

//SPI1BUF=0xAA; // transmit an A character

Init_MAX7301();

                        
} // main


Best regards 

#1

8 Replies Related Threads

    chiranjeevi.M
    Starting Member
    • Total Posts : 76
    • Reward points : 0
    • Joined: 2011/01/09 23:48:35
    • Location: Andhra Pradesh, India
    • Status: offline
    Re:PIC32 -> SPI-> MAX7301 code example 2011/02/15 20:48:27 (permalink)
    0
    Hi,
       
             I had worked with the MAX7301 IC with PIC32MX795F512L, i used the MAX7301 to glow the led's and i am not reading from the IC(IO Expander).

    Here is my code


    void IOCONFIG1(unsigned int a)
    {
        PORTGbits.PORTG12=0;          // i made the port pin as the chip select by ignoring the ssi pin
        SPI1BUF=a;
        while(!SPI1STATbits.SPITBF==1);
        PORTGbits.PORTG12=1;
    }



    void IOINT(void)
    {
        IOCONFIG1(0X0401);
        IOCONFIG1(0x0955);
        IOCONFIG1(0x0A55);
        IOCONFIG1(0x0B55);
        IOCONFIG1(0x0C55);
        IOCONFIG1(0x0D55);
        IOCONFIG1(0x0E55);
        IOCONFIG1(0x0F55);

    // below makes the IO lines pull high
        IOCONFIG1(0x44FF);
        IOCONFIG1(0x4CFF);
        IOCONFIG1(0x54FF);
        IOCONFIG1(0x58FF);
        IOCONFIG1(0x5C0F);

    }

    void spi1_init(void)
    {
        SPI1CON=0;
        SPI1STAT=0;
        SPI1BRG=0x60;    // 50 khz BRG
        SPI1CONbits.MODE16=1;
        SPI1CONbits.CKE=0;
        SPI1CONbits.MSTEN=1;
        SPI1CONbits.ON=1;
    }   


    these are the initializations i made this working fine for me.

    Make a note that Data out pin of the Max7301 is not pulled to high impedance state, it is left floating if you want to use other spi devices with the same port & if you are not using the data out pin in this ic, my suggestion is to break the connection of the data out pin and make it pull high.



    Regards,
    Chiranjeevi.M
    #2
    islemeco
    New Member
    • Total Posts : 18
    • Reward points : 0
    • Joined: 2011/02/02 12:09:48
    • Location: 0
    • Status: offline
    Re:PIC32 -> SPI-> MAX7301 code example 2011/02/21 03:34:45 (permalink)
    0
    Thank you very much chiranjeevi.
    It worked at first attempt.

    Now I would like to control two Max7301 simultaneously with a PIC32.
     
    I have the same circuit as the data sheet of IC.


    But would it also work in this way??

    PIC32                           MAX1              
                  CLK-------------CLK   
                  Dout-----------  DIN                   
                  DIN                  DOUT
                  SS1 (RD12)---SS        
      
    PIC32                           MAX2               
                  CLK-------------CLK   
                  Dout-----------  DIN                   
                  DIN                  DOUT
                  SS2(RD11)---SS                      


    if I want to drive the first building block, then I do it this way:
      IOINT void (void)
    {
          IOCONFIG1 (0x0F55);

    / / below makes the IO lines pull high
         IOCONFIG1 (0x44FF);
    }
    This works!


    If I want to drive the second block, I also send the no-op command (0x00)

      IOINT void (void)
    {
          IOCONFIG1 (0x0000);   //_ nop __Kommando
          IOCONFIG1 (0x0F55);

    / / below makes the IO lines pull high
         IOCONFIG1 (0x0000);    //_ nop __Kommando
         IOCONFIG1 (0x44FF);
    }
    This doesn´t work !?!?


    what am I doing wrong?
    #3
    sborden
    Super Member
    • Total Posts : 1932
    • Reward points : 0
    • Joined: 2010/08/05 02:12:53
    • Location: 0
    • Status: offline
    Re:PIC32 -> SPI-> MAX7301 code example 2011/02/21 12:34:33 (permalink)
    0
    You should control them in sequence because the lines are tied together except the SSx lines.  First use the SS1 to control the first one, then seit it high and set the SS2 line low to control the second one.  If  you want to really do simultaneous, I would suggest bit-banging with all output lines on one port (each on different pins) and the inputs lines on another (each on different pins).  You might get away with having all outputs tied together (depends on slave device current draw), but the inputs *must* be handled on separate lines since they could be sending 1 and 0, causing a short (smoke in worse-case scenario).
    #4
    islemeco
    New Member
    • Total Posts : 18
    • Reward points : 0
    • Joined: 2011/02/02 12:09:48
    • Location: 0
    • Status: offline
    Re:PIC32 -> SPI-> MAX7301 code example 2011/02/21 16:26:01 (permalink)
    0
    Hi,
    What do you mean with "all output lines on one port (each on different pins) and the inputs lines on another (each on different pins);"??

    I should drive with one PIC32 multiple Max7301`s. On each Output of every MAX7301 will sit one Relay.

    "First use the SS1 to control the first one, then seit it high and set the SS2 line low to control the second one."  In this situation, the board layout of the system can become quite a challenge:-)


    I have the same structure as on page 9 in the Datasheet [font="'times new roman'; line-height: 22px; font-size: medium; "]http://datasheets.maxim-ic.com/en/ds/MAX7301.pdf.


     I have connected the DOUT of one device to the DIN of the next, and
    driving SCLK and CS lines in parallel.  

    In the Datasheet is written
    "When sending commands to multiple MAX7301s, all devices are accessed at the
    same time. An access requires (16 ✕ n) clock cycles, where n is the number of MAX7301s connected together. To update just one device in a daisy-chain, the user can send the No-Op command (0x00) to the others. "




    post edited by islemeco - 2011/02/21 16:44:31
    #5
    sborden
    Super Member
    • Total Posts : 1932
    • Reward points : 0
    • Joined: 2010/08/05 02:12:53
    • Location: 0
    • Status: offline
    Re:PIC32 -> SPI-> MAX7301 code example 2011/02/21 18:30:36 (permalink)
    0
    Daisy chain mean for 4 devices, you need to clock 64 pulses.  In parallel, you just need 16.

    in the '32  All ports are 16-bits wide.   You can use one bit (pin) for each signal, then use the LATxSET, LATxCLR commands for simultaneous access for all pins of that port.   I am talking about simultaneous access.  If you can deal with the daisy-chain, then it *is* simpler.  What *is your* requirement?
    #6
    islemeco
    New Member
    • Total Posts : 18
    • Reward points : 0
    • Joined: 2011/02/02 12:09:48
    • Location: 0
    • Status: offline
    Re:PIC32 -> SPI-> MAX7301 code example 2011/02/23 05:33:11 (permalink)
    0
    ok I understand

    My job is to control 128 relays. I navigate them with the PIC32. Since the PIC does not have enough pins i use 8  IO Expander. The  requirement is that the relays should  be controlled to both individually and simultaneously.
    #7
    chiranjeevi.M
    Starting Member
    • Total Posts : 76
    • Reward points : 0
    • Joined: 2011/01/09 23:48:35
    • Location: Andhra Pradesh, India
    • Status: offline
    Re:PIC32 -> SPI-> MAX7301 code example 2011/02/26 20:57:41 (permalink)
    0
    Dear Paul,

             I  also used two MAX7301 IC's on the same pic ic. But i found a problem in writing the data on to them. As in above program if i wrote as it is it was working fine for me, if i change the program in one sentence it will collapse. More over the P28,29,30,31 are slightly different from others so be careful while handling the ports.

             I used PORTG 12,13 as chip select.

             After initialization i have to glow leds with the IC's. When i write the data for one time it doesn't work properly. If i write two times it works fine, however i have to minimize the program.

             More over i use 8 bit register in some cases and single bit register some times.

             sorry for the delay

    Regards,
    Chiranjeevi.M
    #8
    islemeco
    New Member
    • Total Posts : 18
    • Reward points : 0
    • Joined: 2011/02/02 12:09:48
    • Location: 0
    • Status: offline
    Re:PIC32 -> SPI-> MAX7301 code example 2011/03/09 16:11:31 (permalink)
    0
    Thank You for your answers....
    #9
    Jump to:
    © 2017 APG vNext Commercial Version 4.5