cancel
Showing results for 
Search instead for 
Did you mean: 

SPI transmit and receive.

jtron.1
Associate III

Hi All.!!!

I am working on STM32F103 and using its 4-wire SPI for communication with slave whose data is 32bit and addr is 16bit.

What I am trying to do is to write and read slave but i could not below is the settings that

I have done in STM cube MX.

Mode:- Full Duplex Master

Data Size 16 bit

Pre scaler 32 selected.

For write operation

uint8 WriteBronco(uint32 Data,uint16 Addr)

{

  uint32_t data[2];

data[0] = Addr; // multibyte write enabled

data[1] = Data; //32bit of data slave

HAL_GPIO_WritePin (GPIOB, GPIO_PIN_6, GPIO_PIN_RESET); // pull the cs pin low to enable the slave

HAL_SPI_Transmit (&hspi1, data, 2, 100); // transmit the address and data

HAL_GPIO_WritePin (GPIOB, GPIO_PIN_6, GPIO_PIN_SET); // pull the cs pin high to disable the slave

  return 0;

}

For Read operation

void adxl_read (uint16_t address)

{

address = 0x8000; //

address = 0x4000; //

HAL_GPIO_WritePin (GPIOB, GPIO_PIN_6, GPIO_PIN_RESET); // pull the cs pin low to enable the slave

HAL_SPI_Transmit (&hspi1, &address, 2, 100); // send the address from where you want to read data

HAL_SPI_Receive (&hspi1, data_rec, 6, 100); // read 6 BYTES of data

HAL_GPIO_WritePin (GPIOB, GPIO_PIN_6, GPIO_PIN_SET); // pull the cs pin high to disable the slave

 

}

Kindly let me know how I can do this ??

4 REPLIES 4
Pavel A.
Evangelist III

> uint32_t data[2];

> HAL_SPI_Transmit (&hspi1, data, 2, 100); // transmit the address and data

This is 8 bytes. But you're sending 2.

EEbyKarl
Associate III

I've made modifications to your code.

uint8_t WriteBronco(uint32_t Data, uint16_t Addr)
{
    uint8_t data[8] = {0}; // change to 8 bit type
    int i;
    uint8_t dataSize = 6;
 
    // Writing LSB>MSB. You will have to adjust if the register needs to be written MSB>LSB.
    data[0] =  Addr; // multibyte write enabled
    data[1] =  Addr >> 8;
    
    data[2] =  Data; //32bit of data slave
    data[3] =  Data >> 8; 
    data[4] =  Data >> 16; 
    data[5] =  Data >> 24; 
    
    HAL_GPIO_WritePin (GPIOB, GPIO_PIN_6, GPIO_PIN_RESET); // pull the cs pin low to enable the slave
    
    HAL_SPI_Transmit (&hspi1, data, 6, 100); // transmit the address and data <-- writing 6 bytes total
    
    HAL_GPIO_WritePin (GPIOB, GPIO_PIN_6, GPIO_PIN_SET); // pull the cs pin high to disable the slave
 
    return 0;
 
}
 
void adxl_read (uint16_t address)
{
    uint8_t addr[2];
 
    address = 0x8000; //
    
    address = 0x4000; //
    
    addr [0] = address;
    addr [1] = address >> 8;
    
    HAL_GPIO_WritePin (GPIOB, GPIO_PIN_6, GPIO_PIN_RESET); // pull the cs pin low to enable the slave
    
    HAL_SPI_Transmit (&hspi1, addr, 2, 100); // send the address from where you want to read data
    
    HAL_SPI_Receive (&hspi1, data_rec, 4, 100); // read 6 BYTES of data <-- a 32bit register is 4 bytes, not 6 bytes. 
                                                // Let's assume data_rec is an uint8_t array, size of at least 4 bytes.
    
    HAL_GPIO_WritePin (GPIOB, GPIO_PIN_6, GPIO_PIN_SET); // pull the cs pin high to disable the slave
 
}

Thanks for the reply.

You are sending 6x8 bytes of data.

But slave has three registers as ADDR--16bit, Data_L--16bit(LSB), and Data_H--16bit(MSB).

By doing 6x8 how slave will figure out the data and address.??

I configured 16-bit data spi in cube mx.

Below is the code I have made some changes as below

Will it work ?

void spi_wr_flash(uint16 addr, uint16 dat_h, uint16 dat_l)

{

  //set_data_cmd_flash(0x08,dat_l);//This is the code taken from slave datasheet they have done as this.They `broke data into 2 parts 16bit each. Sending cmd for writing sending 16bit LSB.

 //set_data_cmd_flash(0x0a,dat_h); //Sending cmd for writing sending 16bit MSB.

  //set_data_cmd_flash(0x0c,addr);//Sending addr

    uint16_t Data_L[2];

    Data_L[0]=0x08;

    Data_L[1]=dat_l;

    uint16_t Data_H[2];

    Data_H[0]=0x0a;

Data_H[1]=data_h;

uint16_t ADDR[2];

ADDR[0]=0x0c;

ADDR[1]=addr;

 

HAL_GPIO_WritePin (GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);     // pull the cs pin low to enable the slave

HAL_SPI_Transmit (&hspi1, DATA_L, 2, 100); // transmit the address and data

HAL_SPI_Transmit (&hspi1, DATA_H, 2, 100);

HAL_SPI_Transmit (&hspi1, ADDR, 2, 100);

HAL_GPIO_WritePin (GPIOB, GPIO_PIN_6, GPIO_PIN_SET); // pull the cs pin high to disable the slave

}

The SPI bus writes 8 bits at a time whether the register size is 16 or 32 bits.

In your original post you had

uint32_t data[2];
data[0] = Addr; // multibyte write enabled
data[1] = Data; //32bit of data slave

you copied the 16 bit address into a 32bit array. So the SPI peripheral is clocking in the upper 16 bits of the array which will be 0x0000 for the address. Then the next 16 bits which is the address is being clocked in as the register data. So all your address/data is off by 16 bits.

Change you variable declaration to

uint16_t data[3];

So even though data size is three 16 bits array, you still have to pass the argument of 6 for the amount of bytes being clocked into the register.