📜 ⬆️ ⬇️

STM32F103C8T6 - we make an oscilloscope. Part 3

The third part ( first and second ) is about how I am doing an oscilloscope from a debugging board with a price of less than $ 3. Demo video of work:

And the description of some key features under the cut.



Analog part


Almost everything as described in the second part , except for the source of bipolar power. OU consume a significant current (about 10 mA) and it did not succeed as they did not try to obtain acceptable results by the schemes of voltage multiplier on diodes and capacitors. Therefore, for a positive voltage, I installed such a module based on MT3608:

configured for 10 V output voltage. And the negative voltage is obtained by inverting the positive with the help of LT1054.
')

About code size


In the first part I wrote that a lot of memory is consumed. Now I have come to the point that the program does not fit into the memory and studied this issue in more detail.

CooCox CoIDE displays information about the size of the program as follows:
text data bss dec hex filename 60224 2500 10540 73264 11e30 projectName.elf 

Where


The whole program takes:


Now look at what memory is wasted. Making a new project and compiling:
  text data bss dec hex filename 364 1080 32 1476 5c4 test-size.elf 

To use macros of type GPIO_BSRR_BS9, you must include the file stm32f10x.h.
To connect the stm32f10x.h file, add the component STM32F10x_MD_STDLIB in the repositories, which pulls cmsis_core behind it. As a result, for a program writing one value to a register, we get:
  text data bss dec hex filename 1316 1104 32 2452 994 test-size.elf 

Further I am interested in functions like sprintf and sscanf. To use them you need to define some functions like _sbrk and possibly some others. I took the finished file (there is an archive with the project). Add 1 sscanf call and get:
Try to guess how much before you watch!
  text data bss dec hex filename 39312 2264 96 41672 a2c8 test-size.elf 

41 kb flash! More than half of what is in the controller!
In the working firmware, when using printf, adding sscanf increases flash consumption by 13.2 KB. As a result, sscanf refused, and the PC team began to parse the less resource-intensive method.
Failure to printf saves another 8.3 KB.


Modes of operation


Implemented 3 modes by the principle of operation: continuous, batch and logical, and 3 by the number of channels: 1, 2 and 4 channels.
MK has 9 analog inputs, but I can not imagine when I may need more than 4 channels.

Continuous


Everything is simple: in the main MK cycle, we read the ADC data and transfer them to a PC, where we can build a continuous schedule. The disadvantage is the speed limit from the channel MK -> PC. To get around it implemented another 2 modes.

Batch


In this mode, the MC first collects data, then transfers it to the PC in a pack. Optionally it can be overclocked. About overclocking wrote in detail in the previous parts.

In this mode, synchronization is possible. And you can analyze the signal before the condition. To implement this functionality, we had to change the DMA operation mode to a ring one, use the interrupt of filling half of the buffer, and use a buffer containing 2 times more data than in the transmitted packet.

Unlike the baghear project , I have a software trigger. The advantages of this solution:


In single-channel mode, both ADCs in turn convert the value of one channel.
In a two-channel channel, each ADC converts its channel by starting simultaneously with another.
In 4-channel - each ADC has 2 channels, which it converts. The start of both ADCs is simultaneous.
Obviously, the speed of the channel conversion frequency is inversely proportional to the number of channels.

Logic analyzer


The fastest mode. Approximately 20 MSPS per channel. The fastest code for this mode looks like this:
 u32 i = 0; dataBuffer.u8[i] = GPIOA->IDR; dataBuffer.u8[++i] = GPIOA->IDR; dataBuffer.u8[++i] = GPIOA->IDR; dataBuffer.u8[++i] = GPIOA->IDR; dataBuffer.u8[++i] = GPIOA->IDR; dataBuffer.u8[++i] = GPIOA->IDR; 

and so on for the entire buffer.
The value of the variable i in this case is calculated at the compilation stage and as a result from dataBuffer.u8 [++ i] = GPIOA-> IDR; It turns out only 2 operations - load data into the register from the port and save the data into memory at a pre-calculated address. No cycles of such performance was achieved.

PC software


The main, in my opinion, change - the transition to OpenGL. With him, drawing graphics has become easier (for me it turned out to be unexpected, but everything is really simple and brief there!), They are drawn faster and are much more beautiful than they were before.

Total


The project is not completed, there are glitches, there is a lot more to finish, but some breakthroughs are not foreseen. For faster systems, you need another hardware, for example, a separate ADC + FPGA + memory - and this will be much more expensive and more difficult to mount.

After reading the comments on the article "The history of one oscilloscope on stm32" I immediately answer some questions:


Archive with the project
If anyone has any questions, but they are not registered here, write to the email: adefikux at gmail dot com.

Source: https://habr.com/ru/post/372453/


All Articles