寒假在家一起练———基于stm32g031的DIY简易示波器
基于STM32G031的DIY简易示波器,可实现两路信号采集并显示,特定频率信号发生。
标签
嵌入式系统
Charlotte
更新2021-03-07
1555

      项目提交时间延迟了一周,上周以为截止时间快到了,就提交了一次,然而主办方审核没通过,让我再完善功能……怎么说呢,也不是才学stm32没几天,压根就没怎么正经学,自己第一次尝试做出成果,如有错误,还请大佬指正。

1、实现功能

(1)通过Ain管脚测量外部模拟信号(0-3.3V,DC-100KHz)通过ADC对外界模拟输入进行采样,将采样得到的ADC量化值显示在屏幕坐标点上,显示波形。

(2)通过Mic测量外部音频信号。

(3)通过按键来改变电压量程实现波形在纵轴上的变换(0.1v、0.4v、0.6v、0.8v、1.0v),改变采样频率实现波形时间轴上的变换(采样率1KHz、2KHz、4KHz、10KHz、20KHz、40KHz、100KHz、200KHz)。

(4)通过Aux管脚输出特定定频率正弦波、方波、三角波。

2、实现思路

(1)示波器显示

  • ADC双通道连续扫描,实现AD转换
  • 定时器触发采样,改变定时器预分频值和重装载值改变采样频率;(我一直不太懂大佬们ADC软件触发是怎么实现频率变化的)
    void Samplingrate_Init(uint32_t Rate)//采样率
    {
    	if(Rate>=500000)
    	{
    	  LL_ADC_SetSamplingTimeCommonChannels(ADC1, LL_ADC_SAMPLINGTIME_COMMON_1, ADC_SAMPLETIME_1CYCLE_5);
    	  LL_ADC_SetSamplingTimeCommonChannels(ADC1, LL_ADC_SAMPLINGTIME_COMMON_2, ADC_SAMPLETIME_1CYCLE_5);
    	}
    	else if(Rate>=200000)
    	{
    	  LL_ADC_SetSamplingTimeCommonChannels(ADC1, LL_ADC_SAMPLINGTIME_COMMON_1, ADC_SAMPLETIME_7CYCLES_5);
    	  LL_ADC_SetSamplingTimeCommonChannels(ADC1, LL_ADC_SAMPLINGTIME_COMMON_2, ADC_SAMPLETIME_7CYCLES_5);
    	}
    	else if(Rate>=100000)
    	{
    	  LL_ADC_SetSamplingTimeCommonChannels(ADC1, LL_ADC_SAMPLINGTIME_COMMON_1, ADC_SAMPLETIME_12CYCLES_5);
    	  LL_ADC_SetSamplingTimeCommonChannels(ADC1, LL_ADC_SAMPLINGTIME_COMMON_2, ADC_SAMPLETIME_12CYCLES_5);
    	}
    	else if(Rate>=40000)
    	{
    	  LL_ADC_SetSamplingTimeCommonChannels(ADC1, LL_ADC_SAMPLINGTIME_COMMON_1, ADC_SAMPLETIME_39CYCLES_5);
    	  LL_ADC_SetSamplingTimeCommonChannels(ADC1, LL_ADC_SAMPLINGTIME_COMMON_2, ADC_SAMPLETIME_39CYCLES_5);
    	}
    	else
    	{
    	  LL_ADC_SetSamplingTimeCommonChannels(ADC1, LL_ADC_SAMPLINGTIME_COMMON_1, ADC_SAMPLETIME_160CYCLES_5);
    	  LL_ADC_SetSamplingTimeCommonChannels(ADC1, LL_ADC_SAMPLINGTIME_COMMON_2, ADC_SAMPLETIME_160CYCLES_5);
    	}
    
    	if(Rate==10000)
    	{
    		__HAL_TIM_DISABLE(&htim1);
    		TIM1->ARR = 8000000/Rate-1;
    		TIM1->PSC = 8-1;
    		__HAL_TIM_ENABLE(&htim1);
    	}
    	else if(Rate<=20)
    	{
    		__HAL_TIM_DISABLE(&htim1);
    		TIM1->ARR=10000/Rate-1;
    		TIM1->PSC=6400-1;
    		__HAL_TIM_ENABLE(&htim1);
    	}
    	else
    	{
    		__HAL_TIM_DISABLE(&htim1);
    		TIM1->ARR=1000000/Rate-1;
    		TIM1->PSC=64-1;
    		__HAL_TIM_ENABLE(&htim1);
    	}
    	MX_TIM1_Init();
    }
  • DMA连续访问

(2)信号发生

  • SPWM,PWM回调函数(这部分参考了已发布案例里其他同学的代码)
    void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    {
        if (htim->Instance == TIM2)
    	{
        	htim->Instance->CCR2 = pwm[pwm_a][pwm_count++];
        			if(pwm_count>127)
        				pwm_count=0;
    	}
    }​

 

3、未完成的功能以及未来计划

(1)信号发生功能。Aux波形输出只能输出特定频率,通过寄存器修改定时器预分频系数效果不太好。

(2)快速傅里叶变换,显示信号的频谱。因为时间有限,而且还是没理解原理。

(3)菜单界面实现。当前功能键实现功能不够清晰,希望能用菜单界面实现功能扩展。

 

4、遇到问题

  • 通过外部更改预分频值和重装载值同时还要更改ADC的采样周期,否则波形显示不改变。
  • 定时器初始化时预分频值和重装载值要先设置,一开始我直接在初始化函数的时候用Samplingrate_Init函数通过寄存器修改定时器的ARR和PSC,但是出现了有点类似掉帧的现象。
  • 功能页面切换时,清屏函数的处理。起初放在外部中断函数里或者其他地方,导致页面无法正常显示或清屏不完全,后来是在主程序加入循环时做一个判断。
  • 提醒大家千万千万不要小看焊接,一开始以为把管脚焊短路了,板子闲置了大半个月。

 

5、收获与总结

  • 第一次用单片机做出成品来,虽然还有很多地方没有理解透彻,很多功能没能实现……但是对单片机的认识不只是看视频、例程还有做实验了!
  • cubeIDE的使用,在做这个项目之前只是看教学视频学习写标准库代码,用cubeIDE大大提高了效率,但是还是没能用LL库写(网上的例程教程太少)
  • 学好数学很重要。

MiniScope.bin

MiniScope.zip

团队介绍
南京信息工程大学
团队成员
杨乐晴
南京信息工程大学 人工智能学院 信息工程
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号