cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 SPI Master Receiving

AE104
Senior

Hello,

On my custom design board, I use external 12 bit ADC (ADS7886) and STM32F767VI. I try to get digitized ADC values with SPI interface. I set the SPI as Receive only master than prescaler as 8; baudrate as 13.5 Mbits/s; polarity as 1; phase as 1; data size as 16 bits; MSB.

My C code in Keil is

uint16_t ADC_Buf;

if(Rx_flag)

{

HAL_GPIO_WritePin(ADC_CS_GPIO_Port, ADC_CS_Pin, GPIO_PIN_RESET);

HAL_SPI_Receive(&hspi4, (uint8_t*)&ADC_Buf,2,100);

volt = (float)(ADC_Buf * 5 / pow(2,12)); // 

HAL_GPIO_WritePin(ADC_CS_GPIO_Port, ADC_CS_Pin, GPIO_PIN_SET);

Rx_flag = 0;

}

I enabled SPI global interrupt. Then I set a timer. Timer frequency is at least 10 times bigger frequency than the input signal frequency. Every each interrupt of the timer, a flag is active then transmission happen. But I didn't plot in STM Studio and observe in debugger mode successfully yet. For example, now my input signal frequency is 1.96kHZ and I set the timer as 20kHz.

Do you have any idea to solve this problem?

Thank you,

5 REPLIES 5

Maybe you want to take one step at a time.

Starting with basic blinky, then with PWM, determining proper timing, etc.

JW

S.Ma
Principal

If in your mind spi master means you are in control of the sck clock generation, then only spi full duplex bi directional 4 wire shall meet expectations.

AE104
Senior

Actually, the number of clk (yellow) is around 48 counts. It should be 16 numbers of clk during data transmission based on the datasheet. So why I get 48 counts and how can i get 16 of them?

Just don't use the Receive-only mode. It immediately starts to generate clocks as soon as you enable it, and it won't stop until you disable it.

Use normal duplex mode as KIC/HD said above; you don't need to bring out MOSI to a pin.

JW

AE104
Senior

I modified SPI mode as full duplex master. Then I make it pull down of MOSI pin. I correctly read a step signal such as 2.3V fed signal to the ADC. But when I feed biphasic signal. I can only read maximum value of the signal. Then I modified my code a little bit such as

uint8_t ADC_Buf[2]; 

float testdata_in[16];

uint8_t i=0;

uint16_t ADC_Buf_Val = 0;

uint16_t Sample;

float volt = 0;

void ADC_Conversion_of_Voltage_Transients()

{

HAL_GPIO_WritePin(ADC_CS_GPIO_Port, ADC_CS_Pin, GPIO_PIN_RESET);

HAL_SPI_Receive(&hspi4,ADC_Buf,2,100);

HAL_GPIO_WritePin(ADC_CS_GPIO_Port, ADC_CS_Pin, GPIO_PIN_SET);

Sample = (((uint16_t) ADC_Buf[1]) << 8 | ADC_Buf[0]);

//Sample = 0x0 << 12 | ADC_Buf;

volt = (float)(Sample * (5.0 / 4096.0)); // 

testdata_in[i++]=volt;

i %= 16;

}

/* SPI4 init function */

static void MX_SPI4_Init(void)

{

 /* SPI4 parameter configuration*/

 hspi4.Instance = SPI4;

 hspi4.Init.Mode = SPI_MODE_MASTER;

 hspi4.Init.Direction = SPI_DIRECTION_2LINES;

 hspi4.Init.DataSize = SPI_DATASIZE_16BIT;

 hspi4.Init.CLKPolarity = SPI_POLARITY_LOW;

 hspi4.Init.CLKPhase = SPI_PHASE_2EDGE;

 hspi4.Init.NSS = SPI_NSS_SOFT;

 hspi4.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;

 hspi4.Init.FirstBit = SPI_FIRSTBIT_MSB;

 hspi4.Init.TIMode = SPI_TIMODE_DISABLE;

 hspi4.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

 hspi4.Init.CRCPolynomial = 7;

 hspi4.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;

 hspi4.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;

 if (HAL_SPI_Init(&hspi4) != HAL_OK)

 {

  _Error_Handler(__FILE__, __LINE__);

 }

}