+ Post New Thread
Page 2 of 2 FirstFirst 1 2
Results 21 to 39 of 39
  1. #21
    Junior Member level 2
    Points: 319, Level: 3

    Join Date
    Aug 2018
    Posts
    20
    Helped
    0 / 0
    Points
    319
    Level
    3

    Re: 12 Bit ADC with interfacing SPI in STM32

    Actually, I couldn't read the correct values with 'volt' variables.

    I want to share my code, input signal, and ADC signals. I miss something because the 'volt' shows different values than input signal amplitudes.

    Function code:

    Code:
    uint8_t i;
    uint16_t Sample;
    float volt=0;
    uint8_t ADC_Buf[2]; 
    float testdata_in[16];
    
    uint8_t spidata[2];
    
    
    void ADC_Conversion_of_Voltage_Transients()
    {
    		spidata[0]=0x00;       // Set everything up  before you start the exchange
    		spidata[1]=0x00;
    		HAL_GPIO_WritePin(ADC_CS_GPIO_Port, ADC_CS_Pin, GPIO_PIN_RESET);
    		HAL_SPI_TransmitReceive(&hspi4,spidata,ADC_Buf,1,100);   // See below
    		HAL_GPIO_WritePin(ADC_CS_GPIO_Port, ADC_CS_Pin, GPIO_PIN_SET);
    		Sample = (((uint16_t) ADC_Buf[1]) << 8 | ADC_Buf[0]);
    		volt = (float)(Sample * (5.0 / 4096.0)); //
    		testdata_in[i++]=volt;
    		i %= 16;
    	
    }

    ADC SCK (green plot), ADC CS (yellow plot), and ADC SDO (blue plot)

    Click image for larger version. 

Name:	IMG_5727.jpg 
Views:	3 
Size:	517.8 KB 
ID:	155997


    Input signal is
    Click image for larger version. 

Name:	IMG_5729.jpg 
Views:	3 
Size:	505.7 KB 
ID:	155999

    The 'volt' variable result is
    Click image for larger version. 

Name:	IMG_5730.jpg 
Views:	2 
Size:	478.1 KB 
ID:	156000



    •   AltAdvertisement

        
       

  2. #22
    Super Moderator
    Points: 78,412, Level: 68
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    15,910
    Helped
    3610 / 3610
    Points
    78,412
    Level
    68

    Re: 12 Bit ADC with interfacing SPI in STM32

    Hi,

    From post to post you change multiple things but donīt show us. This makes it really hard to find out what you try to do.

    * Now the SCK frequency is about 16MHz. This should be OK.
    * But again you work with 5V ADC (data signal voltage). Tis probably violates STM input specifications.
    * We canīt find out your sample rate

    Btw: Do you recognize how slow the HAL lib works: Just setting NSS LOW takes longer than the complete ADConversion and data transmision. And taking NSS HIGH is really booring slow. It takes three sampling times.

    ***Scope pictures:
    * If you want to verify sampling rate you need a scope view with at least twho falling NSS edges.
    * If you want to do a raw chekc on ADC signals your upper scope picture of post#21 is good
    * if you want to verify data, then you need a more detailed view with focus on all the clock edges and data

    ****
    Every time when you modify the setup, then please show us the setup code.

    ****
    The yellow signal of the second scope view:
    I still donīt know what to do with this. I donīt know if you think this signal is correct or not. ..from timing, waveform, noise and voltage levels.
    Please give more detailed information.

    ****
    I miss something because the 'volt' shows different values than input signal amplitudes.
    Please tell us what "volt levels" you expect. In numbers. Best if you can give a range.

    And .. since the conversion result depends on ADC_VCC.... please measure it with a DVM when ADC is running. Also verify that the VCC signal is very clean during vonversion.

    Klaus
    Please donīt contact me via PM, because there is no time to respond to them. No friend requests. Thank you.



  3. #23
    Junior Member level 2
    Points: 319, Level: 3

    Join Date
    Aug 2018
    Posts
    20
    Helped
    0 / 0
    Points
    319
    Level
    3

    Re: 12 Bit ADC with interfacing SPI in STM32

    Let's finalize this post.

    I isolate the analog input signal of ADC from the circuit, by then I connect this pin to the function generator output which generates 1kHz with 520mV peak to peak sine wave signal. I also changed supply voltage of ADC to 3.3V.

    Click image for larger version. 

Name:	IMG_5733.jpg 
Views:	2 
Size:	511.2 KB 
ID:	156001

    I get the plot for ADC SCK (yellow plot), ADC CS (green plot) and ADC SDO (blue plot).

    Click image for larger version. 

Name:	IMG_5734.jpg 
Views:	2 
Size:	515.8 KB 
ID:	156002

    Please tell us what "volt levels" you expect. In numbers. Best if you can give a range.
    I expect that the values of 'volt' change between 0 and 0.52V. But in Keil debug mode, the 'volt' values in the 'watch window' is different than this values.

    Click image for larger version. 

Name:	test out 10 11 19.PNG 
Views:	3 
Size:	85.3 KB 
ID:	156003

    Here is my code:

    Code:
    void ADC_Conversion_of_Voltage_Transients()
    {
    
    		
    		spidata[0]=0x00;       // Set everything up  before you start the exchange
    		spidata[1]=0x00;
    		HAL_GPIO_WritePin(ADC_CS_GPIO_Port, ADC_CS_Pin, GPIO_PIN_RESET);
    		HAL_SPI_TransmitReceive(&hspi4,spidata,ADC_Buf,2,100);   // See below
    		HAL_GPIO_WritePin(ADC_CS_GPIO_Port, ADC_CS_Pin, GPIO_PIN_SET);
    		Sample = (((uint16_t) ADC_Buf[1]) << 8 | ADC_Buf[0]) & 0x0FFF;
    		volt = (float)(Sample * (5.0 / 4096.0)); //
    		testdata_in[i++]=volt;
    		i %= 16;
    }

    SPI settings:

    Code:
    /* 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_HIGH;
      hspi4.Init.CLKPhase = SPI_PHASE_2EDGE;
      hspi4.Init.NSS = SPI_NSS_SOFT;
      hspi4.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
      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__);
      }
    
    }
    I try to implement NSS enable with Hardware output. But I didn't observe any signal at ADC CS. IF you refer any source, I will definitely implement it.

    Thank you



  4. #24
    Super Moderator
    Points: 78,412, Level: 68
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    15,910
    Helped
    3610 / 3610
    Points
    78,412
    Level
    68

    Re: 12 Bit ADC with interfacing SPI in STM32

    Hi,

    Important: if you choose the ADC supply voltage to 3.3V, then you need to change your mathematics, too:
    --> volt = (float)(Sample * (3.3 / 4096.0)); //

    I'm no friend of guessing. Now with none of your scope pictures I can verify binary code of the ADC.
    Thus I can't be sure at which clock edge tge data transfer occurs.
    Change the following line to react on first clock edge (as already suggested in my first post)
    --> hspi4.Init.CLKPhase = SPI_PHASE_2EDGE;

    ********
    I try to implement NSS enable with Hardware output. But I didn't observe any signal at ADC CS. IF you refer any source, I will definitely implement it.
    I don't see how you did it...thus I have to guess:
    --> Did you change to following line from SOFT(-ware controlled)to HARD(-ware controlled)? (As suggested in my first post)
    --> Did you connect a pullup to the NSS line? (As suggested in my first post)

    Klaus
    Please donīt contact me via PM, because there is no time to respond to them. No friend requests. Thank you.



  5. #25
    Junior Member level 2
    Points: 319, Level: 3

    Join Date
    Aug 2018
    Posts
    20
    Helped
    0 / 0
    Points
    319
    Level
    3

    Re: 12 Bit ADC with interfacing SPI in STM32

    --> Did you change to following line from SOFT(-ware controlled)to HARD(-ware controlled)? (As suggested in my first post)
    --> Did you connect a pullup to the NSS line? (As suggested in my first post)
    Yes I enabled NSS with Hardware output in CubeMX and pulled-up CS pin.

    Code:
    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_HIGH;
      hspi4.Init.CLKPhase = SPI_PHASE_1EDGE;
      hspi4.Init.NSS = SPI_NSS_HARD_OUTPUT;
      hspi4.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
      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__);
      }
    
    }

    Click image for larger version. 

Name:	spi push pull.PNG 
Views:	2 
Size:	28.2 KB 
ID:	156004

    Code:
    void ADC_Conversion_of_Voltage_Transients()
    {
    		spidata[0]=0x00;       // Set everything up  before you start the exchange
    		spidata[1]=0x00;
    	
    		HAL_SPI_TransmitReceive(&hspi4,spidata,ADC_Buf,1,100);   // See below
    		
    		Sample = (((uint16_t) ADC_Buf[1]) << 8 | ADC_Buf[0]) & 0x0FFF;
    		volt = (float)(Sample * (3.3 / 4096.0)); //
    		testdata_in[i++]=volt;
    		i %= 16;
    I also updated the formula. When I run with NSS enabled with Hardware output, ADC CS keeps every time in reset position.



    •   AltAdvertisement

        
       

  6. #26
    Super Moderator
    Points: 78,412, Level: 68
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    15,910
    Helped
    3610 / 3610
    Points
    78,412
    Level
    68

    Re: 12 Bit ADC with interfacing SPI in STM32

    Hi,

    Yes I enabled NSS with Hardware output in CubeMX and pulled-up CS pin.
    You need to externally solder a pull up resistor.
    (Enabling pull up with CubeMX is "internal" .... which I think does not work)

    Klaus
    Please donīt contact me via PM, because there is no time to respond to them. No friend requests. Thank you.



  7. #27
    Junior Member level 2
    Points: 319, Level: 3

    Join Date
    Aug 2018
    Posts
    20
    Helped
    0 / 0
    Points
    319
    Level
    3

    Re: 12 Bit ADC with interfacing SPI in STM32

    You need to externally solder a pull up resistor.
    For make more clarification, I drew the existing connection between the stm32 and ADC. I highlighted the pull up resistor. Do you think its true configuration and resistor value? Now the SPI works full duplex master mode so is it also true?

    Click image for larger version. 

Name:	spi.png 
Views:	2 
Size:	66.2 KB 
ID:	156042



  8. #28
    Super Moderator
    Points: 78,412, Level: 68
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    15,910
    Helped
    3610 / 3610
    Points
    78,412
    Level
    68

    Re: 12 Bit ADC with interfacing SPI in STM32

    Hi,

    1k seems to be OK.

    But in detail it depends in:
    * expected speed
    * drive strength of the output pin
    * signal trace length, connected devices (= capacitance)

    The good thing is:
    * the timing critical signal is the falling edge
    * the falling edge mainly is determined by the drive strength

    Check it with a scope.
    If the timing is OK, then it will be even better without the scope probe.
    * falling edge
    * low level
    * rising edge

    Now the SPI works ....
    The receiving values are OK?

    full duplex master mode so is it also true?
    It does not depend on pull up resistor, it just depends on setup in your software.

    ****
    To save processing power and/or increase sample rate I recommend to use DMA.

    Klaus
    Please donīt contact me via PM, because there is no time to respond to them. No friend requests. Thank you.



  9. #29
    Junior Member level 2
    Points: 319, Level: 3

    Join Date
    Aug 2018
    Posts
    20
    Helped
    0 / 0
    Points
    319
    Level
    3

    Re: 12 Bit ADC with interfacing SPI in STM32

    Thank you, Klaus!

    But in detail it depends in:
    * expected speed
    * drive strength of the output pin
    * signal trace length, connected devices (= capacitance)
    Just my curiosity, could you briefly describe this part of your message?

    I capture the ADC SCK (green), ADC SDO (blue), and ADC CS (yellow) signals. I measured the rising and falling edge for CS signal.

    Click image for larger version. 

Name:	test sck(gree) sdo(blue) and CS (yellow) with rising and falling edge 2019-10-15 12-17-52 0.png 
Views:	3 
Size:	17.7 KB 
ID:	156058

    For calculating sampling rate, I added the figure with multiple CS and SCK signal together.

    Click image for larger version. 

Name:	test sck(gree) sdo(blue) and CS (yellow) with freq and period 2019-10-15 12-24-44 0.png 
Views:	3 
Size:	29.1 KB 
ID:	156059

    So, based on the graphics, the conversion time (tconv) is 1.2us. The sampling rate is (13.5Mbits/s)/16=843.75ksample/s. So these calculations are true?

    The conversion works successfully for a step signal input. I fed 2.6V and I observe 2.57V from 'volt' values during the debug session. Now I will try sine wave and then see it. I will update the post with the results what I get.

    Click image for larger version. 

Name:	test volt 10 15 19.PNG 
Views:	3 
Size:	80.6 KB 
ID:	156062
    Last edited by Alpaslan_Ersoz; 15th October 2019 at 19:08.



    •   AltAdvertisement

        
       

  10. #30
    Junior Member level 2
    Points: 319, Level: 3

    Join Date
    Aug 2018
    Posts
    20
    Helped
    0 / 0
    Points
    319
    Level
    3

    Re: 12 Bit ADC with interfacing SPI in STM32

    I fed the my main signal to the ADC input. I observe the conversion of the signal of mid level (1.95V) as 'volt' value in the debug session. I don't know how long should I wait to see low level (1.628V) and high level (2.288V) of the signal in the watch window as output of the conversion in 'volt' variable?

    Actually, I place two breakpoints on the sequential commands in the while loop. Then I debug it and record each break point debug session time.

    Click image for larger version. 

Name:	time.PNG 
Views:	0 
Size:	116.6 KB 
ID:	156064

    I highlighted the time value where I recorded it. Then I subtracted between of them. So I get 1 ms difference. Then, There are 9 functions in the while loop and total numbers of line from these 9 functions is 299. So 299x1ms= 300ms. It means that I should wait 300ms for each sampling?

    This is the input signal.

    Click image for larger version. 

Name:	input signal 10 15 19 2019-10-15 14-24-39 0.png 
Views:	2 
Size:	20.0 KB 
ID:	156068



  11. #31
    Super Moderator
    Points: 78,412, Level: 68
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    15,910
    Helped
    3610 / 3610
    Points
    78,412
    Level
    68

    Re: 12 Bit ADC with interfacing SPI in STM32

    Hi,

    Your scope picture (especially the upper one of post#29) is awful. Don't you recognize that the sampling rate is much too low for your signals. The SCK looks far away from being a square wave. You can't measure rise and falltime this way.

    So, based on the graphics, the conversion time (tconv) is 1.2us. The sampling rate is (13.5Mbits/s)/16=843.75ksample/s. So these calculations are true?
    Although I can't follow your idea, I can say it is completely wrong.
    The sampling period is somewhere below 600us.
    You can simply read the sampling frequency in the scope picture: 1.7311kHz.

    Just my curiosity, could you briefly describe this part of your message?
    Simply every piece of trace is a capacitance, every input is a capacitance...now you want a to charge/discharge this capacitance.
    It needs to be fast enough to meet the specified timing of the ADC.
    But the faster ... the more current you need. The current has to be delivered by the pullup (rising edge) or the I/O driver (falling edge).

    Klaus

    - - - Updated - - -

    Hi,

    I don't know how long should I wait to see
    Sorry, I really don't understand what you tell in post#30.

    You ask: "how long should I wait"...
    In my eyes it's currently much too slow, you need to get faster rather than slower.

    Klaus
    Please donīt contact me via PM, because there is no time to respond to them. No friend requests. Thank you.



  12. #32
    Junior Member level 2
    Points: 319, Level: 3

    Join Date
    Aug 2018
    Posts
    20
    Helped
    0 / 0
    Points
    319
    Level
    3

    Re: 12 Bit ADC with interfacing SPI in STM32

    Hello Klaus,

    You can simply read the sampling frequency in the scope picture: 1.7311kHz.
    How can I change it?

    The SCK looks far away from being a square wave
    If I set the SPI baudrate as around 1Mbits/s, the clock signal shape looks rectangular.

    Thank you,



  13. #33
    Super Moderator
    Points: 78,412, Level: 68
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    15,910
    Helped
    3610 / 3610
    Points
    78,412
    Level
    68

    Re: 12 Bit ADC with interfacing SPI in STM32

    Hi,

    How can I change it?
    read my previous posts

    If I set the SPI baudrate as around 1Mbits/s, the clock signal shape looks rectangular.
    that's the wrong way round

    Klaus
    Please donīt contact me via PM, because there is no time to respond to them. No friend requests. Thank you.



  14. #34
    Junior Member level 2
    Points: 319, Level: 3

    Join Date
    Aug 2018
    Posts
    20
    Helped
    0 / 0
    Points
    319
    Level
    3

    Re: 12 Bit ADC with interfacing SPI in STM32

    Hi,

    read my previous posts
    --> /CS = NSS needs to toggle!
    So, I set a timer (TIM4) with internal clock in interrupt mode. I verified it with one of the GPIO pin (TIM_CRTL) which has 10kHz. Then I set a flag which will be '1' when the interrupt happens. I placed this flag in to while loop during calling the conversion function.

    Calling function:

    Code:
    while(1)
    {
    
    if(Timer_Flag)
    		{
    			ADC_Conversion_of_Voltage_Transients();
    			Timer_Flag=0;
    		}
    }
    Main function:

    Code:
    void ADC_Conversion_of_Voltage_Transients()
    {
    		spidata[0]=0x00;       // Set everything up  before you start the exchange
    		spidata[1]=0x00;
    		HAL_SPI_TransmitReceive(&hspi4,ADC_Buf,ADC_Buf,1,100);   // See below
    		Sample = (((uint16_t) ADC_Buf[1]) << 8 | ADC_Buf[0]) & 0x0FFF;
    		volt = (float)(Sample * (3.3 / 4095.0)); //
    		testdata_in[i++]=volt;
    		i %= 16;
    }


    Timer IRQ:

    Code:
    void TIM4_IRQHandler(void)
    {
      /* USER CODE BEGIN TIM4_IRQn 0 */
    
      /* USER CODE END TIM4_IRQn 0 */
      HAL_TIM_IRQHandler(&htim4);
      /* USER CODE BEGIN TIM4_IRQn 1 */
    	HAL_GPIO_TogglePin(TIM_CRTL_GPIO_Port, TIM_CRTL_Pin);
    	Timer_Flag=1;
    	
      /* USER CODE END TIM4_IRQn 1 */
    }
    But the sampling frequency did not change.



  15. #35
    Super Moderator
    Points: 78,412, Level: 68
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    15,910
    Helped
    3610 / 3610
    Points
    78,412
    Level
    68

    Re: 12 Bit ADC with interfacing SPI in STM32

    Hi,

    Please read all my posts...especially those with "sampling rate" and what is meant with "toggle NSS".
    It's all written already.

    Klaus
    Please donīt contact me via PM, because there is no time to respond to them. No friend requests. Thank you.



    •   AltAdvertisement

        
       

  16. #36
    Junior Member level 2
    Points: 319, Level: 3

    Join Date
    Aug 2018
    Posts
    20
    Helped
    0 / 0
    Points
    319
    Level
    3

    Re: 12 Bit ADC with interfacing SPI in STM32

    Hi,

    I am sorry I couldn't catch it. If you explain again, I will happy with that. Otherwise, thank you very much so far for your help!

    Thank you,



  17. #37
    Junior Member level 2
    Points: 319, Level: 3

    Join Date
    Aug 2018
    Posts
    20
    Helped
    0 / 0
    Points
    319
    Level
    3

    Re: 12 Bit ADC with interfacing SPI in STM32

    Hi Klaus,

    It depends on how often you toggle /CS .... and read the conversion data.
    But hopefully you don't try to use te run time of the main loop for sampling timing control.
    --> You need at least an Interrupt with fixed, known timing. Or let the hardware (timer) directly start the conversion (without tge need fir an ISR)
    If you are running low on processing power, then I recommend to use SPI in DMA mode.

    If you want a 10kHz sampling rate, then you need a falling edge every 100us.
    .. but for sure after the falling /CS edge you need to go on according interface specification:
    At least 16 SCK cycles to perform the data transfer.
    And after this you need to set /CS high.
    Today, I try again to figure out the sampling rate based on your comments. These are all sampling rate related comments of yours. So based on that I would use SPI DMA mode instead of timer interrupt for setting sampling frequency?



  18. #38
    Advanced Member level 4
    Points: 7,866, Level: 21

    Join Date
    Jan 2015
    Posts
    1,105
    Helped
    347 / 347
    Points
    7,866
    Level
    21

    Re: 12 Bit ADC with interfacing SPI in STM32

    Quote Originally Posted by Alpaslan_Ersoz View Post
    So based on that I would use SPI DMA mode instead of timer interrupt for setting sampling frequency?
    I think you are getting a number of concepts mixed up here.

    1) Sampling rate: You will need a timer to reliably trigger the ADC sampling at a regular interval.
    The way to tell the ADC to start sampling is to start an SPI exchange - and that means lowering the \CS line.

    2) SPI clock rate: how fast the MCU exchanges values with the ADC via the SPI interface
    Once you lower the \CS line, you need to perform a 16-bit value exchange and that means setting up the SPI module to exchange a single 16-bit value. Once the SPI module has been triggered, it will then send the 16 SCK pulses. Once the value has been exchanged, you need to raise the \CS line

    3) Possible interactions between 1) and 2): how to coordinate the \CS line transitions and the SPI exchange
    There are two ways you can achieve this coordination (which is necessary to correctly get the ADC value). Firstly you can control the \CS line yourself - that means in your code you:
    - lower the \CS line
    - start the SPI exchange
    - wait for the SPI exchange to complete
    - raise the \CS line
    The alternative way is to configure the SPI module to control the NSS signal. The SPI module uses the term NSS (Negative Slave Select) but it effectively means the same as the \CS (Negated Chip Select) name we have been using. IN both cases the 'Negative' refers to the fact that you take to line low (logical 0) when it is active.
    I don't recommend the alternative way at this stage - you seem to have enough trouble with the basics of SPI and the operation of the ADC and the ST implementation of the NSS signal can (in my experience) be a little tricky to get right. I mention it only so you know what the NSS signal that is mentioned in the HAL is and how to set it correctly - come back to this later once everything else is working.

    4) Saving the value: use the value you have received from the ADC
    Especially if you are controlling the \CS line yourself (as indicated in the code snippets you have provided), then it is easy to know when the exchange has completed so that you can read the value from the SPI module that has just been received. Basically this is what you have been doing in your code so far.
    The alternative is to use DMA which is hardware built into the MCU that transfers the value from the SPI module (in this case) to an array in memory for you. The big advantage of using DMA is that it does not use the main CPU so that your code can be doing something else while the hardware is handling the ADC data.
    You can set up the DMA to set a flag/trigger an interrupt when it has transferred a set number of values for you. Only then do you need to look at the values in the array and do something with them.

    Now, the DMA *can* do something else for you as well and this is where some of the confusion about the sample timing can come in. The DMA controller can also be set up to trigger the SPI module to stat an exchange. There are a couple if things you need to understand about this way of working. The first is that you MUST set up the SPI module to control the NSS single itself as the hardware has to do everything - no software is involved and so you cannot control the \CS line yourself.
    The other is how the DMA controller knows to trigger the next transfer. Typically the DMA controller is used to transfer values from one place to another as quickly as possible which means that it will normally trigger the next transfer as soon as the last one finishes. In your case this is NOT what you want as you want the ADC to be triggered by the SPI exchange at a specific interval and not just as fast as it can possibly go.
    I've not looked in detail at the DMA controller on your MCU but sometimes you can set the DMA controller to be triggered by some external source - such as your timer.
    I've left this part to last because, while it is all possible, I would strongly recommend that you get the basics of communicating with the ADC running in code first. Once that is working then you can build up the rest of the application code. If/When you are dong that, you find that there is too much else going on that upsets the proper timing of the ADC reads, then you can (step by step) mode to a more hardware-managed way of doing things.
    Susan



  19. #39
    Super Moderator
    Points: 78,412, Level: 68
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    15,910
    Helped
    3610 / 3610
    Points
    78,412
    Level
    68

    Re: 12 Bit ADC with interfacing SPI in STM32

    Hi,

    Maybe it's time to start from the beginning ...
    An engineer should start with specifying the requirements (forget about all the ADC and SPI stuff)

    You show several different input signals. They very widely in repeating frequency (at least 900Hz up to 14kHz)
    Now you need to know that this repeating frequency is also called "fundamental frequency".
    But regarding nyquist (and sampling frequency) this fundamental frequency is not what you need to focus on.
    You need to focus on the overtones.
    You - as the designer - need to decide up to which overtone you are interested in.
    Mainly this depends on what information of the signal you are interested in.
    Informations can be:
    * average voltage
    * RMS voltage
    * minimum / maximum (@ which time resolution)
    * rise / fall time
    * SNR
    * frequency analysis
    * scope like picture
    * or many other..

    And then (still before thinking about ADC and SPI) you need to install a suitable low pass filter, also called "anti aliasing filter" to suppress the unwanted high frequencies.
    If you don't suppress them they will cause artefacts on the digital values that can't be safely filtered out....causing fluctuations in your calculated output value. Your result becomes unreliable.

    I assume you need at least a sampling frequency of 15 x fundamental frequency, but maybe even 100 x fundamental frequency is too low, if you are interested in the
    * HF ringing (shown in the scope pictures) or
    * rise/fall rates
    * SNR
    * peak values
    ...

    Btw: most (all?) STM microcontrollers have built in 12 bit ADCs. Why don't you use them?

    Klaus
    Please donīt contact me via PM, because there is no time to respond to them. No friend requests. Thank you.



--[[ ]]--