Archive for October 29, 2013

Implementing Software SPI for PIC 2 PIC Communication

facebooktwittergoogle_plusredditpinterestlinkedinmailby feather

Hello,

In one of my projects i had to transmit some data between two PIC microcontrollers. The data represented some sensor values and it was important to know which value corresponded to which sensor.

This can be tricky if you don’t have free peripherals so i will present a way to implement SPI style communication by bit-banging any pin/port available. As with most SPI you will need 4 wires representing Clock, MISO (Master In Slave Out), MOSI (Master Out Slave In) and CS (Chip Select or Slave Select or Data Enable….).

Scenario is like this PIC1 MCU converts analog value of a few sensors with a 16bit resolution and then sends the data to PIC2 MCU for further processing. PIC2 needs to know that the data that was just received corresponds to a certain sensor. When can achieve this simply by letting PIC2 make a data request to PIC1.

E.g.

PIC2: [SEND DATA OF SENSOR 3]—————->:PIC1

PIC1:[SENDING SENOR 3 DATA]——————>:PIC2

PIC2: [SEND DATA OF SENSOR 7]—————->:PIC1

PIC1:[SENDING SENOR 7 DATA]——————>:PIC2

This way PIC2 will always associate the received data with the right sensor. It seems natural that PIC2 will be the SPI Master and PIC1 will be the slave. The Master is the one initiating the communication by first setting CS line to logic low and then starting the clock. It will then send the sensor address to the slave and receive the value from the slave. Once value was read it will stop the clock and set CS to logic high.

I assigned each sensor an address, 8 bit is enough allowing basically for 256 sensors. The received data is 16 bits long.

1. SPI MASTER program

/* I will use delay functions which you will need to define according to your compiler

and your Fcy settings. */

//Defining Signal Lines, replace “x” chars with your port/pin numbers

#define DCLK PORTxbits.Rxx
#define DIN PORTxbits.Rxx //MISO
#define DOUT PORTxbits.Rxx //MOSI
#define CS PORTxbits.Rxx

//Function to configure the data direction

//If you add these functions after main() remember to add prototype before main()

void Init_MSPI(void)

{

TRISxbits.TRISxx = 0; // clock
TRISxbits.TRISxx = 1; // DIN
TRISxbits.TRISxx = 0; // DOUT
TRISxbits.TRISxx = 0; // CS

//look in your MCU h file to get the actual TRIS struct parameters

CS=1;
DCLK=1;

}

UINT16 Get_Value_SSPI(char ADDRESS)

{

char temp; //used to serialize data

UINT16 in=0x0000; //will hold received 16bit data, initialize with 0

CS=0;

__delay_us(50);

//CS Line set to logic low

//begin serializing ADDRESS and sending it via DOUT from MSB to LSB

for(i=0;i<8;i++)
{
temp=ADDRESS&0x80; //Keep the MSB, ignore the rest of the bits
if(temp) // if MSB is 1 put 1 on DOUT and cycle clock 
{
DOUT = 1;
DCLK = 0;
__delay_us(50);
DCLK = 1;
__delay_us(50);
}
else //if MSB is 0 put 0 on DOUT and cycle clock
{
DOUT = 0;
DCLK = 0;
__delay_us(50);
DCLK = 1;
__delay_us(50);
}
ADDRESS <<=1; // Shift data to the right to get the next bit in MSB position
}

//cycle clock again, prepare to receive
DCLK = 0;
__delay_us(50);
DCLK = 1;
__delay_us(50);

//receiving the data
for(i=0;i<16;i++)
{
DCLK = 0; //activate clock
if(DIN) // if on DIN line we have 1 we put 1 in LSB position of “in” variable
in|=0x0001;
__delay_us(50);
DCLK = 1;
__delay_us(50);

//if DIN 0 leave variable unchanged, cycle clock
in<<=1; // shift LSB to right and prepare to receive the next bit
}

 //reception of last bit needs to be out of for loop so it wont get shifted to the right

if(DIN)
in|=0x0001;
DCLK = 0;
__delay_us(50);
DCLK = 1;
__delay_us(50);

//cycle clock and close communication by putting CS line to logic high

CS=1;
__delay_us(50);

}

// to call the function in main

UINT16 Sensor_Value;

Sensor_Value = Get_Value_SSPI(ADDRESS);

2. SPI Slave Program

//Defining Signal Lines, replace “x” chars with your port/pin numbers

#define DCLK PORTxbits.Rxx
#define DIN PORTxbits.Rxx //MISO
#define DOUT PORTxbits.Rxx //MOSI
#define CS PORTxbits.Rxx

//Function to configure the data direction

//If you add these functions after main() remember to add prototype before main()

void Init_SSPI(void)

{

TRISxbits.TRISxx = 1; // clock
TRISxbits.TRISxx = 1; // DIN
TRISxbits.TRISxx = 0; // DOUT
TRISxbits.TRISxx = 1; // CS

//notice clock and CS are inputs on slave MCU

}

void Send_Value_MSPI(void)

{

char address=0x00; //variable to hold sensor address

UINT16 out,temp; //out holds the sensor value, temp used to serialize data

while(!CS);
while(CS);

//wait for CS line to cycle to logic low

//this prevents the Slave to start its routine in the middle of communication

//start receiving Master data on DIN
for(i=0;i<8;i++)
{
if(DIN) //if DIN is 1 put 1 in data as LSB if 0 leave data unchanged
data|=0x01;
data<<=1; //shift LSB to the right, wait for clock and prepare for new bit
while(!DCLK);
while(DCLK);
}
if(DIN)//last bit must be out of for loop to prevent shifting it to the right
data|=0x01;

/*wait 2 clock periods in here you should get the value corresponding to the received address */
while(!DCLK);
while(DCLK);
while(!DCLK);
while(DCLK);

// serialize the value and send it bit by bit on DOUT

for(j=0;j<16;j++)
{
temp = out&0x8000;// keep MSB and ignore the res
if(temp) //toggle DOUT depending on MSB
DOUT=1;
else
DOUT=0;
out<<=1;//shift data to the right prepare next bit as MSB and wait for clock
while(!DCLK);
while(DCLK);
}
DOUT=0; // once all bits are sent put DOUT to 0 and wait final clock
while(DCLK);
while(!DCLK);

}

Ran the software on 2 PIC24FJ128GA010 devices and below you can see the signals. Remember DOUT form Master goes to DIN on Slave and DIN from Master Goes to DOUT on Slave. From top to bottom 1st signal = Clock, 2nd signal = Master DOUT, 3rd signal = Master DIN, 4th signal = CS

ADDRESS = 0xC2 Sensor_Value = 0xF10F

SPI Communication PIC

 

 

to see if each PIC MCU will interpret the data correctly i added a verification point on both programs by making a pin go high if the data is verified. Below you can see the signals.

SPI Communication PIC

showing control output and data lines

SPI Communication PIC

Showing control output with Clock and CS lines

 

You can change delay values in the Master program for faster or slower transmission, just make sure you have the same value everywhere. The beauty part is that you can use it with any ports/pins and not worrying about your peripherals.

Thank you for visiting.

Modern JBL Loudspeaker Lineup

IMG_0694 facebooktwittergoogle_plusredditpinterestlinkedinmailby feather

Here are some pictures of loudspeakers currently in JBL offer preserving the old monitors look.

JBL 4306 Loudspeaker

JBL 4306 Loudspeaker

JBL STUDIO Series

JBL STUDIO Series

JBL SAS101

JBL SAS101

JBL S4700

JBL S4700

JBL STUDIO 590CH

JBL STUDIO 590CH

JBL S4700 Grill off

JBL S4700 Grill off

JBL S4700 Grill off

JBL S4700 Grill off

JBL 4365

JBL 4365

From Left to Right: JBL 4365 JBL 4429 JBL 4306 JBL 4319 JBL 4312E

From Left to Right:
JBL 4365
JBL 4429
JBL 4306
JBL 4319
JBL 4312E

JBL 4319 JBL 4312E

JBL 4319
JBL 4312E

JBL 4365

JBL 4365 and JBL Everest DD66000

JBL K2 S9900 and a Pair of JBL S4700

JBL K2 S9900 and a Pair of JBL S4700

 

Thanks for visiting

 

 

 

 

 

 

 

 

 

 

 

 

JBL Everest DD66000 Bi-Amped with Accuphase

facebooktwittergoogle_plusredditpinterestlinkedinmailby feather

Looking through some of my pictures, I remember a setup i really liked and i thought i should share it.

JBL DD66000 running bi-amped with Accuphase P-6100 driving Mid-High Drivers and M-6000 driving Low Drivers. This was presented when DF-55 crossover unit was introduced.

Hope you will enjoy the pictures.

JBL Everest  and Accuphase Bi-Amp Setup

JBL Everest and Accuphase Bi-Amp Setup

JBL Everest DD66000

JBL Everest DD66000

JBL Everest DD66000 also Avalon

JBL Everest DD66000 also Avalon

JBL Everest DD66000 2WAY

JBL Everest DD66000 2WAY

The Mighty Accuphase M-6000

The Mighty Accuphase M-6000

 

Thank you for visiting.