
梁山派示波器拓展版
简介
通过学习官方的历程制作了一款示波器
简介:通过学习官方的历程制作了一款示波器开源协议
:GPL 3.0
描述
电路部分
负压电路部分
采用SGM3204YN6G/TR电荷泵将+5V的电压,转换为-5V电压用于给运放供电


模拟输出电路
分压电路
软件部分
串口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
。
- 初始化 DMA0 通道 5,方向设置为内存到外设
- 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库文件到工程
1.2 打开工程添加编译宏和库文件
USE_HAL_DRIVER,GD32F450xx,ARM_MATH_CM4,__CC_ARM,ARM_MATH_MATRIX_CHECK,ARM_MATH_ROUNDING
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


评论