STM32 oscilloscope design

Table of contents

foreword

1. Hardware module

2. Basic knowledge of oscilloscope

2.1 The first blow is the concept of waveform

2.2 The second is the waveform parameters to be observed

2.3 The third is the oscilloscope parameters

2.3.1 Sampling rate

2.3.2 Bandwidth

2.3.4 Refresh rate

3. ADC acquisition and DAC output

3.1 ADC Acquisition Realization

3.1.1 Configure ADC acquisition as timing trigger DMA acquisition mode

3.1.2 Configure the timer associated with the ADC

3.1.3 Conversion to effective value

3.2 DAC waveform output

3.2.1 Select timer trigger

3.2.2 Configuring Timers

3.2.3 Generating Waveform Data

4. Waveform refresh scheme

4.1 Initialization process

4.2 Generating Waveform Data

4.3 Waveform refresh

Solution 1: Blank a line and draw the current line instead of drawing the line after blanking

Solution 2: Special treatment of grid points

Solution 3: Calculate pixels and refresh the whole screen

5. Trigger mode

6. Storage depth


foreword

Due to product requirements, it is necessary to integrate an oscilloscope function in the product to meet the demand for displaying real-time voltage.

This article summarizes and discusses the solution design (low cost) of the oscilloscope.

Among them, the implementation plan is mainly in chapters 3 and 4, and 1 and 2 are the concept part and the introduction of the environment, which can be skipped if not needed.

The following are the main reference materials when I design.

Reference 1: Second Generation Oscilloscope Tutorial - Essay Classification - Tough Guy eric2013 - Blog Garden (cnblogs.com)

Reference 2: STM32 Pocket Oscilloscope DS201 Design - Circuit City (cirmall.com)

1. Hardware module

In general, there are 2 hardware modules that can be provided: ADC interface of MCU, LCD screen , and nothing else;

There are no amplification circuits and filtering functions. The demo board directly uses the ADC interface of the MCU to collect external voltages, and sends the processed data to the screen for refresh.

At the same time, in order to simulate the measurement data, DAC+timer is also used to output sine wave , square wave, triangle wave and other waveforms.

2. Basic knowledge of oscilloscope

2.1 The first blow is the concept of waveform

Concept 1: Waveform refers to the graphic abstraction of the distribution of corresponding physical quantities in time and space.

Concept 2: A sine wave is defined in the time domain, and any other non-sinusoidal waveform can be regarded as a superposition of sine waves.

2.2 The second is the waveform parameters to be observed

As shown below.

Basic observation parameters: maximum value, minimum value and peak-to-peak value (not a typo, it is peak-to-peak value, worst);

Other parameters are: top value, bottom value and amplitude , all three of which are calculated in the stable value;

Time domain parameters: rise time, fall time, positive pulse width, negative pulse width , these four are measured values, and frequency, duty cycle , are calculated values.

Generally, what we need to display is ① maximum value, minimum value and peak-to-peak value, ② frequency, duty cycle, ③ X, Y axis unit size

2.3 The third is the oscilloscope parameters

2.3.1 Sampling rate

Sampling rate refers to how many sample values ​​can be collected in one second.

Theoretically speaking, the sampling rate must be more than 5 times the maximum frequency of the signal under test, in order to collect data rules more completely. (Why? Dividing the measured signal frequency by the sampling frequency is actually the number of points that can be collected within one cycle of the measured signal. If it is less than 5 points, it is difficult to specifically describe the data law)

The sampling rate of the STM32 microcontroller is equal to the sampling clock divided by the sampling period . Taking the STM32F4 series chip as an example, the maximum ADC clock is 36MHz, and the minimum sampling period of the ADC is 3+12 cycles, so the maximum sampling rate is 36/15=2.4MHz.

Practical applications:

1. According to the main frequency clock, the clock calculation obtained by the actual frequency division of the ADC, for example, when using the USB interface at the same time, the maximum main frequency is 168MHz, and the maximum ADC clock is 21MHz;

2. It can be used at the same time through dual or three ADCs to increase the ADC sampling rate ;

2.3.2 Bandwidth

Definition of bandwidth: In the frequency-amplitude characteristic curve, when the signal attenuates to -3db (70.7%), the frequency point at this time is defined as the bandwidth of the oscilloscope.

How to calculate? I haven't figured it out yet, so I'll leave it for later to study it carefully.

But it can be understood that the bandwidth must be more than 5 times larger than the measured signal (generally believed) in order not to be distorted.

Several effects of low sampling rate and small bandwidth on the waveform :

 

2.3.4 Refresh rate

Refresh rate, that is, the rate at which one frame of waveform image is refreshed.

Assuming that it takes 15ms to refresh a waveform (about 20,000 pixels), the refresh rate is equal to 66 frames per second.

The refresh rate is mainly limited by the MCU main frequency, data processing efficiency, and screen refresh efficiency.

There are several ideas for improving data processing and screen refresh:

1. Running on bare metal

Reduce the time consumption caused by task switching (microsecond level)

2. Use cache

Exchange space for time: one is to write the function package into the storage device to improve the calling efficiency; the other is to open up a cache (global variable) to store data, which is convenient for processing waveform data and LCD pixel data.

3. Optimization algorithm

One is to optimize the code, and the other is to improve the compiler optimization level.


For the early development work, you can put it aside first, first use the RTOS, and then realize the basic real-time waveform output function, and optimize the function first. After the optimization is completed, try to optimize the refresh time (it can be gradually degraded, but not gradually upgraded).

3. ADC acquisition and DAC output

premise {

        Chip platform: STM32F429ZGT6

        ADC:PA3

        DAC:PA4

}

3.1 ADC Acquisition Realization

3.1.1 Configure ADC acquisition as timing trigger DMA acquisition mode

Take PA3 as an example, ① select timer 3 trigger, ② select the minimum sampling period three, ③ select DMA cycle mode or Normal mode (half word size)

3.1.2 Configure the timer associated with the ADC

As follows, select the timer trigger event as the update event.

Therefore, we use two methods to judge whether the ADC data conversion is over:

1. Read the count value of DMAbuf of ADC

Pay attention to the DMA Count reading function of the ADC, the number read, not the actual length; for example, the length of BUF is 300, and the size of each unit is 2byte. When the DMA is full, the value read is 300 (not like the serial interrupt. , read 0).

2. Judging in the callback function of the DMA completion interrupt

When the completion interrupt is triggered, it definitely means that a conversion is over, which can be processed directly, or just closed without processing (waiting for the thread to process).

3.1.3 Conversion to effective value

The first layer of ADC data processing is to convert the ADC value into a real voltage value according to its own hardware circuit design.

I am directly connected to the MCU here, so the conversion relationship is vol = adc_value * 3300 / 4096 .

In the reference materials, the hardware circuit in DS201 uses an input amplifier and a gear switching circuit. It is necessary for a hardware engineer to calculate the resistance voltage division and amplification relationship, and finally get the calculation formula.

With this layer of data, it is convenient for subsequent algorithm debounce, normalization processing, and so on.

3.2 DAC waveform output

Since the waveform for measuring the internal voltage is basically a straight line, the input voltage of the external environment is likely to exceed 3.3V, causing the MCU to burn out.

Therefore, using the internal DAC output and using the ADC to measure the DAC, the ground wire is missing.

Or more cleverly, only one IO is used, and the DAC is output and the ADC is used for measurement at the same time.

Blood lesson!

The reference voltage collected by the single-chip ADC and the chip power supply voltage are both 3.3V, and there is no voltage dividing resistor.

So the maximum can only measure 3.3V.

However, when I connected to the external input, I didn't control it well, and a 12V passed, and the STM32H743 MCU of 380 yuan was burned directly.


The DAC configuration here uses DMA+DMA+timer.

3.2.1 Select timer trigger

Remember to configure it in DMA cycle mode

3.2.2 Configuring Timers

Or timer "update event"

3.2.3 Generating Waveform Data

Generate sine wave and square wave data according to your own test requirements. Its essence is an array of uint16_t type, and the data in it evolves according to a certain cycle.

After configuration, start the timer and configure DMAbuf for output.

HAL_TIM_Base_Start(&htim6);
HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_1, pData, Length, DAC_ALIGN_12B_R);

4. Waveform refresh scheme

premise {

        Screen size: 320*240

        Waveform window: 300*200

        LCD API functions (initialization, clear screen, draw dots, draw lines, display strings)

}

4.1 Initialization process

1) Initialize the DAC module and start the data transmission of the DAC module

2) Initialize the ADC module and start collecting ADC data

3) The while(1) loop makes the following judgments: wait until the ADC acquisition is completed, process the data first after processing, start the next ADC transmission first, and then refresh and complete the waveform before the ADC transmission ends.

4.2 Generating Waveform Data

In "ADC+DMA interrupt reception", we have received the real voltage data set.

If the vertical scanning voltage is 5V at this time (that is, the maximum voltage of the Y-axis is 5V, and the minimum voltage is 0V), then the y-axis has only 200 pixels, and the value unit of each point is 5000/200=25, so it is necessary to The data set is divided by 25 to get the corresponding Y-axis coordinate point.

Here are a few questions:

1. Can you directly divide by 25?

If the data is divided by 25, there will be a sawtooth characteristic with the real value +1, -1, which will cause glitches in the waveform.

At this time, it is necessary to design an optimization algorithm, such as the simplest rounding.

2. How to determine the X-axis coordinate point?

In my current processing method, scan once according to the current horizontal scanning clock (time base gear), for example, if the current time base is 200us, then scan once in 200us, and the scan is enough for 300 coordinate points to end, and start processing-refresh.

There are also many optimization methods here: for example, the number of scans is set to a multiple of 300, and the corresponding multiple of the time base is reduced or unchanged, and several ranges are screened and averaged to obtain 300 points.


In any case, what is finally sent to the screen to refresh is an array with a length of 300, corresponding to 300 coordinate values. These 300 coordinate values ​​are called waveform data.

4.3 Waveform refresh

The simpler method is to draw a line + cache the last waveform data and blank it;

Line drawing: As the name suggests, it is to draw a line between every two points for 300 coordinate points;

1. First blank the last waveform data, and blank the color of the line into the background color (erase the last frame of waveform);

2. Then draw the waveform of the current waveform data;

3. Cache the current waveform data.

//绘制波形
//1\擦除原有波形再绘制新波形
//2\输入数组长度为OSC_WIDTH:300
//X0\X1\Y0\Y1分别波形窗口的角落坐标值
void OscDrawWave(uint8_t WaveBuf[])
{
	static uint16_t X = {0};
	static uint8_t WaveBufPre[OSC_WIDTH] = {0};
	
	if(WaveBufPre[0])
	{
		LCD_SetColor(List_c[OSC_M_WAVE].Back, List_c[OSC_M_WAVE].Back);
		for(X = 0; X < X1 - X0 - 1; X++)
		{
			LCD_DrawLine(
				X0 + X, Y1 - WaveBufPre[X], 
				X0 + X + 1, Y1 - WaveBufPre[X+1]
			);
		}
	}
	
	LCD_SetColor(List_c[OSC_M_WAVE].Point, List_c[OSC_M_WAVE].Back);
	for(X = 0; X < X1 - X0 - 1; X++)
	{
		LCD_DrawLine(
			X0 + X, Y1 - WaveBuf[X], 
			X0 + X+ 1, Y1 - WaveBuf[X+1]
		);
	}
	
	for(X = 0; X < X1 - X0; X++){
		WaveBufPre[X] = WaveBuf[X];
	}
}

 The advantage of this is that it can reduce the frequency of flickering.

Furthermore, from the perspective of the display principle, the refresh rate can also be improved by the following methods:

Solution 1: Blank a line and draw the current line instead of drawing the line after blanking

In the above code, even if blanking is done, there will be flickering. If you change it to erase a line and draw another line, the sensory experience will be much better.

void OscDrawWave(uint8_t WaveBuf[])
{
	static uint16_t X = {0};
	static uint8_t WaveBufPre[OSC_WIDTH] = {0};
	
	for(X = 0; X < X1 - X0 - 1; X++)
	{
		LCD_SetColor(List_c[OSC_M_WAVE].Back, List_c[OSC_M_WAVE].Back);
		LCD_DrawLine(
			X0 + X, Y1 - WaveBufPre[X], 
			X0 + X + 1, Y1 - WaveBufPre[X+1]
		);
		LCD_SetColor(List_c[OSC_M_WAVE].Point, List_c[OSC_M_WAVE].Back);
		LCD_DrawLine(
		X0 + X, Y1 - WaveBuf[X], 
		X0 + X+ 1, Y1 - WaveBuf[X+1]
	);

	for(X = 0; X < X1 - X0; X++){
		WaveBufPre[X] = WaveBuf[X];
	}
}

Solution 2: Special treatment of grid points

For the oscilloscope to refresh, there are waveforms, grid lines, and waveform parameters.

Generally, the waveform parameters need to be changed by the value of the string type, and there is not much room for optimization (the pixel size is fixed).

Moreover, in the waveform, most of the pixels often coincide with the grid points.

So for grid points, there are three states and two judgments:

1. When blanking, the grid points should be drawn in the grid color, not the background color;

2. When drawing, the grid points should be drawn in the waveform color, not the grid color;

If you accidentally change the grid points into the background color, it will cause the waveform to brush and the grid will disappear...

Solution 3: Calculate pixels and refresh the whole screen

This solution is to calculate all the pixels that need to change state and send them to the screen for a one-time refresh, or take a step back and refresh the pixels one by one. The former "one-time refresh" can find a way to increase the refresh rate by using a method similar to DMA2D, while the latter can reduce the number of repeated pixel refreshes, thereby increasing the speed.

At present, no good implementation method has been made, and we will study and share it later.

5. Trigger mode

The above discussion is all about waveform processing without trigger mode.

Of course we know that the oscilloscope also has trigger functions: automatic trigger, single trigger, among which the most commonly used trigger method is edge trigger, we assume half of the vertical scanning voltage value + rising edge as the trigger condition.

There are several ways to achieve this condition that come to mind:

1. Hardware trigger

It is determined by the hardware to send the data in, and the first signal is the start signal that meets the conditions. (we don't)

2. Software trigger

Expand the sample size of data sampling

2.1. The software judges the position of the first rising edge of the data;

2.2. Use the external interrupt EXTI to select the rising edge trigger, and record the sample position when triggered;

When the trigger position is found, the subsequent 300 sample values ​​are used as coordinate point data

If no trigger position is found, the last 300 coordinate points will be displayed forcibly.

6. Storage depth

Take the waveform window width of 300 as an example, assuming that the minimum unit of the time base is 200us, the maximum is 200ms, and the difference is 1000 times. If you want to limit the signal state during pause, you need 3000 coordinate points. If you need to be able to move back and forth in general size, Then a total of 6000 sample points are required, that is, the size of 6K.

How to realize the storage depth, slightly...

Guess you like

Origin blog.csdn.net/weixin_38743772/article/details/126675787