Pages: 1 2 [3] 4   Go Down
Author Topic: STM32F4  (Read 18061 times)
0 Members and 1 Guest are viewing this topic.
SF Bay Area (USA)
Offline Offline
Tesla Member
***
Karma: 124
Posts: 6654
Strongly opinionated, but not official!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It's common for a microcontroller to have many fewer A-D converters than it has analog pins, with an analog multiplexer in between the pins and the A-D converter.  The Atmel AVR used on the Arduino only has ONE A-D converter, fronted by a 16
:1 analog multiplexer (some of whose inputs are not connected), so that when you do an "analogRead(port)", what actually happens is more like:
Code:
SelectAnalogInput(port);
delay(MUXSETTLETIME);
StartADConversion();
delay(ADCONVERTTIME);
return(readADC();
The  STM32F4 actually has three separate A2D converters, each with an 8:1 mux (and some complex connections to pins that I didn't look into very much.)  So you could read up to three Analog inputs without messing separately with the muxes (except at setup time), or you'll have to do something similar to what the Arduino core SW does.

In general, it is a useful technique in learning a new processor/board to try to COPY (only be sure to call it "port") an existing familiar set of software.  So the question shouldn't be "how do I read analog inputs on STM32F4?", but "How do I duplicated the AnalogRead() function on STM32F4?"   It may seem very similar, but the process is different.  Instead of starting from scratch, you get to look at the steps that the arduino code uses, and figure out whether they have equivalents on the STM.  Since the individual steps are smaller, they may be easier to understand.  Of course, you end up needing to understand both the existing Arduino code AND the new processor code.  But ... it's good for you!
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 131
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
It's common for a microcontroller to have many fewer A-D converters than it has analog pins, with an analog multiplexer in between the pins and the A-D converter.

Yeah that makes perfect financial sense, THE ADC will be relatively expensive so one ADC can be used via a mux to read different pins on the same port

Quote
The  STM32F4 actually has three separate A2D converters, each with an 8:1 mux (and some complex connections to pins that I didn't look into very much.) 


Got that bit the STM32F4 has ADC1 ADC2 ADC3, I dont know much about their associated mux block though

Quote
So you could read up to three Analog inputs without messing separately with the muxes (except at setup time), or you'll have to do something similar to what the Arduino core SW does.

I am reading three separate ADC's but I had to set them up on separate ports, port A port B and portC, I really havent a clue how I could setup the mux so that I can use say three ADC's on one port it just wouldnt work even better would be to use one ADC on one port with three separate pins but I havent a clue how to do that, at the minute I am still on a high because I got an input recognised by the board (dont spoil it!!) the analogue reference is 2.95V and I wish I knew how to change that but for the moment I am happy!


Quote
In general, it is a useful technique in learning a new processor/board to try to COPY (only be sure to call it "port") an existing familiar set of software.  So the question shouldn't be "how do I read analog inputs on STM32F4?", but "How do I duplicated the AnalogRead() function on STM32F4?"   It may seem very similar, but the process is different.  Instead of starting from scratch, you get to look at the steps that the arduino code uses, and figure out whether they have equivalents on the STM.  Since the individual steps are smaller, they may be easier to understand.  Of course, you end up needing to understand both the existing Arduino code AND the new processor code.  But ... it's good for you!

I would be willing to do that in fact I would go as far as to say I would probably enjoy it!,...

trouble is I havent got a clue where I would even start!
Logged

Greenville, IL
Offline Offline
Edison Member
*
Karma: 15
Posts: 1328
Warning Novice on board! 0 to 1 chance of errors!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

  I am glad you are making great progress! I have been following the thread and have learned some from reading it.

 Here is a bit of code from Arduino wiring_analog.c related to analogread :

Code:
int analogRead(uint8_t pin)
{
uint8_t low, high;

#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
if (pin >= 54) pin -= 54; // allow for channel or pin numbers
#else
if (pin >= 14) pin -= 14; // allow for channel or pin numbers
#endif

#if defined(__AVR_ATmega32U4__)
pin = analogPinToChannel(pin);
ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
#elif defined(ADCSRB) && defined(MUX5)
// the MUX5 bit of ADCSRB selects whether we're reading from channels
// 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
#endif
 
// set the analog reference (high two bits of ADMUX) and select the
// channel (low 4 bits).  this also sets ADLAR (left-adjust result)
// to 0 (the default).
#if defined(ADMUX)
ADMUX = (analog_reference << 6) | (pin & 0x07);
#endif

// without a delay, we seem to read from the wrong channel
//delay(1);

#if defined(ADCSRA) && defined(ADCL)
// start the conversion
sbi(ADCSRA, ADSC);

// ADSC is cleared when the conversion finishes
while (bit_is_set(ADCSRA, ADSC));

// we have to read ADCL first; doing so locks both ADCL
// and ADCH until ADCH is read.  reading ADCL second would
// cause the results of each conversion to be discarded,
// as ADCL and ADCH would be locked when it completed.
low  = ADCL;
high = ADCH;
#else
// we dont have an ADC, return 0
low  = 0;
high = 0;
#endif

// combine the two bytes
return (high << 8) | low;
}
Logged


Tacoma, WA
Offline Offline
Full Member
***
Karma: 4
Posts: 192
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

It's common for a microcontroller to have many fewer A-D converters than it has analog pins, with an analog multiplexer in between the pins and the A-D converter.  The Atmel AVR used on the Arduino only has ONE A-D converter, fronted by a 16
:1 analog multiplexer (some of whose inputs are not connected)
I had no idea it worked like this. Your explanation was very enlightening. Thanks.
Logged

Brian from Tacoma, WA
Arduino evangelist - since Dec, 2010.

Offline Offline
Full Member
***
Karma: 1
Posts: 131
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I am glad you are making great progress!

Thanks, I have really gotten into this STM32F4 and I have made some excellent progress in the last few days, I have been learning C as I go and after a fair few hours I have wrote a program which replaced three Uno's with one STM32F4, its a motor drive program to drive a low voltage (30V) prototype inverter which in turn drives a dummy RL load

The program uses an timed interrupt three ADC's and four pins and its quick enough to set the ADC to maximum sample time 480 cycles and calculate the reference on the fly

I initially uploaded the program to the board about three days ago and I hit a few problems but at last smiley-grin it works!!!!!!  smiley-lol YES! I have a nice warm glowing feeling!  smiley-red

The STM does the job pretty fast which gives better results


I took some shots, I need two sinusoidal currents 90 degrees out of phase which is what I get





* DSCF0676.JPG (2289.96 KB, 2832x2128 - viewed 43 times.)
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 131
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Another showing the phase shift


* DSCF0678.JPG (2290.37 KB, 2832x2128 - viewed 22 times.)
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 131
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The PWM is really fast and it works a dream



* DSCF0679.JPG (2328.71 KB, 2832x2128 - viewed 27 times.)
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 131
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Same again


* DSCF0688.JPG (2315.4 KB, 2832x2128 - viewed 29 times.)
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 131
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I was happy with what the three arduinos did

heres a pic


* DSCF0653.JPG (2264.23 KB, 2832x2128 - viewed 18 times.)
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 131
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The Uno can be seen to be slower and I dedicated a complete controller to one phase where the STM32 is now controlling three!


* DSCF0656.JPG (2366.64 KB, 2832x2128 - viewed 31 times.)
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 131
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The Unos pulse width was much bigger hence lots of low order harmonics in the audio spectrum, the higher order harmonics the STM generates will be filtered by the motors windings inductance


* DSCF0657.JPG (2284.78 KB, 2832x2128 - viewed 16 times.)
Logged

Offline Offline
Full Member
***
Karma: 1
Posts: 131
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The programs a bit large to upload here, heres the main while loop of the program

Code:
 while (1)

  {GPIO_ToggleBits(GPIOD, GPIO_Pin_15);


/***************************Main Winding*******************************************************/
    SINWt= sinf(n*Wt);
         IMAINREF= 340*SINWt;

       ADC_SoftwareStartConv(ADC1);
        while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);

            MAINHALL = *ADC1_DATA*2950/4095 - MAINOFFSET;
            IMAIN=(34*MAINHALL/40-2125);
            MAINERR=IMAIN-IMAINREF;
            if(MAINERR<=-2){
             GPIO_ResetBits(GPIOD, GPIO_Pin_9);
            }
          if(MAINERR>=2){
             GPIO_SetBits(GPIOD, GPIO_Pin_9);
            }

/*************************Aux Winding****************************************************/
              COSWt =cosf(n*Wt);
          IAUXREF= 340*COSWt;

                  ADC_SoftwareStartConv(ADC2);
                    while(ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC) == RESET);

                      AUXHALL = *ADC2_DATA*2950/4095 - AUXOFFSET;
                      IAUX=(34*AUXHALL/40-2125);
                      AUXERR=IAUX-IAUXREF;
                        if(AUXERR<=-2){
                         GPIO_ResetBits(GPIOD, GPIO_Pin_13);
                        }
                   if(AUXERR>=2){
                         GPIO_SetBits(GPIOD, GPIO_Pin_13);
                      }

/***************************************************************************************/


  ADC_SoftwareStartConv(ADC3);
   while(ADC_GetFlagStatus(ADC3, ADC_FLAG_EOC) == RESET);

   VIN = *ADC3_DATA;
   int CHANGEHZ = (VIN*22/3390)-(FREFINIT-25);
                  if(CHANGEHZ<=-1 || CHANGEHZ>=1){

                  GPIO_ResetBits(GPIOD, GPIO_Pin_13|GPIO_Pin_11|GPIO_Pin_9);
                  VIN = *ADC3_DATA;
                  FREFINIT= (VIN*22/3390);
                  FREFINIT+= 25;

                  if(FREFINIT>=47)
                    {FREFINIT=47;}

                  if(FREFINIT<=25)
                    {FREFINIT=25;}

                     FREF= FREFINIT;
                     Wt = 157.0796327*FREF/1000000;
                  }

  }





It takes about 31.2us to do all that as I used pin 15 to monitor it

All in all i am loving it, I still have so much more to mess around with and implement but I have the bare bones working its all optional extras from here, I already have the drive able to alter output frequency online which is something I just couldnt manage with the Arduinos


* DSCF0689.JPG (2235.84 KB, 2832x2128 - viewed 31 times.)
« Last Edit: June 15, 2012, 08:14:02 pm by Resinator » Logged

Greenville, IL
Offline Offline
Edison Member
*
Karma: 15
Posts: 1328
Warning Novice on board! 0 to 1 chance of errors!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


 Very impressive! You definitely ran with that STM chip! I have worked some with an Olimex STM32 board that runs the Maple IDE and I was impressed with the speed also. I need to spend more time to get my head around the programming necessary to get the most out of it though.

 If you are needing to move to custom board, here is a link to some hardware designs that a member of the Leaflabs forum has posted.  https://github.com/gbulmer
Logged


Offline Offline
Full Member
***
Karma: 1
Posts: 131
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Its taken me four weeks, Attolic is the best advice ever, I have really gotten to grips with it, by using the ST Link debugger a noob can learn so much about program flow and the C language, I think the next step is a space vector modulation drive (this ones an hysteresis current drive) the board can definitely do it

I love power electronics, I really need to get the facilities to make my own PCB's I dont suppose anyone can advise the best way?
Quote

here is a link to some hardware designs

I clicked the link but I dont understand what it even is?, hardware designs? of a microcontroller board? theres a lot there!
« Last Edit: June 15, 2012, 08:15:06 pm by Resinator » Logged

Greenville, IL
Offline Offline
Edison Member
*
Karma: 15
Posts: 1328
Warning Novice on board! 0 to 1 chance of errors!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


 I should have gave this more specific link that has the Eagle designs. https://github.com/gbulmer/openstm32hw

The readme at the bottom of the page best describes what the files contain.
Logged


Pages: 1 2 [3] 4   Go Up
Jump to: