梁山派示波器-双通道 - 嘉立创EDA开源硬件平台

编辑器版本 ×
标准版 Standard

1、简单易用,可快速上手

2、流畅支持300个器件或1000个焊盘以下的设计规模

3、支持简单的电路仿真

4、面向学生、老师、创客

专业版 professional

1、全新的交互和界面

2、流畅支持超过3w器件或10w焊盘的设计规模,支持面板和外壳设计

3、更严谨的设计约束,更规范的流程

4、面向企业、更专业的用户

专业版 梁山派示波器-双通道

简介:基于梁山派的双通道示波器设计

开源协议: GPL 3.0

(未经作者授权,禁止转载)

创建时间: 2023-08-29 12:16:39
更新时间: 2024-01-09 18:49:04
描述

项目分析

本项目基于梁山派设计双通道示波器

实现功能:

1、双通道采集

2、DAC波形生成

3、拨轮按键控制

4、屏幕触控控制

硬件整体框图:

ergeNRejIi6uKLhSfsyfucrhDcvCHTSEVaYQPed3.png

本项目基于官方案例设计,官方案例如下:【示波器扩展板】资料

本人所作工作如下:

1、基于官方单通道采集电路绘制双通道采集电路

2、绘制屏幕触控电路,代替按键操作

3、删去轻触按键,保留拨轮按键

4、使用屏幕触控+拨轮按键完成人机交互

5、增加一处供电接口

6、根据绘制的原理图设计PCB

7、焊接并调试示波器

8、完成双通道示波器代码

 

原理图设计说明

1、AC/DC耦合电路
本项目使用一个继电器同时控制两路ADC采集电路的AC/DC耦合,通过切换GPIO电平的高低来控制继电器开关,以实现AC/DC的切换
3ShXqXHF1M24rkN71RVdlsZmMfNcGXEOdnDdFcEd.png
 
2、分压电路、程控运放信号处理电路和波形发生器输出电压跟随电路
这三部分电路均借鉴官方案例,在此不多做说明,参考官方文档即可【示波器扩展板】资料
DN7BKJtdZ7bsYXHKP0JEgomAhfEahJb2yvZKVTkn.png
 
0IihrXIcEEOCx3rJlXPby4f3mxvJzQTBpcg1L8ky.png
 
WnceckQFAJWA75OV9ujIF9DL9zpyyeVtvErGf0eR.png
 
3、电源部分
电源部分的电平转换借鉴官方案例,在此不多做说明
在官方的基础上,我增加一处供电接口,原因是我在使用官方示波器扩展版时,供电接口与波形采集通道和波形输出通道相互干扰,无法正常使用,在本项目中修改为波形采集通道后,会直接导致一个通道无法使用,所以在本项目中增加了一处供电接口,以保证双通道稳定使用
Vh62MU6ZNm1Aor00o8FENpkHUuCk5TPD95zvfCLe.png
 
同时,需要注意一点的是,示波器采用是ADC基准源使用的是+2.5V,但在梁山派中使用是基准源为3.3V,需要将梁山派中的A3.3V和AGND 0Ω电阻拆除,官方文档的特别注意如下:
OAWc4hytd5MLdaHTZnxRKKMCUYQPZr4MPblgwdkf.png
 
4、屏幕电路
 本项目使用2.4寸SPI屏幕,在官方显示电路的基础上增加触控电路,以实现示波器的触控交互,显示和触控均使用SPI通信
RNI0Ogiy7aAn36fPzlf47qhsbGVgJNIQFXHPI3Y4.png
 
5、按键电路
 本项目使用两个拨码按键和屏幕触控实现示波器的人机交互
xQaMJjkIR36mW8saAaIBf3JUbGeydi4WCakvk9Z5.png
 
 

PCB设计说明

本项目需要放置的器件比较多,所以我在设计时,加长了板子的长度,宽度与梁山派核心板保持一致,如下图所示

cXK1HRnolEu2mvRFYmrcY3z9Yb8sQwF9WFTl8NYl.png

 

在PCB设计时,布局比较紧凑,对布线影响较大,所以本项目最后采用了4层板设计,使用了内层1为模拟地平面,内层2因为担心会对模拟信号产生干扰,所以仅连接了部分电源线和信号线(这方面也是第一次绘制,不太清楚会不会产生干扰,如果有大佬看到并且能普及一下相关知识那定然是极好的,还请勿喷)

 

在本项目中,引出两个ADC检测探头,同时引出波形发生测试点和模拟地测试点,波形发生测试点和模拟地测试点采用测试环,便于示波器探头连接测试

78Xt5JZR24mXM3gwMwvKBJSE7equKKIBUqhgi6Cy.png

 

还有就是元器件布局较密,焊接稍微麻烦一些

 

软件说明

1、双路ADC初始化

两路ADC分别是PA1-ADC0CH1和PF7-ADC2CH5,采集思路为:定时器触发ADC采集,DMA自动将数据存储,当数据采集过半或完成采集触发DMA中断,将采集到的数据以波形形式进行显示

在ADC初始化函数中,PA1与官方例程中使用引脚一致,不做修改,仅添加PF7部分即可

aZTERjjkWZUsJt7HDJ2IwAiBmJ9Cnui2jhCUaLdB.png

 

ADC2CH5的采集中断函数

mzz6Xdl1qqluFlDoS0UixqiFQ0lTfGdSBgEvTfMO.png

 

2、交直流切换和采样倍率切换控制

0j7EdkIj3olC085zpuCEBZRSMGxdGRjT40BLUU9y.png

 

3、微秒延时函数实现

首先,修改进入systick.c函数,修改systick时钟重装寄存器的值,原值为系统时钟/1000,这种情况下,每次进入中断的实践间隔为1ms,所以原文件中只有毫秒延时的函数。将该值修改为系统时钟/1000000,每次进入中断的时间就变为了1us,同时对原毫秒延时函数进行修改,即完成了微妙延时函数的实现

EMyx7EQdbROgTE02w2STqgHGVldGGUCayPwML1WK.png

 

4、触控函数移植

本项目中使用的触控芯片是XPT2046,卖屏幕的有提供XPT2046的触控函数,不过是应用于ST芯片的函数,需要进行GD的移植

触控提供的例程是软件SPI,所以本项目也使用软件SPI,上一步的微秒函数实现就是主要是应用于触控的软件SPI通信

触摸屏因批次不同等原因,默认的校准参数值可能会引起触摸识别不准,推荐校准后再使用,不建议直接使用固定的默认校准参数,触摸函数初始化如下图所示,通过Adjust函数确定是使用原厂参数还是采用手动校准获取参数

推荐先使用手动校准获得较为准确的参数(通过串口输出),根据这个参数修改程序后再关闭手动校准

k8aRF9eRTLR8xcYeWeJz7pMKfxnmRTk5ETcgLWMp.png

 

触控的坐标采集如下图所示,同时添加两个状态机用于支持单次触摸,放置一次触屏导致多次触发对应函数

Gmf3MkHTzo5Q9eF6yeJZbAaISb8Z71JlijjFANjR.png

 

简单介绍一下,本项目中的触控逻辑,首先循环检测屏幕是否有被按下,当被按下后,检测被按下屏幕区域,如果该区域内有相应的触控函数,就执行对应的代码,执行完毕后,就等待触控被释放,当触控被释放后,便回到开头,实现循环检测,逻辑框图如下图所示

wkrWbtAsLYPl8lugZB2STBSb94p5vUDqckDBuRNk.png

 

未暂停状态下的触控响应函数如下图所示

U2BjSYeYvuWVPK41oqtVL2FKEwYWc0dVeLnYHh4u.png

 

暂停状态下的触控响应函数如下图所示

zTpKj7yKlxdHBBGBgLp3jJA8Pkd9eIB60GrQsP7N.png

 

 

 

5、整体函数实现

本项目的整体函数根据官方例程修改而来

实现功能如下

实现触控操作,包括波形采集的暂停开启、上下边沿切换、交直流切换、放大倍数切换、采样速度切换、波形种类切换、FFT切换、暂停状态下的通道信息显示切换

双拨轮函数适配,原例程的拨轮控制函数不适用于双通道采集,所以本项目基于双通道采集,实现了双拨轮的控制函数

整体功能与双通道示波器适配

 
#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>
#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采集数据指针
uint16_t *adc_tmp;
uint16_t *adc_tmp1;
 
//FFT变量
#define FFT_LENGTH 1024 //FFT长度,默认是1024点FFT
float fft_inputbuf[FFT_LENGTH*2]; //FFT输入数组
float fft_outputbuf[FFT_LENGTH]; //FFT输出数组
arm_cfft_radix4_instance_f32 scfft;
 
//FFT显示处理
float max_fft;
uint16_t fft_number;
//uint16_t fft_n; //缩放比例
 
//频域显示状态
uint8_t fft_show_state = 1;   //默认1显示探头1的,2显示探头2,0不显示
 
uint16_t Lase_Trigger_number,Lase_Trigger_number1;
uint8_t show_updata;
uint16_t data_tmp;
 
//波轮按键对应设置
uint8_t keya_set=0;
uint8_t keya_number=3;
uint8_t keyb_set=0;
uint8_t keyb_number=4;
 
//触控的坐标和触控状态
uint16_t touch_x;
uint16_t touch_y;
uint8_t touch_state = 0;    //0代表未屏幕未被触控,1代表屏幕已被触控
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);  // 优先级分组
    systick_config();
    led_gpio_config();  // led初始化
    key_gpio_config(); // key初始化
    usart_gpio_config(9600U);
    
    //sram初始化
    exmc_synchronous_dynamic_ram_init(EXMC_SDRAM_DEVICE0);
    
    //LCD初始化
    LCD_Init();
    delay_1ms(50);
    Spi2_Dma_Init();
    Lcd_Gram_Fill(Show_GramA,GRAM_BLACK);   //将颜色数据写入缓冲区
    LCD_Show_Gram(Show_GramA);
    while(Lcd_Show_Over);
    LCD_BLK_Set();//打开背光
    delay_1ms(10);
    Lcd_Gram_Fill(Show_GramA,GRAM_BLACK);
    Lcd_Gram_Fill(Show_GramB,GRAM_BLACK);
    
    
    //开启定时器固定刷屏
    Lcd_Show_Time();
    
    //波形输出
    dac_config();
    Dac_Show_Wav(wav_number);
    Dac_Time_Hz(wav_Fps);
    
    //ADC采集
    adc_config();
    adc_setio_init();
    alternating_direct_set(ac_dc);
    gather_rate_set(gather_rate);
    adc_speed_set(adc_speed);
 
TP_Init();
    
    ////FFT初始化 scfft结构体
    arm_cfft_radix4_init_f32(&scfft,FFT_LENGTH,0,1);
    
    //绘制功能图标
    POINT_COLOR=GRAM_WHITE; //画笔颜色
    for(i=0;i<10;i++) Lcd_Show_Data(i);
    POINT_COLOR=GRAM_YELLOW; //画笔颜色
    Lcd_Show_Data(keya_number);
    POINT_COLOR=GRAM_GREEN; //画笔颜色
    Lcd_Show_Data(keyb_number);
    POINT_COLOR=GRAM_WHITE; //画笔颜色
    
    while(1) 
    {
        //定时器循环固定数据刷屏
        while(Lcd_Show_Over);
        if(show_updata)
        {
            show_updata=0;
            Show_Star=1;            //开始这个一帧标志
            while(Show_Star);       //等待帧处理
        }
 
 
//触摸检测,仅支持单触摸,不支持连触
TP_Scan(0);
if(touch_state == 0)
{
if(tp_dev.sta&TP_PRES_DOWN)//有触摸被按下
{  
delay_1ms(1);//必要的延时,否则老认为有按键按下.    
if((tp_dev.x[0]<(LCD_W-1)&&tp_dev.x[0]>=1)&&(tp_dev.y[0]<(LCD_H-1)&&tp_dev.y[0]>=1))
touch_x = tp_dev.x[0];
touch_y = tp_dev.y[0];
touch_judge = 1;
//printf("X:%d, Y:%d\r\n", tp_dev.x[0], tp_dev.y[0]);
}    
}
}
if(tp_dev.sta&TP_PRES_DOWN)//有触摸被按下
touch_state = 1;
else
touch_state = 0;
 
 
        
        if(adc_power)
        {
            //等待采集完成
            while(!adc_dma_ok);
            adc_dma_ok=0;
            
            //配置指针 添加计算缓冲  DMA采样速度过快
            if(adc_dma_AB) adc_tmp = adc_value + adc_buff_2x;
            else adc_tmp = adc_value ;
if(adc_dma_AB1) adc_tmp1 = adc_value1 + adc_buff_2x;
else adc_tmp1 = adc_value1;
for(i=0;i<adc_buff_2x;i++) 
{
adc_buff[i] = adc_tmp[i];
adc_buff1[i] = adc_tmp1[i];
}
            
if(fft_show_state == 1)
{
//FFT运算 <1ms
for(i=0;i<FFT_LENGTH;i++)//生成信号序列
{
fft_inputbuf[2*i]=adc_buff[i];//生成输入信号实部
fft_inputbuf[2*i+1]=0;//虚部全部为0
}
arm_cfft_radix4_f32(&scfft,fft_inputbuf);//FFT计算(基4)
arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,FFT_LENGTH);//把运算结果复数求模得幅值 
fft_outputbuf[0] = 0;//第一个值非常大,这里舍弃
//测算最大FFT点
max_fft = 0;
fft_number=0;
for(i=0;i<320;i++)
{
if(fft_outputbuf[i] > max_fft)
{
max_fft = fft_outputbuf[i];
fft_number = i;
}
}
//自动评估FFT缩放等级
fft_n = max_fft/150 + 1; //只显示150个刻度
for(i=0;i<320;i++)
{
Show_LinB[i]=(fft_outputbuf[i]/fft_n +27);
if(Show_LinB[i] > 227) Show_LinB[i]=227-8;
else if(Show_LinB[i] < 27) Show_LinB[i]=27-8;
else Show_LinB[i]=Show_LinB[i]-8;
}
//FFT频率估测
fft_fps = (2000000 / (0x01<<adc_speed)) * fft_number / 1024;
}
else if(fft_show_state == 2)
{
//FFT运算 <1ms
for(i=0;i<FFT_LENGTH;i++)//生成信号序列
{
fft_inputbuf[2*i]=adc_buff1[i];//生成输入信号实部
fft_inputbuf[2*i+1]=0;//虚部全部为0
}
arm_cfft_radix4_f32(&scfft,fft_inputbuf);//FFT计算(基4)
arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,FFT_LENGTH);//把运算结果复数求模得幅值 
fft_outputbuf[0] = 0;//第一个值非常大,这里舍弃
//测算最大FFT点
max_fft = 0;
fft_number=0;
for(i=0;i<320;i++)
{
if(fft_outputbuf[i] > max_fft)
{
max_fft = fft_outputbuf[i];
fft_number = i;
}
}
//自动评估FFT缩放等级
fft_n = max_fft/150 + 1; //只显示150个刻度
for(i=0;i<320;i++)
{
Show_LinB[i]=(fft_outputbuf[i]/fft_n +27);
if(Show_LinB[i] > 227) Show_LinB[i]=227-8;
else if(Show_LinB[i] < 27) Show_LinB[i]=27-8;
else Show_LinB[i]=Show_LinB[i]-8;
}
//FFT频率估测
fft_fps = (2000000 / (0x01<<adc_speed)) * fft_number / 1024;
}
            
            
            //////设定值判定  Trigger  上升下降沿
            Trigger_number=0;
            max_data = 2048+(Trigger-Level)*16;
            if(wav_trigger)
            {
                for(i=lin_stat_set;i<lin_over_set;i++) 
                {
                    if(adc_tmp[i] <  max_data-25) 
                    {
                        for(;i<lin_over_set;i++) 
                        {
                            if(adc_tmp[i] > max_data)
                            {
                                Trigger_number=i-lin_stat_set;
                                break;
                            }
                        }
                        break;
                    }
                }
            }
            else
            {
                for(i=lin_stat_set;i<lin_over_set;i++) 
                {
                    if(adc_tmp[i] >  max_data+25) 
                    {
                        for(;i<lin_over_set;i++) 
                        {
                            if(adc_tmp[i] < max_data)
                            {
                                Trigger_number=i-lin_stat_set;
                                break;
                            }
                        }
                        break;
                    }
                }
            }
            Trigger_number1=0;
            max_data = 2048+(Trigger1-Level1)*16;
            if(wav_trigger)
            {
                for(i=lin_stat_set;i<lin_over_set;i++) 
                {
                    if(adc_tmp1[i] <  max_data-25) 
                    {
                        for(;i<lin_over_set;i++) 
                        {
                            if(adc_tmp1[i] > max_data)
                            {
                                Trigger_number1=i-lin_stat_set;
                                break;
                            }
                        }
                        break;
                    }
                }
            }
            else
            {
                for(i=lin_stat_set;i<lin_over_set;i++) 
                {
                    if(adc_tmp1[i] >  max_data+25) 
                    {
                        for(;i<lin_over_set;i++) 
                        {
                            if(adc_tmp1[i] < max_data)
                            {
                                Trigger_number1=i-lin_stat_set;
                                break;
                            }
                        }
                        break;
                    }
                }
            }
            
            //缓存缩放裁剪导入
            for(i=0;i<320;i++)
            {
                Show_LinA[i]=((adc_buff[i+Trigger_number] + 0x08)>>4) + Level;//
                if(Show_LinA[i] > 227) Show_LinA[i]=227-8;
                else if(Show_LinA[i] < 27) Show_LinA[i]=27-8;
                else Show_LinA[i]=Show_LinA[i]-8;
 
                Show_LinA1[i]=((adc_buff1[i+Trigger_number1] + 0x08)>>4) + Level1;
                if(Show_LinA1[i] > 227) Show_LinA1[i]=227-8;
                else if(Show_LinA1[i] < 27) Show_LinA1[i]=27-8;
                else Show_LinA1[i]=Show_LinA1[i]-8;
            }
            
            //显示数据
            if(Show_AB)  Lcd_Show_Wav(Show_GramA);
            else Lcd_Show_Wav(Show_GramB);
 
//触摸判断操作
if(touch_judge == 1)
{
//开始暂停
if(touch_x >= 10 & touch_x <= 26 & touch_y >= 2 & touch_y <= 18)
{
Lase_Trigger_number = Trigger_number+1;
Key_Make_Set(0); //开始暂停
}
 
//下降沿上升沿
if(touch_x >= 125 & touch_x <= 141 & touch_y >= 2 & touch_y <= 18)
{
if(wav_trigger)
Key_Make_Set(4);
else
Key_Make_Set(5);
}
 
//ACDC
if(touch_x >= 150 & touch_x <= 166 & touch_y >= 2 & touch_y <= 18)
{
Key_Make_Set(6); //ACDC
}
 
//增加放大倍数
if(touch_x >= 175 & touch_x <= 191 & touch_y >= 2 & touch_y <= 18)
{
Key_Make_Set(11);
}
 
//减小放大倍数
if(touch_x > 191 & touch_x <= 207 & touch_y >= 2 & touch_y <= 18)
{
Key_Make_Set(10);
}
 
//减少采样速度
if(touch_x >= 240 & touch_x <= 261 & touch_y >= 2 & touch_y <= 18)
{
Key_Make_Set(13); //增加波形种类
}
 
//增加采样速度
if(touch_x > 261 & touch_x <= 282 & touch_y >= 2 & touch_y <= 18)
{
Key_Make_Set(14); //增加波形种类
}
 
//改变波形种类
if(touch_x >= 10 & touch_x <= 42 & touch_y >= 222 & touch_y <= 238)
{
Key_Make_Set(23); //增加波形种类
}
 
//FFT功能
if(touch_x >= 100 & touch_x <= 132 & touch_y >= 222 & touch_y <= 238)
{
Key_Make_Set(29); //FFT
}
            //拨轮A
            if(key[3] == Key_Time)
            {
                if(keya_set)
                {
                    key[3] = Key_No; //需要再次释放
Lcd_Show_Data(keya_number);
                    if(keya_number < 9) keya_number++;
                    POINT_COLOR=GRAM_YELLOW; //画笔颜色
                    Lcd_Show_Data(keya_number);
                    POINT_COLOR=GRAM_WHITE; //画笔颜色
                }
                else
                {
 
                    if(keya_number==5 || keya_number==6 || keya_number==8) key[3]--; //不需要释放
                    else key[3] = Key_No; //需要再次释放
                    POINT_COLOR=GRAM_YELLOW; //画笔颜色
                    Key_Make_Set(keya_number*3 + 2); //减1
                    POINT_COLOR=GRAM_WHITE; //画笔颜色
                }
            }
            if(key[4] == Key_Time)
            {
                key[4] = Key_No; //需要再次释放
                keya_set = !keya_set;
            }
            if(key[5] == Key_Time)
            {
                if(keya_set)
                {
                    key[5] = Key_No; //需要再次释放
Lcd_Show_Data(keya_number);
                    if(keya_number) keya_number--;
                    POINT_COLOR=GRAM_YELLOW; //画笔颜色
                    Lcd_Show_Data(keya_number);
                    POINT_COLOR=GRAM_WHITE; //画笔颜色
                }
                else
                {
                    if(keya_number==5 || keya_number==6 || keya_number==8) key[5]--; //不需要释放
                    else key[5] = Key_No; //需要再次释放
                    POINT_COLOR=GRAM_YELLOW; //画笔颜色
                    Key_Make_Set(keya_number*3 + 1); //减1
                    POINT_COLOR=GRAM_WHITE; //画笔颜色
                }
            }
            //拨轮B
            if(key[6] == Key_Time)
            {
                if(keyb_set)
                {
                    key[6] = Key_No; //需要再次释放
Lcd_Show_Data(keyb_number);
                    if(keyb_number < 9) keyb_number++;
                    POINT_COLOR=GRAM_GREEN; //画笔颜色
                    Lcd_Show_Data(keyb_number);
                    POINT_COLOR=GRAM_WHITE; //画笔颜色
                }
                else
                {
                    if(keyb_number==5 || keyb_number==6 || keyb_number==8) key[6]--; //不需要释放
                    else key[6] = Key_No; //需要再次释放
                    POINT_COLOR=GRAM_GREEN; //画笔颜色
                    Key_Make_Set(keyb_number*3 + 2); //减1
                    POINT_COLOR=GRAM_WHITE; //画笔颜色
                }
            }
            if(key[7] == Key_Time)
            {
                key[7] = Key_No; //需要再次释放
                keyb_set = !keyb_set;
            }
            if(key[8] == Key_Time)
            {
                if(keyb_set)
                {
                    key[8] = Key_No; //需要再次释放
Lcd_Show_Data(keyb_number);
                    if(keyb_number) keyb_number--;
                    POINT_COLOR=GRAM_GREEN; //画笔颜色
                    Lcd_Show_Data(keyb_number);
                    POINT_COLOR=GRAM_WHITE; //画笔颜色
                }
                else
                {
                    if(keyb_number==5 || keyb_number==6 || keyb_number==8) key[8]--; //不需要释放
                    else key[8] = Key_No; //需要再次释放
                    POINT_COLOR=GRAM_GREEN; //画笔颜色
                    Key_Make_Set(keyb_number*3 + 1); //减1
                    POINT_COLOR=GRAM_WHITE; //画笔颜色
                }
            }
            
            
            
            //更新显示
            show_updata=1;
        }
        else
        {
//确定最大/小值
min_data=0xffff;
min_data1=0xffff;
max_data=0;
max_data1=0;
for(i=0;i<300;i++) 
{
if(adc_tmp[i+Trigger_number]< min_data) min_data=adc_tmp[i+Trigger_number];
if(adc_tmp[i+Trigger_number]> max_data) max_data=adc_tmp[i+Trigger_number];
 
if(adc_tmp1[i+Trigger_number1]< min_data1) min_data1=adc_tmp1[i+Trigger_number1];
if(adc_tmp1[i+Trigger_number1]> max_data1) max_data1=adc_tmp1[i+Trigger_number1];
}
            if(Lase_Trigger_number != Trigger_number) 
            {
                Lase_Trigger_number = Trigger_number;
                //缓存导入
                for(i=0;i<320;i++)
                {
                    Show_LinA[i]=((adc_tmp[i+Trigger_number] + 0x08)>>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] < 27) Show_LinA[i]=27-8;
                    else Show_LinA[i]=Show_LinA[i]-8;
                }
            }
 
            if(Lase_Trigger_number1 != Trigger_number1) 
            {
                Lase_Trigger_number1 = Trigger_number1;
                //缓存导入
                for(i=0;i<320;i++)
                {
                    Show_LinA1[i]=((adc_tmp1[i+Trigger_number1] + 0x08)>>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] < 27) Show_LinA1[i]=27-8;
                    else Show_LinA1[i]=Show_LinA1[i]-8;
                }
            }
 
//显示数据
if(Show_AB)
{
//绘制波形
Lcd_Show_Wav(Show_GramA);
}
else
{
//绘制波形
Lcd_Show_Wav(Show_GramB);
}
//更新显示
show_updata=1;
 
//触摸判断操作
if(touch_judge == 1)
{
if(touch_x >= 10 & touch_x <= 26 & touch_y >= 2 & touch_y <= 18)
{
Key_Make_Set(0); //开始暂停
}
if(touch_x >= 11 & touch_x <= 82 & touch_y >= 20 & touch_y <= 80)
{
if(ch_state == 0)
ch_state =1;
else if(ch_state == 1)
ch_state = 0;
}
}
            //拨轮A
            if(key[3] == Key_Time)
            {
                key[3]--;
                if(Trigger_number < adc_buff_2x-320) Trigger_number+=5;
            }
            if(key[4] == Key_Time)
            {
                key[4] = Key_No; //需要再次释放
            }
            if(key[5] == Key_Time)
            {
                key[5]--;
                if(Trigger_number > 5) Trigger_number-=5;
                else if(Trigger_number) Trigger_number = 0;
                else;
            }
            //拨轮B
            if(key[6] == Key_Time)
            {
                key[6]--;
                if(Trigger_number1 < adc_buff_2x-320) Trigger_number1+=5;
            }
            if(key[7] == Key_Time)
            {
                key[7] = Key_No; //需要再次释放
            }
            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);
    }
}
 
//屏幕刷新 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;
    }
 
    //拨码A
    if(KeyAUp) key[3] &= Key_Time;
    else if(key[3] < Key_Time) key[3]++;
    else;
    if(KeyAOn) key[4] &= Key_Time;
    else if(key[4] < Key_Time) key[4]++;
    else;
    if(KeyADown) key[5] &= Key_Time;
    else if(key[5] < Key_Time) key[5]++;
    else;
    //拨码B
    if(KeyBUp) key[6] &= Key_Time;
    else if(key[6] < Key_Time) key[6]++;
    else;
    if(KeyBOn) key[7] &= Key_Time;
    else if(key[7] < Key_Time) key[7]++;
    else;
    if(KeyBDown) key[8] &= Key_Time;
    else if(key[8] < Key_Time) key[8]++;
    else;
    
}
 
//ADC采集
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采集
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);
}
 

 

 

 

 

 

 

 

 

 

 

 

实物展示说明

正面反面

注意事项

1、在原理图设计说明的电源部分,提到ADC的基准源使用的+2.5V,但在梁山派中使用是基准源为3.3V,所以需要将梁山派中的A3.3V和AGND 0Ω电阻拆除,否则相当于将2.5V和3.3V短路,但是我其实一开始是没有注意到这一点的,并没有拆除梁山派的0Ω电阻,但是在这种情况下,示波器是能够正常工作的

能够正常工作的原因我认为是0Ω电阻并不少真正的短接,是仍然有一部分电阻的,3.3-2.5=0.8V的压降通过0Ω电阻达不到烧毁电路的状况,通过实际的功率测试,我得到的数据如下表

拆除0Ω电阻情况 未拆除 拆除
示波器电流 254.6mA 125.4mA

 

 

测试设备:合宙CC表

但仍不建议在不拆除0Ω电阻的情况下插入示波器扩展版。如果非试不可的话,请在确保安全的情况下进行测试

 

2、在使用示波器探头时,注意探头上的1X档位和10X档位,正常使用1X档位即可,10X档位会将信号缩小十倍,一般不使用

6CJisQWc3u5sIODrIL9Ohipz9Y5jXNWTQQGuveK5.png

在使用示波器时,如果发现采集的信号突然变得很小,可注意检查是否将示波器探头拨到了10X档位(别问,问我也不会说我因为不小心拨错了档位去把电路全检查了一遍了的)

 

3、程序直接编译烧录即可,如果烧录后无法正常显示,可能是屏幕驱动使用错误,在bsp_lcd.h文件内根据自己的芯片型号修改Chip_Selection变量值即可,支持ILI9341和ST7789两种屏幕驱动

stZW0IPiJHsVGDOjIHoO22oH9al8fbaaUbj66xN2.png

 

项目总结

我通过本项目学习到了很多知识,总结如下:

梁山派硬件电路知识

模电电路硬件知识

模拟电路电源设计

拨码开关的应用

2.4寸IPS屏幕的使用

模拟电路PCB设计

4层板PCB设计

GD32F450/470使用

TIME+DMA+ADC/DAC结合使用

DSP库的FFT使用

UI界面设计

C语言开发知识

系统程序开发

 

可以说是收获满满

 

参考链接

梁山派示波器扩展版资料

【立创·梁山派】入门教程资料

 

 

 

 

设计图
原理图
1 /
PCB
1 /
未生成预览图,请在编辑器重新保存一次
工程视频/附件
序号 文件名称 下载次数
1

梁山派双通道示波器-程序.7z

361
2

演示视频.mp4

374
工程成员
侵权投诉
相关工程
换一批
加载中...
添加到专辑 ×

加载中...

温馨提示 ×

是否需要添加此工程到专辑?

温馨提示
动态内容涉嫌违规
内容:
  • 153 6159 2675

服务时间

周一至周五 9:00~18:00
  • 技术支持

support
  • 开源平台公众号

MP