
Liangshan oscilloscope - dual channel
PROLiangshan oscilloscope - dual channel
License
:GPL 3.0
Description
Project analysis
This project is based on the design of a dual-channel oscilloscope based on the Liangshan Pi.
Functions:
1. Dual-channel acquisition
2. DAC waveform generation
3. Dial wheel button control
4. Screen touch control
Hardware overall block diagram:
This project is based on the official case design, and the official case is as follows: [Oscilloscope Expansion Board] information
I have done the following:
1. Draw a dual-channel acquisition circuit based on the official single-channel acquisition circuit.
2. Draw the screen touch circuit instead of the button operation.
3. Delete the touch button and keep the wheel button.
4. Use screen touch + dial button to complete human-computer interaction.
5. Add a power supply interface.
6. Design the PCB according to the schematic diagram drawn.
7. Solder and debug the oscilloscope.
8. Complete the dual-channel oscilloscope code.
Schematic design description
In this project, a relay is used to control the AC/DC coupling of two ADC acquisition circuits at the same time, and the relay switch is controlled by switching the GPIO level to achieve AC/DC switching.

These three parts of the circuit are all based on the official case, not much to explain here, refer to the official document can be [oscilloscope expansion board] information.



3. Power supply part
The level shift of the power supply part is based on the official case, so I will not explain it here.
On the basis of the official, I added a power supply interface, the reason is that when I use the official oscilloscope extension version, the power supply interface and the waveform acquisition channel and the waveform output channel interfere with each other, and cannot be used normally, after being modified to the waveform acquisition channel in this project, it will directly cause a channel to be unusable, so a power supply interface is added in this project to ensure the stable use of dual channels.

At the same time, it should be noted that the oscilloscope uses an ADC reference of +2.5V, but the reference of the Liangshan Pi is 3.3V, and the A3.3V and AGND 0Ω resistors in the Liangshan Pi need to be removed.

4. Screen circuit
This project uses a 2.4-inch SPI screen, and a touch circuit is added on the basis of the official display circuit to realize the touch interaction of the oscilloscope, and the display and touch are both SPI communication.

5. key circuit
This project uses two DIP buttons and screen touch to realize the human-computer interaction of the oscilloscope.

PCB Design Instructions
There are a lot of devices that need to be placed in this project, so when I designed, I lengthened the length of the board, and the width is consistent with the Liangshan Pi core board, as shown in the figure below.
In the PCB design, the layout is relatively compact, which has a greater impact on the wiring, so this project finally adopts a 4-layer board design, using the inner layer 1 as the analog ground plane, and the inner layer 2 is only connected to part of the power line and signal line because it is worried that it will interfere with the analog signal (this aspect is also the first time to draw, I don't know if it will interfere, if there is a big guy to see and can popularize the relevant knowledge, it must be excellent, please do not spray)
In this project, two ADC detection probes are introduced, and the waveform generation test point and the simulated ground test point are drawn out at the same time, and the waveform generation test point and the simulated ground test point are used with test rings to facilitate the oscilloscope probe connection test.
There is also a dense layout of components, which is slightly more troublesome for welding.
Software Description
1. Dual-channel ADC initialization
The two ADCs are PA1-ADC0CH1 and PF7-ADC2CH5, and the acquisition idea is as follows: the timer triggers the ADC acquisition, and the DMA automatically stores the data, and when the data acquisition is more than half or the acquisition is completed, the DMA interrupt is triggered, and the collected data is displayed in the form of waveforms.
In the ADC initialization function, PA1 is the same as the pin used in the official routine, and only the PF7 part can be added without modification.
ADC2CH5 acquisition interrupt function.
2. AC and DC switching and sampling magnification switching control.
3. Microsecond delay function implementation
First of all, modify the function of entering systick.c, modify the value of the systick clock reload register, the original value is the system clock/1000, in this case, the practice interval of each entry interrupt is 1ms, so there is only a millisecond delay function in the original file. If the value is changed to system clock/1000000, the time of each interrupt is changed to 1us, and the original millisecond delay function is modified, that is, the implementation of the subtle delay function is completed.
4. Touch function porting
The touch chip used in this project is XPT2046, and the touch function that provides XPT2046 for the screen is sold, but it is a function applied to the ST chip, which needs to be ported to GD.
The example provided by touch is software SPI, so this project also uses software SPI, and the microsecond function implementation in the previous step is mainly applied to the software SPI communication of touch.
It is recommended to use the fixed default calibration parameters directly after calibration, and the touch function is initialized as shown in the figure below, and the Adjust function is used to determine whether to use the original parameters or manually calibrate to obtain the parameters.
It is recommended to use manual calibration to obtain more accurate parameters (through serial output) first, and then turn off manual calibration after modifying the program according to this parameter.
The coordinate collection of touch is shown in the figure below, and two state machines are added at the same time to support a single touch, and placing a touch screen once will cause the corresponding function to be triggered multiple times.
To briefly introduce the touch logic in this project, first of all, cycle to detect whether the screen is pressed, when pressed, detect the screen area that is pressed, if there is a corresponding touch function in the area, execute the corresponding code, after the execution, wait for the touch to be released, when the touch is released, it will return to the beginning to achieve loop detection, the logic block diagram is shown in the following figure.
The touch response function in the unpaused state is shown in the following figure.
The touch response function in the paused state is shown in the following figure.
5. Overall function implementation
The overall function of this project is modified according to the official routine.
The implementation functions are as follows:
Touch operation is realized, including pause and turn on waveform acquisition, upper and lower edge switching, AC and DC switching, magnification switching, sampling speed switching, waveform type switching, FFT switching, and channel information display switching in the paused state.
The dial control function of the original routine is not suitable for dual-channel acquisition, so this project realizes the control function of dual-dial wheel based on dual-channel acquisition.
The overall function is adapted to the dual-channel oscilloscope.
#include "gd32f4xx.h"
#include "systick.h"
#include
#include "main.h"
#include "bsp_led.h"
#include "sys.h"
#include "bsp_usart.h"
#include "bsp_key.h"
#include "bsp_basic_timer.h"
#include "bsp_lcd.h"
#include "bsp_spi.h"
#include "bsp_gui.h"
#include "exmc_sdram.h"
#include "bsp_dac.h"
#include "bsp_adc.h"
#include "touch.h"
#include "arm_math.h"
//ADC collects data Pointers
uint16_t *adc_tmp;
uint16_t *adc_tmp1;
//FFTvariable
#define FFT_LENGTH 1024 //FFT length, default is 1024 FFT
float fft_inputbuf[FFT_LENGTH*2]; //FFT input array
float fft_outputbuf[FFT_LENGTH]; //FFT output array
arm_cfft_radix4_instance_f32 scfft;
//FFTdisplay processor
float max_fft;
uint16_t fft_number;
//uint16_t fft_n; //scale
//Frequency domain display status
uint8_t fft_show_state = 1; //Default 1 shows probe 1, 2 shows probe 2, 0 does not
uint16_t Lase_Trigger_number,Lase_Trigger_number1;
uint8_t show_updata;
uint16_t data_tmp;
//The wave wheel button corresponds to the setting
uint8_t keya_set=0;
uint8_t keya_number=3;
uint8_t keyb_set=0;
uint8_t keyb_number=4;
//Touch coordinates and touch status
uint16_t touch_x;
uint16_t touch_y;
uint8_t touch_state = 0; //0 indicates that the screen is not touched, and 1 indicates that the screen is touched
uint8_t touch_judge = 0;
/*!
\brief main function
\param[in] none
\param[out] none
\retval none
*/
int main(void)
{
uint32_t i;
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); // Priority grouping
systick_config();
led_gpio_config(); // led initialize
key_gpio_config(); // key initialize
usart_gpio_config(9600U);
//sram initialize
exmc_synchronous_dynamic_ram_init(EXMC_SDRAM_DEVICE0);
//LCD initialize
LCD_Init();
delay_1ms(50);
Spi2_Dma_Init();
Lcd_Gram_Fill(Show_GramA,GRAM_BLACK); //Writes color data to the buffer
LCD_Show_Gram(Show_GramA);
while(Lcd_Show_Over);
LCD_BLK_Set();//Turn on the backlight
delay_1ms(10);
Lcd_Gram_Fill(Show_GramA,GRAM_BLACK);
Lcd_Gram_Fill(Show_GramB,GRAM_BLACK);
//Start the timer to fix the screen
Lcd_Show_Time();
//Output wave
dac_config();
Dac_Show_Wav(wav_number);
Dac_Time_Hz(wav_Fps);
//ADC collect
adc_config();
adc_setio_init();
alternating_direct_set(ac_dc);
gather_rate_set(gather_rate);
adc_speed_set(adc_speed);
TP_Init();
////FFT initialize scfft struct
arm_cfft_radix4_init_f32(&scfft,FFT_LENGTH,0,1);
//Draw function icon
POINT_COLOR=GRAM_WHITE; //stroke color
for(i=0;i>4) + Level1;
if(Show_LinA1[i] > 227) Show_LinA1[i]=227-8;
else if(Show_LinA1[i]
else Show_LinA1[i]=Show_LinA1[i]-8;
}
//data display
if(Show_AB) Lcd_Show_Wav(Show_GramA);
else Lcd_Show_Wav(Show_GramB);
//Touch judgment operation
if(touch_judge == 1)
{
//start/pause
if(touch_x >= 10 & touch_x = 2 & touch_y = 125 & touch_x = 2 & touch_y = 150 & touch_x = 2 & touch_y = 175 & touch_x = 2 & touch_y 191 & touch_x = 2 & touch_y = 240 & touch_x = 2 & touch_y 261 & touch_x = 2 & touch_y = 10 & touch_x = 222 & touch_y = 100 & touch_x = 222 & touch_y max_data1) max_data1=adc_tmp1[i+Trigger_number1];
}
if(Lase_Trigger_number != Trigger_number)
{
Lase_Trigger_number = Trigger_number;
//import cache
for(i=0;i>4) + Level;
//Show_LinA[i]=((adc_tmp[i+Trigger_number] )>>4) + Level;
if(Show_LinA[i] > 227) Show_LinA[i]=227-8;
else if(Show_LinA[i]
else Show_LinA[i]=Show_LinA[i]-8;
}
}
if(Lase_Trigger_number1 != Trigger_number1)
{
Lase_Trigger_number1 = Trigger_number1;
//import cache
for(i=0;i>4) + Level1;
//Show_LinA[i]=((adc_tmp[i+Trigger_number] )>>4) + Level;
if(Show_LinA1[i] > 227) Show_LinA1[i]=227-8;
else if(Show_LinA1[i]
else Show_LinA1[i]=Show_LinA1[i]-8;
}
}
//dispaly data
if(Show_AB)
{
//draw wave
Lcd_Show_Wav(Show_GramA);
}
else
{
//draw wave
Lcd_Show_Wav(Show_GramB);
}
//update dispaly
show_updata=1;
//touch judgment operation
if(touch_judge == 1)
{
if(touch_x >= 10 & touch_x = 2 & touch_y = 11 & touch_x = 20 & touch_y 5) Trigger_number-=5;
else if(Trigger_number) Trigger_number = 0;
else;
}
//Dial wheel B
if(key[6] == Key_Time)
{
key[6]--;
if(Trigger_number1
}
if(key[7] == Key_Time)
{
key[7] = Key_No; //Need to release again
}
if(key[8] == Key_Time)
{
key[8]--;
if(Trigger_number1 > 5) Trigger_number1-=5;
else if(Trigger_number1) Trigger_number1 = 0;
else;
}
}
touch_judge = 0;
//delay_1ms(200);
}
}
//screen refresh
50mS
void TIMER3_IRQHandler(void)
{
timer_interrupt_flag_clear(TIMER3, TIMER_INT_FLAG_UP);
if(Show_Star)
{
//LED1_TOGGLE();
Show_Star=0;
if(Show_AB)LCD_Show_Gram(Show_GramA);
else LCD_Show_Gram(Show_GramB);
Show_AB =!Show_AB;
}
//Dial-upA
if(KeyAUp) key[3] &= Key_Time;
else if(key[3]
else;
if(KeyAOn) key[4] &= Key_Time;
else if(key[4]
else;
if(KeyADown) key[5] &= Key_Time;
else if(key[5]
else;
//Dial-upB
if(KeyBUp) key[6] &= Key_Time;
else if(key[6]
else;
if(KeyBOn) key[7] &= Key_Time;
else if(key[7]
else;
if(KeyBDown) key[8] &= Key_Time;
else if(key[8]
else;
}
//AD Ccollect
void DMA1_Channel0_IRQHandler(void)
{
//LED3_TOGGLE();
adc_dma_ok=1;
if(dma_interrupt_flag_get(DMA1, DMA_CH0,DMA_INT_FLAG_HTF) == SET) adc_dma_AB=0;
else adc_dma_AB=1;
dma_interrupt_flag_clear(DMA1, DMA_CH0, DMA_INT_FLAG_FTF|DMA_INT_FLAG_HTF);
}
//ADC2 collect
void DMA1_Channel1_IRQHandler(void)
{
//LED2_TOGGLE();
adc_dma_ok1=1;
if(dma_interrupt_flag_get(DMA1, DMA_CH1,DMA_INT_FLAG_HTF) == SET) adc_dma_AB1=0;
else adc_dma_AB1=1;
dma_interrupt_flag_clear(DMA1, DMA_CH1, DMA_INT_FLAG_FTF|DMA_INT_FLAG_HTF);
}
Physical display description
FrontReverse
Precautions
1. In the power part of the schematic design description, it is mentioned that the reference source of ADC is +2.5V, but the reference source used in Liangshan Pi is 3.3V, so the A3.3V and AGND 0Ω resistors in Liangshan Pi need to be removed, otherwise it is equivalent to 2.5V and 3.3V short circuit, but I actually did not notice this at the beginning. Did not remove the 0Ω resistance of LiangshanPi, but in this case, the oscilloscope is able to work normally. The reason for the normal work is that the 0Ω resistance is not a lot of real short connection, there is still a part of the resistance, 3.3-2.5=0.8V voltage drop through the 0Ω resistance can not burn the circuit, through the actual power test, The data I got is shown below.
Remove the 0Ω resistor case | Not demolished | dismantle |
Oscilloscope current | 254.6mA | 125.4mA |
Test equipment: Hezhou CC table.
However, it is still not recommended to insert an oscilloscope extension without removing the 0Ω resistor. If you have to try it, do it when it is safe to do so.
2. When using the oscilloscope probe, pay attention to the 1X gear and 10X gear on the probe, the normal use of 1X gear can be, 10X gear will reduce the signal by ten times, generally do not use.
When using an oscilloscope, if you find that the collected signal suddenly becomes small, you can pay attention to check whether the oscilloscope probe is dialed to 10X (don't ask, I won't say that I accidentally dialed the wrong gear to check all the circuits)
3. The program can be compiled and burned directly, if it cannot be displayed normally after burning, it may be that the screen driver is used incorrectly, modify the variable value of the Chip_Selection according to your own chip model in the bsp_lcd.h file, and support ILI9341 and ST7789 two screen drivers.
Project Summary
I learned a lot through this program, which can be summarized as follows:
- Knowledge of hardware circuits in the Liangshan Pi.
- Hardware knowledge of modular circuits.
- Analog circuit power supply design.
- Application of DIP switches.
- Use of 2.4 inch IPS screen.
- Analog circuit PCB design.
- 4-layer board PCB design.
- GD32F450/470 use.
- TIME+DMA+ADC/DAC combined.
- FFT use of DSP libraries.
- UI interface design.
- Knowledge of C language development.
- System program development.
It can be said that it is full of harvest.
Reference Links
Designed by 子牧 (from OSHWHub)
Link:https://oshwhub.com/woshinidiegun/ji-yu-li-chuang-liang-shan-pai
Design Drawing


Comment