2025-04-26 2:21 AM
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
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, ®Value, 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.
2025-04-26 2:37 AM
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?
2025-04-26 3:16 AM
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
Below is the CubeIDE pin config
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
2025-04-26 3:34 AM
CubeIDE which is not working is attached, while Ardiuono code is pasted below.
2025-04-26 3:52 AM - edited 2025-04-26 3:54 AM
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.
2025-04-26 12:10 PM
@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.
2025-04-26 12:13 PM
>>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.
2025-04-26 12:15 PM
@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 ?
2025-04-26 12:19 PM
>>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.
2025-04-28 12:23 AM
"Arduino" can refer to many things
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 ?