发作品签到
专业版

梁山派示波器拓展版

工程标签

92
0
0
0

简介

通过学习官方的历程制作了一款示波器

简介:通过学习官方的历程制作了一款示波器
复刻成本:150

开源协议

GPL 3.0

创建时间:2024-08-26 21:58:56更新时间:2025-02-11 09:27:53

描述

电路部分

负压电路部分

采用SGM3204YN6G/TR电荷泵将+5V的电压,转换为-5V电压用于给运放供电

 
基准电压电路
基准电压在电路中提供一个稳定的参考电压,这里选择了2.5V的电压基准给运放平移电路进行平移,还给ADC提供了参考基准,需要注意的是CJ431基准芯片的Ika默认一般为10mA工作效果较为稳定,故限流电阻选择为470Ω。
 
 
按键电路
示波器模块使用了两种按键,正面三个独立按键,背面两个拨码按键,拨轮按键有三种触发状态分别为上拨,按下,下拨。拨轮接线需要参考器件手册进行设计。
 
 
屏幕电路
这里使用了一块2.4寸SPI屏幕,屏幕大小(42.7260.26mm)和梁山派尺寸(4570mm)非常的搭配,并且SPI的屏幕驱动简单,引出的IO也能有效的和模拟电路进行分离。

模拟输出电路

这里使用的一个普通的单运算放大器作为电压跟随输出,主要是为了隔离单片机的DAC输出。

 

AC/DC耦合电路
该电路使用的一个信号继电器并在耦合电容两端,继电器不工作时由耦合电容进行耦合,由于电容的通交流阻直流特性,只有交流变化的信号会被后面的电路检测到。继电器工作时,耦合电容短路直连耦合,所有信号均可被后面的电路检测到。    这里的耦合电容越小,高频信号通过越容易,低频信号通过失真越严重。而耦合电容越大则反之,低频信号正常,高频信号失真,并且信号会出现延迟。这里我们使用单片机内部ADC(2M采样),故使用100nF(1206封装)进行耦合。(结合后级分压电路的计算fp=1/2πRC)

 

分压电路

相比于传统的分压电路,这里的分压电阻都有点过大,主要为了满足1MΩ的信号阻抗匹配,而分压电阻旁的电容有起到交流信号耦合的重要作用。 最后下面的可调电容,则是为了调整示波器的信号补偿电容,对于实际电路存在的偏差造成的信号损耗不同,就需要使用可调电容对信号就行补偿,补偿过大和补偿不足都会导致波形失真。

 

程控运放信号处理电路
这里主要使用一个8通单选模拟开关芯片74HC405和双运算放大器芯片TLV2372组成。

软件部分

串口usart

typec口连接了USART0,串口用于调试打印信息

串口部分代码概述:

  • 初始化配置usart_gpio_config 函数负责使能串口相关时钟,配置GPIO引脚的复用功能、模式及输出选项,同时设置串口的波特率、校验位、数据位、停止位等参数,并使能串口及发送功能。
  • 数据发送usart_send_data 函数用于向串口发送单个字节数据,usart_send_string 函数则用于发送字符串,二者都基于底层的串口发送操作并进行相应等待处理。
  • 标准库重定向fputc 函数重定向标准库的 fputc,让 printf 能通过串口输出数据 。

 

按键

三个普通按键分别用于直流交流偶合切换,开始暂停切换,FFT开关,两个拨码开关用于调节某些参数或者功能的增减。

按键的使用:

按键检测


按键放在定时器中断中进行检测,即可以及时检测到按键的触发。这了为了保证定时器的利用率,直接在屏幕刷新的50mS周期内进行查询的处理。

按键部分代码概述:

main函数

主函数部分代码概述:

1. 整体结构

代码包含一个无限循环 while(1),在循环内部进行各种数据处理和按键检测操作。

2. 定时器与数据更新

  • 定时器循环固定数据刷屏:通过 while(Lcd_Show_Over); 等待 LCD 显示完成。
  • 数据更新标志:当 show_updata 为真时,开始一帧数据的处理,设置 Show_Star 标志,并等待帧处理完成 while(Show_Star);

3. ADC 数据采集与处理

  • 采集完成检测:当 adc_power 为真时,等待 ADC DMA 采集完成 while(!adc_dma_ok);,然后重置 adc_dma_ok
  • 数据缓冲处理:根据 adc_dma_AB 的值配置指针,将 ADC 数据存储到缓冲区 adc_buff 中。
  • FFT 运算:将 ADC 缓冲区数据转换为 FFT 输入信号,进行 FFT 计算(基 4),并将运算结果复数求模得幅值。
  • FFT 数据处理:测算最大 FFT 点,自动评估 FFT 缩放等级,并对 FFT 输出数据进行缩放和裁剪处理,存储到 Show_LinB 数组中。
  • FFT 频率估测:根据 ADC 采样速度和最大 FFT 点计算 FFT 频率 fft_fps

4. 设定值判定与触发检测

  • 触发检测:根据 wav_trigger 的值,检测 ADC 数据的上升沿或下降沿触发,计算触发位置 Trigger_number
  • 无触发情况处理:如果没有触发,确定 ADC 数据的最大/小值,并计算触发位置。

5. 数据缓存与显示

  • 数据缓存缩放裁剪导入:将 ADC 缓冲区数据进行缩放和裁剪处理,存储到 Show_LinA 数组中。
  • 显示数据:根据 Show_AB 的值,调用 Lcd_Show_Wav 函数显示波形数据。

6. 按键配置与处理

代码对多个按键进行检测和处理,根据按键状态执行不同的操作,如设置按键功能、调整参数等。具体按键功能包括:

  • 按键 0:切换 ACDC 模式。
  • 按键 1:开始/暂停操作。
  • 按键 2:切换 FFT 模式。
  • 拨轮 A 和拨轮 B:通过不同的操作调整参数,如增加或减少数值。

7. 数据更新与显示

  • 更新显示:在数据处理完成后,设置 show_updata = 1,触发下一次数据更新。
  • 按键处理:在 adc_power 为假时,根据按键状态调整触发位置 Trigger_number,并更新显示数据。

 

SPI

SPI部分代码概述:

1. SPI2 初始化函数 Spi2_Init(void)

  • 时钟使能:使能 GPIOC 和 SPI2 的时钟,为后续配置 GPIO 和 SPI2 做准备。
  • GPIO 配置:将 GPIOC 的引脚 10、11、12 配置为复用功能(AF6),模式为复用推挽输出,速度为 50MHz。
  • SPI2 参数配置
    • 传输模式设置为全双工 SPI_TRANSMODE_FULLDUPLEX
    • 设备模式设置为主机 SPI_MASTER
    • 数据帧大小为 8 位 SPI_FRAMESIZE_8BIT
    • 时钟极性和相位设置为 SPI_CK_PL_HIGH_PH_2EDGE
    • NSS 管理设置为软件模式 SPI_NSS_SOFT
    • 预分频器设置为 SPI_PSC_2
    • 数据传输顺序设置为高位在前 SPI_ENDIAN_MSB
  • 使能 SPI2:完成配置后,使能 SPI2 外设,并开启 SPI2 的 DMA 发送功能。

2. SPI2 数据读写函数

  • Spi2_ReadWriteByte(uint8_t dat):用于向 SPI2 发送一个字节数据并同时接收一个字节数据。通过等待发送缓冲区为空标志 SPI_FLAG_TBE 发送数据,等待接收缓冲区非空标志 SPI_FLAG_RBNE 接收数据。
  • Spi2_Read(void):用于从 SPI2 接收一个字节数据。通过等待接收缓冲区非空标志 SPI_FLAG_RBNE 来获取接收到的数据。
  • Spi2_Write(uint8_t dat):用于向 SPI2 发送一个字节数据。通过等待发送缓冲区为空标志 SPI_FLAG_TBE 来发送数据。

3. SPI2 DMA 初始化函数 Spi2_Dma_Init(void)

  • 时钟使能:使能 DMA0 的时钟。
  • DMA 通道配置
    • 初始化 DMA0 通道 5,方向设置为内存到外设 DMA_MEMORY_TO_PERIPH
    • 内存地址初始化为 0,内存地址自增使能 DMA_MEMORY_INCREASE_ENABLE
    • 外设和内存宽度设置为 8 位 DMA_MEMORY_WIDTH_8BIT
    • 传输数据数量设置为 38400。
    • 外设地址设置为 SPI2 的数据寄存器地址 (uint32_t)&SPI_DATA(SPI2),外设地址自增禁止 DMA_PERIPH_INCREASE_DISABLE
    • 优先级设置为超高 DMA_PRIORITY_ULTRA_HIGH
  • DMA 模式配置
    • 禁止循环模式 dma_circulation_disable(DMA0, DMA_CH5)
    • 选择 DMA 子外设 dma_channel_subperipheral_select(DMA0, DMA_CH5, DMA_SUBPERI0)
  • 中断配置:使能 DMA0 通道 5 的传输完成中断,并配置 NVIC 中断使能。

 

LCD

LCD屏幕根据商家提供的代码移植,但要注意屏幕的是什么驱动的,为ILI9341还是ST7789,需自行对照代码

 

ADC

ADC部分代码概述:

1. adc_config 函数

该函数用于配置ADC、DMA(直接内存访问)、定时器以及相关GPIO(通用输入输出)。具体步骤如下:

  • 时钟使能
    • 使能GPIOA、ADC0、TIMER1和DMA1的时钟。
    • 配置定时器时钟预分频器。
  • GPIO配置:将GPIOA的引脚1配置为模拟输入模式。
  • 定时器配置
    • 初始化TIMER1的基本参数,包括预分频器、计数模式、周期等。
    • 配置TIMER1的通道2为PWM模式1,并设置输出极性、使能输出、配置脉冲值等参数,最后使能TIMER1。
  • DMA配置
    • 初始化DMA1的通道0,配置外设地址、内存地址、数据宽度、传输方向、传输数量和优先级等参数。
    • 选择DMA通道的子外设,使能DMA循环模式和通道,并配置中断使能和NVIC(嵌套向量中断控制器)。
  • ADC配置
    • 配置ADC时钟分频。
    • 设置ADC规则通道长度、通道配置、外部触发、数据对齐、分辨率等参数。
    • 使能ADC的DMA请求和DMA模式,最后使能ADC并进行校准。

2. adc_setio_init 函数

该函数用于初始化与ADC采样相关的IO口。具体操作如下:

  • 使能GPIOF和GPIOB的时钟。
  • 分别配置GPIOF的引脚10和GPIOB的引脚5、7、8为推挽输出模式,设置上拉电阻和输出速度,并初始化为高电平(之后对GPIOB引脚进行了清零操作)。

3. alternating_direct_set 函数

该函数根据传入的参数 gather 的值来设置交流或直流模式。如果 gather 等于 alternating(推测为一个预定义的常量),则将GPIOF的引脚10清零,表示交流模式;否则将该引脚置位,表示直流模式。

4. gather_rate_set 函数

该函数根据传入的参数 rate 的值来设置采样倍率。通过检查 rate 的低三位(分别对应0x01、0x02、0x04),来决定是否将GPIOB的引脚8、7、5置位或清零,从而实现不同采样倍率的设置。

5. adc_speed_set 函数

该函数根据传入的参数 speed 来设置ADC的采样速度。通过修改TIMER1的预分频器值 TIMER_PSC(TIMER1),来调整采样速度。

6. adc_power_set 函数

该函数根据传入的参数 onoff 的值来控制ADC采样的开始和停止。如果 onoff 为真,则使能TIMER1,开始采样;否则禁用TIMER1,停止采样。

 

DAC

DAC部分代码概述:

1. 全局变量

定义了一个全局数组 convertarr,用于存储DAC转换的数据。

2. dac_config 函数

该函数用于配置DAC、DMA(直接内存访问)和定时器相关的硬件资源,具体步骤如下:

  • GPIO配置:使能GPIOA时钟,并将GPIOA的引脚5配置为模拟输入模式,用于连接DAC输出。
  • DAC配置
    • 使能DAC时钟,对DAC进行复位。
    • 配置DAC的触发源为TIMER6的触发输出,使能触发、禁用波形模式、使能输出缓冲。
    • 使能DAC和DAC的DMA功能。
  • DMA配置
    • 使能DMA0时钟,选择DMA0通道6的子外设。
    • 配置DMA通道的参数,包括外设地址、内存地址、传输方向、传输数量、外设和内存地址自增模式、数据宽度、优先级和循环模式等。
    • 初始化DMA通道并使能。
  • 定时器配置
    • 使能TIMER6时钟,配置定时器的预分频器、自动重装载值、主输出触发源,并使能定时器。

3. Dac_Time_Hz 函数

该函数根据传入的频率值 hz 来配置TIMER6的预分频器和自动重装载值,以实现不同频率的DAC输出。根据频率范围不同,采用不同的预分频器设置:

  • 如果 hz 大于 max_wav_fps,则将 hz 限制为 max_wav_fps
  • 当 hz 大于1000时,设置TIMER6的预分频器为0,自动重装载值根据频率计算。
  • 当 hz 大于10且小于等于1000时,设置预分频器为9,自动重装载值相应计算。
  • 当 hz 小于等于10时,设置预分频器为49,自动重装载值再次相应计算。

4. Dac_Show_Wav 函数

该函数用于设置DAC输出的波形。根据传入的波形编号 number,将对应的波形数据(存储在 wav_data 数组中)复制到 convertarr 数组中。如果 number 超出范围,则将其限制为最大波形编号减1。

 

 

1.DSP库的移植

   详情可以参考GD官网的DSP库移植文档,也可以参考STM32F4的DSP库移植,因为它们都是使用的arm公司内核的DSP库。本文档教程仅供参考不同keil版本和库略有差异。

1.1 添加RAM官方DSP库文件到工程

image.png

1.2 打开工程添加编译宏和库文件

USE_HAL_DRIVER,GD32F450xx,ARM_MATH_CM4,__CC_ARM,ARM_MATH_MATRIX_CHECK,ARM_MATH_ROUNDING

image.png

1.3 在代码里面使用FFT

#include "arm_math.h"  

//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初始化一次 scfft结构体
    arm_cfft_radix4_init_f32(&scfft,FFT_LENGTH,0,1);

    //FFT运算
    for(i=0;i>4);
            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;
        }
        
        //FFT运算 <1ms
        for(i=0;i max_fft) max_fft = fft_outputbuf[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;
        }
        
        
        //显示数据
        if(Show_AB)  Lcd_Show_LinA(Show_GramA);
        else Lcd_Show_LinA(Show_GramB);
        
        
        //delay_1ms(200);
    }
}

设计图

未生成预览图,请在编辑器重新保存一次

BOM

暂无BOM

附件

序号文件名称下载次数
1
演示视频.mp4
0
克隆工程
添加到专辑
0
0
分享
侵权投诉

工程成员

评论

全部评论(1
按时间排序|按热度排序
粉丝0|获赞0
相关工程
暂无相关工程

底部导航