cancel
Showing results for 
Search instead for 
Did you mean: 

NUCLEO-H753ZI SPI Communication

Aamir1033
Associate II

 

hi, 

I am integrating ADS1256 ADC, which communicates on SPI with NUCLEO-H753ZI board. 

Firstly, I can communicate when I am writing my code in Arduino, which is simple. It is working fine and showing me the converted output. 

But for some reasons I have to use cubide and perform some work on ethernet after establishing communication on SPI. But through cubeIDE I am not able to establish cube ide. below is Clock config

But with same flow as in Arduino, I cannot stablish communication. Cannot read registers of the device, nor i can get the output

Aamir1033_0-1745658400470.png

and here is my SPI initiazation.

hspi3.Instance = SPI3;

hspi3.Init.Mode = SPI_MODE_MASTER;

hspi3.Init.Direction = SPI_DIRECTION_2LINES;

hspi3.Init.DataSize = SPI_DATASIZE_8BIT;

hspi3.Init.CLKPolarity = SPI_POLARITY_LOW;

hspi3.Init.CLKPhase = SPI_PHASE_1EDGE;

hspi3.Init.NSS = SPI_NSS_SOFT;

hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;

hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB;

hspi3.Init.TIMode = SPI_TIMODE_DISABLE;

hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

hspi3.Init.CRCPolynomial = 0x0;

hspi3.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;

hspi3.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;

hspi3.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;

hspi3.Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;

hspi3.Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;

hspi3.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;

hspi3.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;

hspi3.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;

hspi3.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE;

hspi3.Init.IOSwap = SPI_IO_SWAP_DISABLE;

if (HAL_SPI_Init(&hspi3) != HAL_OK)

{

Error_Handler();

}

 

void delay_us(uint32_t us)

{

// Reset the counter to 0

__HAL_TIM_SET_COUNTER(&htim2, 0);

 

// Wait until the counter reaches the desired delay

while (__HAL_TIM_GET_COUNTER(&htim2) < us);

}

 

uint8_t ADS1256_DRDY_Wait()

{

unsigned int DRDY_State = 1;

while(DRDY_State)

{

DRDY_State = HAL_GPIO_ReadPin(DRDY_PIN_GPIO_Port, DRDY_PIN_Pin);

}

return 0;

}

uint8_t ADS1256_Reset()

{

HAL_GPIO_WritePin(RST_PIN_GPIO_Port, RST_PIN_Pin, 0);

HAL_Delay(100);

HAL_GPIO_WritePin(RST_PIN_GPIO_Port, RST_PIN_Pin, 1);

 

uint8_t resetCmd = 0xfe;

HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_RESET); // CS Low

HAL_SPI_Transmit(&hspi3, &resetCmd, 1, HAL_MAX_DELAY);

HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_SET); // CS High

return 0;

}

 

void ADS1256_SelectChannel()

{

uint8_t wregCmd[3];

wregCmd[0] = 0x50 | 0x01; // WREG command for the MUX register (0x01)

wregCmd[1] = 0x00; // Number of registers to write minus 1 (just the MUX register)

wregCmd[2] = 0x2f; // Channel configuration

 

ADS1256_DRDY_Wait();

HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_RESET); // CS Low

HAL_SPI_Transmit(&hspi3, wregCmd, 2, HAL_MAX_DELAY); // Send WREG command and data

delay_us(5);

HAL_SPI_Transmit(&hspi3, &wregCmd[2], 1, HAL_MAX_DELAY);

HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_SET); // CS High

}

 

uint8_t ADS1256_ReadMuxRegister()

{

uint8_t rregCmd[2];

uint8_t regValue = 0x01;

 

rregCmd[0] = 0x10 | 0x01; // RREG command for the MUX register (0x01)

rregCmd[1] = 0x00; // Number of registers to read minus 1 (just the MUX register)

 

ADS1256_DRDY_Wait();

HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_RESET); // CS Low

HAL_SPI_Transmit(&hspi3, rregCmd, 2, HAL_MAX_DELAY); // Send RREG command

delay_us(5);//5 microsec delay required

HAL_SPI_Receive(&hspi3, &regValue, 1, HAL_MAX_DELAY); // Receive the register value

HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_SET); // CS High

printf("\nRegister Value = %x", regValue);

return regValue;

}

 

void ADS1256_ReadData(uint32_t *adcValue)

{

uint8_t rdataCmd = 0x01; // RDATA command

uint8_t rxBuffer[3]; // Buffer for 24-bit ADC data

 

ADS1256_DRDY_Wait();

HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_RESET); // CS Low

HAL_SPI_Transmit(&hspi3, &rdataCmd, 1, HAL_MAX_DELAY); // Send RDATA command

delay_us(10);

HAL_SPI_Receive(&hspi3, rxBuffer, 3, HAL_MAX_DELAY); // Receive 24-bit data

HAL_GPIO_WritePin(SPI_CS_GPIO_Port, SPI_CS_Pin, GPIO_PIN_SET); // CS High

 

// Combine the 3 bytes into a 24-bit integer

*adcValue = ((uint32_t)rxBuffer[0] << 16) |

((uint32_t)rxBuffer[1] << 8) |

(uint32_t)rxBuffer[2];

}

 

double ConvertToVoltage(int32_t registerData)

{

double Voltage = 0;

double VREF = 2.5;

long minus = registerData >> 23;

if (minus == 1) //if the 24th bit (sign) is 1, the number is negative

{

registerData = registerData - 16777216; //conversion for the negative sign

//"mirroring" around zero

}

 

Voltage = ((2*VREF) / 8388608)*registerData; //2.5 = Vref; 8388608 = 2^{23} - 1

return (Voltage);

}

 

/* USER CODE END 0 */

 

/**

* @brief The application entry point.

* @retval int

*/

int main(void)

{

 

/* USER CODE BEGIN 1 */

 

/* USER CODE END 1 */

 

/* MCU Configuration--------------------------------------------------------*/

 

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */

HAL_Init();

 

/* USER CODE BEGIN Init */

 

/* USER CODE END Init */

 

/* Configure the system clock */

SystemClock_Config();

 

/* Configure the peripherals common clocks */

PeriphCommonClock_Config();

 

/* USER CODE BEGIN SysInit */

 

/* USER CODE END SysInit */

 

/* Initialize all configured peripherals */

MX_GPIO_Init();

MX_SPI3_Init();

MX_TIM2_Init();

 

/* Initialize interrupts */

MX_NVIC_Init();

/* USER CODE BEGIN 2 */

 

/* USER CODE END 2 */

 

/* Initialize leds */

BSP_LED_Init(LED_GREEN);

BSP_LED_Init(LED_BLUE);

BSP_LED_Init(LED_RED);

 

/* Initialize USER push-button, will be used to trigger an interrupt each time it's pressed.*/

BSP_PB_Init(BUTTON_USER, BUTTON_MODE_EXTI);

 

/* Initialize COM1 port (115200, 8 bits (7-bit data + 1 stop bit), no parity */

BspCOMInit.BaudRate = 115200;

BspCOMInit.WordLength = COM_WORDLENGTH_8B;

BspCOMInit.StopBits = COM_STOPBITS_1;

BspCOMInit.Parity = COM_PARITY_NONE;

BspCOMInit.HwFlowCtl = COM_HWCONTROL_NONE;

if (BSP_COM_Init(COM1, &BspCOMInit) != BSP_ERROR_NONE)

{

Error_Handler();

}

 

/* USER CODE BEGIN BSP */

 

/* -- Sample board code to send message over COM1 port ---- */

printf("Welcome to STM32 world !\n\r");

 

/* -- Sample board code to switch on leds ---- */

BSP_LED_On(LED_GREEN);

BSP_LED_On(LED_BLUE);

BSP_LED_On(LED_RED);

 

/* USER CODE END BSP */

 

/* Infinite loop */

/* USER CODE BEGIN WHILE */

HAL_TIM_Base_Start(&htim2);

ADS1256_Reset();

ADS1256_ReadMuxRegister();

ADS1256_SelectChannel();

ADS1256_ReadMuxRegister();

 

uint32_t adcValue = 0;

double Voltage = 0;

 

while (1)

{

ADS1256_SelectChannel();

ADS1256_ReadMuxRegister();

ADS1256_ReadData(&adcValue);

printf("\nADC Value: %d", adcValue);

ConvertToVoltage(adcValue);

Voltage = ConvertToVoltage(adcValue);

printf("\nConverted Voltage: %f\n\n", Voltage);

 

BSP_LED_Toggle(LED_GREEN);

BSP_LED_Toggle(LED_BLUE);

BSP_LED_Toggle(LED_RED);

HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);

delay_us(500000);

 

/* USER CODE END WHILE */

 

/* USER CODE BEGIN 3 */

}

/* USER CODE END 3 */

}

 

But with same flow as in Arduino, I canot stablish communication. Cannot read the registers of the device, nor can I get the output. I am new, so can't guess what is going on. With SPI communication I am using "timer" which is working well and i am blinking LEDs also. Moreover, I am sending data to virtual "COM" which also works. Help is requested in this regard. i can also upload Arduinoi code as well if required.

 
10 REPLIES 10

Welcome to the forum.

Please see How to write your question to maximize your chances to find a solution; in particular, How to insert source code.

 

Have you used an oscilloscope and/or logic analyser to see what's actually happening on the wires?

 


@Aamir1033 wrote:

I can communicate when I am writing my code in Arduino, But with same flow as in Arduino, I cannot stablish communication. .


Please show your schematics for both cases.

What Arduino were you using?

 

Before getting into SPI, have you got a simple blinking LED working on the Nucleo?

And UART output?

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.
Aamir1033
Associate II

Thanks Andrew, for the reply

>>Schematic?

Here is how I am connecting wires in both cases. I don't need to change the wiring or schematic. When uploading through arduino my adc works fine. In both cases I am using SPI3

Aamir1033_0-1745661442823.png

Below is the CubeIDE pin config 

Aamir1033_2-1745662339950.png

What Arduino were you using?

I am using Arduino IDE 2.3.4 and CubeIDe is Version: 1.18.0 Build: 24413_20250227_1633 (UTC).

Unfortunately I haven't connected scope. I am working from home for this project and don't have scope now., but I will arranged that.

Before getting into SPI, have you got a simple blinking LED working on the Nucleo? And UART output?

Yes the LED is blinking and I can see COM port data on my laptop. Even I am blinking led in the same while loop and sending data on COM port where I am reading data from SPI. Only SPI is not working

Below is the brief on what I am doing in Arduino

#include <SPI.h>

#define DRDY_PIN  PC7
#define RST_PIN   PA15//PA15
#define SPI_CS    PD14//PD14
SPIClass SPI_A;
double VREF = 2.5;

void setup()
{
  // put your setup code here, to run once:
  pinMode(PE1,OUTPUT);
  Serial.begin(115200);
  while(!Serial);

  SPI_A = SPIClass(PB5, PB4, PB3);
  Initialize_ADS1256();
}

void loop()
{
  digitalWrite(PE1,HIGH);//LED
  delay(250);
  digitalWrite(PE1,LOW); //LED
  delay(250);
 
  ReadRegister(0x01);

  WriteRegister(0x01, 0x2f);

  ReadSingle();

}
void Initialize_ADS1256()
{
  pinMode(SPI_CS, OUTPUT);
  digitalWrite(SPI_CS, LOW);
  pinMode(RST_PIN, OUTPUT);
  pinMode(DRDY_PIN, INPUT);

  SPI_A.begin();

  digitalWrite(RST_PIN, LOW);
  delay(500);
  digitalWrite(RST_PIN, HIGH);
  delay(500);
}
   How to insert source code. By the way this link is not working
Aamir1033
Associate II

 

CubeIDE which is not working is attached, while Ardiuono code is pasted below.

#include <SPI.h>

#include <SPI.h>

#define DRDY_PIN  PC7
#define RST_PIN   PA15//PA15
#define SPI_CS    PD14//PD14
SPIClass SPI_A;
double VREF = 2.5;

void setup()
{
  // put your setup code here, to run once:
  pinMode(PE1,OUTPUT);
  Serial.begin(115200);
  while(!Serial);

  SPI_A = SPIClass(PB5, PB4, PB3);
  Initialize_ADS1256();
}

void loop()
{
  digitalWrite(PE1,HIGH);
  delay(250);
  digitalWrite(PE1,LOW);
  delay(250);
  //Serial.println("BismiALLAH");
  // put your main code here, to run repeatedly:
 // Initialize_ADS1256();
  ReadRegister(0x01);

  WriteRegister(0x01, 0x2f);

  ReadSingle();

}

void Initialize_ADS1256()
{
  pinMode(SPI_CS, OUTPUT);
  digitalWrite(SPI_CS, LOW);
  pinMode(RST_PIN, OUTPUT);
  pinMode(DRDY_PIN, INPUT);

  SPI_A.begin();

  digitalWrite(RST_PIN, LOW);
  delay(500);
  digitalWrite(RST_PIN, HIGH);
  delay(500);
}

unsigned long ReadRegister(uint8_t registerAddress) //Function for READING a selected register
{
  unsigned long RegisterValue = 0;
  unsigned int DRDY_State = 1;
 
  while (DRDY_State)
  {
    DRDY_State = digitalRead(DRDY_PIN);
  } //Wait while Data Ready pin is low

  SPI_A.beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1));
  digitalWrite(SPI_CS, LOW);
  SPI_A.transfer(0x10 | registerAddress);
  SPI_A.transfer(0x00);

  delayMicroseconds(5);

  RegisterValue = SPI_A.transfer(0xff);

  digitalWrite(SPI_CS, HIGH);

  SPI_A.endTransaction();

  Serial.println("Register Value of " + String(registerAddress) + " = " + String(RegisterValue));

  return (RegisterValue);
}

void WriteRegister(uint8_t registerAddress, uint8_t registerValueW)
{
   unsigned int DRDY_State = 1;
 
  while (DRDY_State)
  {
    DRDY_State = digitalRead(DRDY_PIN);
  } //Wait while Data Ready pin is low

  SPI_A.beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1));
  digitalWrite(SPI_CS, LOW);
  SPI_A.transfer(0x50 | registerAddress);
  SPI_A.transfer(0x00);

  delayMicroseconds(5);
  SPI_A.transfer(registerValueW);

  digitalWrite(SPI_CS, HIGH);

  SPI_A.endTransaction();
}

void ReadSingle()
{
  unsigned int RegisterData = 0;
  unsigned int DRDY_State = 1;
 
  while (DRDY_State)
  {
    DRDY_State = digitalRead(DRDY_PIN);
  } //Wait while Data Ready pin is low

  SPI_A.beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1));
  digitalWrite(SPI_CS, LOW);
  SPI_A.transfer(0x01);
  delayMicroseconds(10);

  RegisterData = SPI_A.transfer(0x0f);
  RegisterData <<= 8;

  RegisterData |= SPI_A.transfer(0x0f);
  RegisterData <<= 8;

  RegisterData |= SPI_A.transfer(0x0f);

  RegisterData |= SPI_A.transfer(0x0f);
  Serial.println("Consverted Value =" + String(RegisterData));
  ConvertToVoltage(RegisterData);
 
  digitalWrite(SPI_CS, HIGH);

  SPI_A.endTransaction();  
 
}

void ConvertToVoltage(int32_t registerData)
{
  double Voltage = 0;
  if (long minus = registerData >> 23 == 1) //if the 24th bit (sign) is 1, the number is negative
    {
      registerData = registerData - 16777216;  //conversion for the negative sign
      //"mirroring" around zero
    }

    Voltage = ((2*VREF) / 8388608)*registerData; //2.5 = Vref; 8388608 = 2^{23} - 1

    //Basically, dividing the positive range with the resolution and multiplying with the bits  
   
    Serial.println("Voltage = " + String(Voltage,8)); //print it on serial, 8 decimals    //Serial.println("Consverted Value =" + String(RegisterData));
    Serial.println();
}
Pavel A.
Evangelist III

How to insert source code - STMicroelectronics Community

Here you can find help and guidance how to convert your arduino project to "native" STM32, with or without HAL library. Whatever you prefer.

 

 


@Aamir1033 wrote:
   How to insert source code. By the way this link is not working

Sorry.

But it is covered in the  How to write your question to maximize your chances to find a solution link.

The correct link is:

https://community.st.com/t5/community-guidelines/how-to-insert-source-code/ta-p/693413 

 


@Aamir1033 wrote:

What Arduino were you using?

I am using Arduino IDE 2.3.4 and CubeIDe is Version: 1.18.0 Build: 24413_20250227_1633 (UTC).

 

I meant what Arduino board are you using.

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.
Aamir1033
Associate II

>>But it is covered in the  How to write your question to maximize your chances to find a solution link.

Yes, I got that. I will try to follow you next time.

>>I meant what Arduino board are you using.

My apologies. My board is NUCLEO-H753ZI.

 


@Aamir1033 wrote:

>>I meant what Arduino board are you using.

My apologies. My board is NUCLEO-H753ZI.


So you are loading an Arduino core onto the Nucleo board ?

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.
Aamir1033
Associate II

>>So you are loading an Arduino core onto the Nucleo board ?

I am new to STM and Arduino and not very familiar with the terminology. For me, loading the Arduino core means I selected my board in Arduino IDE and am uploading my program through COM. 

If anything else I have missed, please elaborate. 

"Arduino" can refer to many things

  • A physical board,
  • The Arduino IDE,
  • The Arduino "ecosystem" in general

The Arduino "core" is the code that needs to be loaded into the Target chip in order for it to be programmable via the COM port, using the Arduino IDE.

So are you saying that you are programming your Nucleo board using the Arduino IDE ?

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.