cancel
Showing results for 
Search instead for 
Did you mean: 

NUCLEO-H753ZI SPI Communication

Aamir1033
Visitor

 

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.

 
4 REPLIES 4

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
Visitor

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
Visitor

 

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.