Stm32 Array Declaration

  1. A boardentry.txt file is generated to ease board declaration. Note that flash size used can be increased by 2k as now all pins are available in the PeripheralPins.c. To decrease it you can redefine the PinMap arrays at sketch level to only provide access to the used pins. See the Wiki custom pinmap array section. This release includes: Add.
  2. More useful Information about STM32 Timers. The Timers of STM32s are numerous, yet very sophisticated and powerful. In general, across the STM32 microcontrollers families, the timer peripherals that have the same name also have the same features set, but there are a few exceptions.
  3. Previously we have tried to do a single conversion of one ADC channel. We were waiting for the ADC result in a loop, which isn’t an effective way of using processor resources. It is better to trigger a conversion and wait for the conversion to complete the interrupt. This way, a processor can do other tasks rather than wait for ADC conversion to complete. This time we will go through another.
  4. Variable arrays. An array is a set of data, stored in consecutive memory locations, beginning at a named address – Declare array name and number of data elements, N – Elements are “indexed”, with indices 0. N -1 int n5; //declare array of 5 “int” values. N3 = 5; //set value of 4 th array element.
  1. Stm32 Array Declaration Tool
  2. Stm32 Array Declaration Codes
  3. Stm32 Array Declaration Form

Previously we have tried to do a single conversion of one ADC channel. We were waiting for the ADC result in a loop, which isn’t an effective way of using processor resources. It is better to trigger a conversion and wait for the conversion to complete the interrupt. This way, a processor can do other tasks rather than wait for ADC conversion to complete. This time we will go through another example to set up more than one channel and read ADC values using interrupt service routine.

How does multichannel ADC conversion works?

The main idea of writing program in C language is to break a bigger problem down into several smaller pieces. Suppose it is necessary to write a program for the microcontroller that is going to measure temperature and show results on an LCD display.

If we need to convert several channels continuously, we need to set up Sequence registers (ADC_SQRx). There are three sequence registers: ADC_SQR1, ADC_SQR2, and ADC_SQR3 where we can set up a maximum of 16 channels in any order. Conversion sequence starts with SQ1[4:0] settings in ADC_SQR3 register. Bits [4:0] hold the number of ADC channels.

All 16 sequence channels can be set up the same way through all SQR registers. Then in the ADC_SQR1 register, there are four bits marked L[3:0] where you can set the number how many times sequence reading will be repeated.

Another thing we will have to take care of is to set up sample time for each channel. As we know, each channel in sequence can be set for different conversion times. The sampling time for each channel can be set up in two registers: ADC_SMPR1 and ADC_AMPR2. There are three bits for each channel in sequence.

If you use a standard peripheral library setting up multichannel ADC becomes an easy task.

Setting up multichannel ADC conversion with DMA write

Let’s write an example where we will read the first 8 ADC channels four times using scan mode. Then we calculate an average value of each channel and later print results on a terminal screen using UART.

Stm32 Array Declaration

We will write ADC values to memory by using a DMA channel. Once all data is stored in memory, a DMA transfer complete interrupt will be generated to trigger averaging and output. In the STM32F100x datasheet, we find that ADC pins are assigned alternate functions as follows:

Stm32
  • ADC1_IN0 – PA0
  • ADC1_IN1 – PA1
  • ADC1_IN2 – PA2
  • ADC1_IN3 – PA3
  • ADC1_IN4 – PA4
  • ADC1_IN5 – PA5
  • ADC1_IN6 – PA6
  • ADC1_IN7 – PA7
  • ADC1_IN8 – PB0
  • ADC1_IN9 – PB1
  • ADC1_IN10 – PC0
  • ADC1_IN11 – PC1
  • ADC1_IN12 – PC2
  • ADC1_IN13 – PC3
  • ADC1_IN14 – PC4
  • ADC1_IN15 – PC5

We will need to set up pins A0 to A7 as analog inputs for the first eight channels. Then we can set up an ADC conversion mode. Also, we need to set up Scan Conversion Mode to go through all channels selected in ADC1_SQRx registers. In the peripheral library, this looks like:

Then we must enable to enable continuous conversion mode as we want to cycle through channel list several times:

DeclarationStm32 array declaration code

Then we indicate the number of channels to be converted in scan mode:

The next thing is to indicate which channels and what order we need to convert. For this, we set up each channel individually with commands:

I’ve chosen to go all eight channels in the row from 0 to 7. But you can mess up the numbers as you like. The rest is to set up DMA where it copies ADC values to memory on each EOC event. After DMA copies a predefined number of values, it generates an interrupt. Then we can manipulate data as we like. As in our example, we average multiple instances.

This is a result on the terminal screen.

You can hook up a potentiometer or any other analog sensor to each channel to see its ADC value.

Stm32 Array Declaration Tool

Working C code of multichannel ADC

Stm32 Array Declaration Codes

Here is the complete main source code if you would like to analyze or use fragments for your purposes:

Also, you can download project files [STM32DiscoveryADC_DMAmultiple.zip] that compile with Codebench GCC and Eclipse.

In any microcontroller there is at least one general purpose input-output port. STM32 is a not different breed and as expected it also has several GPIO ports. These ports are usually named GPIOA, GPIOB, etc. but unlike most 8/16-bit micros these ports are 16 bit wide. Thus, in general, every port has 16 IO pins. Port pins have several modes of operation and this is what that makes them both robust and complex at first. In development boards the IO port pin naming is cut short and so we’ll find PA0, PB12, etc. instead of GPIOA0, GPIOB12, etc. Even in the reference manuals this short naming is used widely. In the end every I/O pin is general purpose in nature.

Key points with STM32’s GPIO

  • Upon any reset event all GPIOs are floating inputs. This prevents any accidental damage to GPIOs in the event of emergency.
  • All GPIO registers are needed to be accessed with 32 bit words. This is mandatory.
  • Reserved bits for any GPIO register are kept at reset values i.e. 0.
  • For every GPIO port there are seven registers but the only the first four are the most important ones. The rest can be ignored most of the times.
  • These important GPIO registers per port are CRL, CRH, IDR and ODR. The rest three registers for GPIO ports can be avoided at the beginning.
  • For bit set and for bit clear, operations REGx |= (1 << bit) and REGx &= ~ (1 << bit) respectively are very handy and efficient. However MikroC compiler provides bit level access though its internal header file coding like this GPIOB_BSRRbits.BS15. We can use this method or the other one.
  • Some IOs are 5V tolerant and are label “FT” in datasheets and other docs. The rest of the I/O pins are not that tolerant and so 3.3V operation should always be ensured. STM32 has a maximum VDD tolerance of 4V but this value shouldn’t be used in any situation for safe operation. Best is to avoid 5V use with GPIOs whenever possible. This will help in avoiding accidental damage to the micro due to common mistakes.
  • Unused GPIO pins should be kept at reset state or tied to ground with 10kΩ resistors so that they remain either as floating inputs or safely connected to ground though it’s not a must.
  • I/O pins can source or sink currents up to 25mA. Thus direct LED drive is possible with them. To drive loads that need more than this value, we must use external BJTs, MOSFETs, optocouplers, transistor arrays or other driver devices.
  • I/O pins should not directly drive inductive or capacitive loads.
  • Care should be taken to avoid driving outputs beyond 50MHz. This is the maximum I/O pin frequency rating.
  • CRL/H registers essential set GPIO pin operating mode independently as according to the table below:
  • CRL sets GPIOs from 0 – 7 while CRH sets from 8 – 15. All IO ports are 16 bit wide unlike common 8 bit micros like PIC or AVR.


CRL Register:

Stm32 Array Declaration Form

CRH Register: