STM32学习——入门小项目

这个小项目是来自参加电设时,老师发的STM32入门(进阶)任务,具体的要求如下:

软件设计要求

  1. 编写简单I/O程序,能用板上的4个基本按键控制10个LED灯的亮灭。(扩展要求:设计不同的流水灯或呼吸灯效果,并能用按键切换)
  2. 编写显示模块的显示程序,能在显示屏上显示欢迎信息,欢迎信息包括学号姓名。(扩展要求:能模拟广告牌的文字滚动显示效果,并用按键控制滚动方向和速度)
  3. 编写程序输出PWM波形(频率为100kHz,占空比通过按键可调),能把设置参数存错于I2C接口的EEPROM或SPI Flash或MCU片内Flash中,掉电重启后自动使用存错的参数
  4. 综合设计:使用MCU中的ADC采集1kHz正弦波信号(幅度不做要求),在显示屏上显示该信号波形与幅度值,要求稳定显示正弦波(提示:设置触发)
  5. 综合设计:一个低频信号发生器。具备以下功能:使用STM32的DAC输出功能,生成10KHz以下方波、三角波、锯齿波、正弦波。能在液晶屏上显示频率、信号类型。可用按键切换输出信号类型、频率。要求波形尽可能平滑完整,幅度固定1V;频率可调1KHz~10KHz,步进100Hz。
  6. 综合设计:使用STM32的定时器信号捕捉功能,测量标准信号发生器输出的正弦波信号频率,测量范围100Hz~3MHz,精度1%

该任务的具体代码请移步https://github.com/Zcj119303/STM32_Oscilloscope(PS:因为疫情,板子在学校,等回去了在上传展示效果。。。。。。)

该软件设计要求,最高标准是能够把上述的6个设计集成在一个程序当中,在切换时不需要重新烧录代码,因此我在设计的时候,使用了操作系统UCos,来达到任务切换的目标,并且使用UCos使得我在第4个设计中,能够使用Graph控件显示波形,使得显示更为美观。

接下来,我将详细介绍整个工程的架构。

该工程由6个窗口组成,其中主界面,作为函数刚进入的界面,由5个按键组成,分别进入每一个任务窗口,其中第4、6个任务合并成了一个任务。

任务1、2作为STM32的入门任务我这里就不做的描述,在界面上,任务1使用了13个按键,10个按键用来控制任意一个IO的高低电平,即LED的亮灭,另外三个按键,分别是Water lamp(流水灯)、Breathing lamp(呼吸灯)以及ESC(用于返回主界面),任务2使用了7个按键,分别控制字的上下左右移动,速度的增加与减少,以及ESC按键。另外,关于任务的切换,我会在后面有所描述。

任务3采用的PWM生成的定时器是TIM14,存储参数使用的SPI Flash(即代码中W25QXX的部分)。任务3的界面使用了14个按键,其中10个按键组成了数字键盘,Output按键用来波形的输出,Store按键用来存储参数,Backspace用来在输入参数时进行退格,ESC按键用来返回主界面。

任务4是整个任务的核心,因此我先讲任务5。任务5的界面由7个按键和一个Graph组成,其中七个按键分别是Sine Wave(正弦波),Triangular wave(三角波),Square wave(方波),Sawtooth wave(锯齿波),Frequence++(频率增加),Frequence–(频率降低)(频率步进100Hz)以及ESC。Graph是画图控件,也是任务4的主要控件,具体我将在后面介绍,在任务5中,Graph将根据你的按键来显示波形,提示用户现在输出的是属于哪一类波形。

在波形的产生上,具体可参照HardWare中的waveoutput.c,其中描述了生成波形表,用DMA连接DAC输出波形。关于DMA的配置可以详细了解该文件。(后续有机会会再分享一个有关DMA的应用,不过具体…咕咕咕…)

最后,就是这个任务的难点了,任务4——简易的低频示波器(不完善)。有一说一,任务4只是STM32制作示波器的门缝,通过该门缝,我们可以一窥示波器的风采。

STM32来做示波器的话,有许多的技术要点,譬如触发功能、等效采样、FFT频谱,相对而言,显示幅值,周期的调整反而是一项比较容易实现的功能。

在这个任务4中,他要求能够设置触发,因为STM32的功能有限,在这个任务中我做了一个简易触发——用外部中断来进行触发,当信号触发外部中断时,ADC进行采样。

具体设计流程图如下

设计流程

当信号输入,一个上升沿触发外部中断,外部中断中关闭外部中断并使能ADC和DMA(在这里,因为库函数没有相关的函数,因此用了寄存器的操作,详细信息可以去看看STM32的数据手册),ADC采集信号的频率是靠Timer3来进行控制(这也是是一个蛮秀的操作),ADC采集到的数据通过DMA传输到内存的Buff中,当DMA传输完成后,会进入DMA中断,在DMA中断中会告知Graph显示波形,Graph波形显示后会重新打开外部中断,这时会在进入第二次循环。

上述就是整个设计流程,有关Graph控件的使用可以参照正点原子的EMwin开发手册,在这里我使用的是GRAPH_DATA_YT_AddValue函数,该函数每输入一个值,图像自动后移。

有关于任务6的测频可以参照我之前的文章中的stm32定时器外部中断的配置,链接如下https://infinite-zh.com/archives/56

最后来讲一下有关于界面的切换,在这个任务中最麻烦的是将这6个任务集成起来,不过如果使用上了Emwin也不算复杂,一般任务切换都是用按键切换,在这个任务中,我用了前文提到的ESC按键来进行界面的切换,而在ESC按键的释放后,使用了如下的函数

GUI_EndDialog(pMsg->hWin, 0);
CreateMain();

其中GUI_EndDialog是很必要的,如果不使用这个函数可能会导致在切换了几次界面后整个程序卡死,这是因为没有将窗口关掉。

而在界面切换的过程中,需要注意的是,要将在这个界面中所启用的外设给关掉,不然他会影响你在下一个界面中任务。

关于本个任务4的升级:这个其实只是一个简易的STM32示波器,具有的功能很少,它还可以有很高的前景如:

  1. 使用FPGA控制高速ADC采集信号,提高带宽;
  2. 加入FFT频谱等功能;
  3. 使用等效采样,进一步扩大带宽;
  4. 能够任意修改触发的电压值;
  5. 能够显示李萨如图像等。

头像

SNinfinite

立志成为Double E的程序猿

You may also like...

发表评论

电子邮件地址不会被公开。 必填项已用*标注