第一次写博客,也是想分享一下自己的心得体会。本人大三,因为准备比赛的缘故,需要做一个示波器,因为不是想做一个成品,所以只是实现了基本功能,后续的话也不会再用这个,更多的是体会过程。此文章主要是给像我这样的初学者一个参考,当时做的时候看到了很多大佬的成品,感觉一上来看一些很完美的代码看不太懂,所以想自己写一个东西。这东西是和同学一起做的,他用另一块单片机进行AD采样,通过串口发送给STM32,然后从寄存器中读出来数据(关于32的AD采集内容可以去看其他大佬的文章)。当时有事没要来他的代码,这里主要说一下有关通信和显示的部分。一块单片机能完成的事情为什么要用两块?文章最后会给出说明。废话不多说,开始进入正题。

1.串口通讯部分

串口设置的一般步骤可以总结为如下几个步骤:

  1. 串口时钟使能, GPIO 时钟使能
  2. 串口复位
  3. GPIO 端口模式设置
  4. 串口参数初始化
  5. 开启中断并且初始化 NVIC(如果需要开启中断才需要这个步骤)
  6. 使能串口
  7. 编写中断处理函数

查看手册得知, 配置全双工的串口 1,那么 TX(PA9)管脚需要配置为推挽复用输出, RX(PA10)管脚配置为浮空输入或者带上拉输入。 模式配置参考下面表格:

串口的GPIO 端口模式设置和初始化都是一些套路性的东西,比较重要的是中断处理函数的编写,这里代码我是参考原子来的,感觉原子哥写的很巧妙:

u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大字节数
//接收状态
//bit15 接收完成标志
//bit13 接收到的有效字节长度
u16 USART_RX_STA=0;       //接受状态标志

因为TFT屏幕用的是ILI9328型号,分辨率240*320,所以在usart.h里把最大字节数定义为260,可以一次性从USART_RX_BUF[ ]中读260个值送入显示。这里我适当修改了原子的中断服务程序:

void USART1_IRQHandler(void)                 //串口1中断服务程序{u8 Res;#if SYSTEM_SUPPORT_OS   //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.OSIntEnter();    #endifif(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断{Res =USART_ReceiveData(USART1); //读取接收到的数据if((USART_RX_STA&0x8000)==0)//接收未完成{if(USART_RX_STA<USART_REC_LEN)  //还可以接收数据    {USART_RX_BUF[USART_RX_STA++]=Res;  //记录接收到的值 }else {USART_RX_STA|=1<<15;     //强制标记接收完成,可以看成0x8000}     } }#if SYSTEM_SUPPORT_OS  //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.OSIntExit();              #endif
} 

原子的程序是接收到回车符视为一次接受完成,考虑到这样会降低通信的效率,所以我把它改成了接收到260个字符视为一次完成。这一段代码好好看看,写的特别好,有些地方也不是很好懂。

/*****************************串口接收***********************************/                                                                                       if(USART_RX_STA&0x8000){        len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度for(t=0;t<len;t++){USART_SendData(USART1, USART_RX_BUF[t]);//向串口1发送数据while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束}USART_RX_STA=0;}
/*************************************************************************/  

我们发送一个数据到串口USART_RX_BUF[ ]中(数据就可以从这个寄存器中取了),之后,要检测这个数据是否已经被发送完成了。 USART_FLAG_TC 是宏定义的数据发送完成标识符。

2.TFT显示部分

首先,在工程中加入和TFTLCD相关的.c文件和.h文件,基本的GPIO定义就不说了。当时做的时候遇到了一个难题,就是如何让LCD横屏显示,如果你是原子的屏,改一个参数就OK了,但我的屏文件里的代码只有一些基本的,胡乱改了好多东西,显示的都是乱码,当时心里是崩溃的,实在是不想放弃,后来硬着头皮查了下LCD和扫描有关的寄存器,终于算是成功了。

1.显存控制方式 (AM、I/D0、I/D1)

2.扫描线控制方式(R01h)



上面说的有点晦涩难懂,简单来说就是修改01h,03h,60h的控制指令。而Write_Cmd_Data0x_ _,0x _ _ )就是分别写入指令和数据,实际上是这一个函数调用了两个函数,简化了代码。

Write_Cmd_Data(0x0001,0x0000);   //set SS and SM bit //设置扫描方向
Write_Cmd_Data(0x0003,0x1038);   //set Entry Mode  //设置进入模式
Write_Cmd_Data(0x0060,0xA700); // Gate Scan Linevoid LCD_SetPos(unsigned int x0,unsigned int x1,unsigned int y0,unsigned int y1)
{Write_Cmd_Data(0x50,y0);  // Horizontal GRAM Start AddressWrite_Cmd_Data(0x51,y1);  // Horizontal GRAM End AddressWrite_Cmd_Data(0x52,x0);  // Vertical GRAM Start AddressWrite_Cmd_Data(0x53,x1);  // Vertical GRAM Start AddressWrite_Cmd_Data(0x20,y0);  // GRAM horizontal AddressWrite_Cmd_Data(0x21,x0);  // GRAM Vertical AddressWrite_Cmd(0x00,0x22);    // 0x0022,Start to Write Data to GRAM
}

下面是我总结的表格:

LCD 扫描指令1 LCD扫描指令2
0x01, 0x0000 0x01, 0x0100
0x03, 0x1038 0x03, 0x1030
0x60, 0xA700 0x60, 0x2700

把0x20和0x21后面的参数互相调一下,上面的带代码已经调过了。
不同型号的屏的修改方式不同,不同人写的代码,这几个函数的写法也不同,大家可以自己修改尝试一下,大概有8种可能的显示方式(因为有些组合是乱码)。

接下来就是从USART_RX_BUF[ ]中取数据的程序,

for(n=0;n<260;n++) //从串口寄存器中取{adc1[n]=USART_RX_BUF[n];}for(n=0;n<260;n++) {adc[n]=16*(adc1[n])+adc1[n+1]+120;}

这里多加了一个adc1[ ]数组作为过渡,不写这个的话不知道为什么取出来的数莫名其妙的变得特别大,后来把这几个寄存器中的值都显示出来计算分析了一下找到了问题所在。因为我接收到的数值是十六进制的,所以在取高位时乘了16。刚开始认为得到的值是ASCII码,应该减去**‘0’**才是真值,但那样写了不对,所以就删掉了。在接收数据之前,可以先自己用串口调试助手调试一下,给大家看一下我调试的结果:

右边的频率和峰值什么的参数,本来是想加的,但时间不允许了,就把它糊弄过去了,要加的话,只需让发送方周期性的发送这些信息(例如每发260个点发一次)。波形还是挺漂亮的!

3.示波器最终效果(半成品)


采样的波形把网格线刷掉了,时间原因就没有去掉,之前从网上看到过,是一篇LCD的“或关系”显示的文章,有想完善的朋友可以完善一下。出现了波形失真是因为当时用信号发生器时忘了加直流偏移量,一般要加到峰峰值的一半以上,AD采样的芯片采不到真正的0,忘加直流偏移量可能会烧芯片,幸好我们的没烧。这里说明一下为什么要用通信的方法,单片机外设接的多了必然会影响速度,而且采样到的波形会有很多毛刺,所以真正显示的波形以后要改成自己生成的所谓的“完美波形”,串口发送的也不再是一系列的点,而是波形的信息。
当然还有一点更重要的,提供的单片机的型号是STM32F103C8T6,端口实在是少得可怜,插上TFT屏之后ADC端口就用不了了,改端口的话还要自己插线,麻烦得很,就偷了个懒。

代码在下面的链接里,大家可以自行下载:
STM32简易示波器
https://download.csdn.net/download/qq_42628795/10926556

如果觉得还不错的话,求个点赞啊!!!

STM32简易示波器相关推荐

  1. stm32简易示波器(标准库)

    简介 此项案例是基于正点原子精英板制作的一个简易示波器,可以读取信号的频率和幅值,并可以通过按键改变采样频率和控制屏幕的更新暂停. (输入最大3.3V,由ADC参考电压决定) 将PA6与PA4相连,可 ...

  2. 【单片机开发】STM32简易示波器开发

    文章目录 (一)前言 (二)硬件介绍 (1)MCU (2)TFT显示屏 (3)按键接口 (三)驱动编程 (1)ADC驱动 (2)LCD驱动 (3)一路测试PWM (四)FFT原理 (四)操作逻辑 (五 ...

  3. STM32简易示波器开发总结

    考研失利不用准备复试了,有了空闲时间做了个示波器,带宽80Khz,输入幅度0-3.3V,带有触发功能,接近实时的波形显示和FFT计算,不过存储深度太小了只有1024个点.最近要准备工作的面试了之后有时 ...

  4. 基于STM32的开源简易示波器项目

    目录 ​一.前言 二.硬件接线 三.信号的采集 四.代码配置 五.数据的处理 六.模拟正弦波输出 七.模拟噪声或三角波输出 八.显示函数与按键控制 ​一.前言 该项目是基于正点原子精英板制作的一个简易 ...

  5. 基于STM32的简易示波器的UCOS II嵌入式实时操作系统实现

    基于STM32的简易示波器的UCOS II嵌入式实时操作系统实现 在基于STM32的示波器的实现的基础上,在STM32上移植UCOS II嵌入式实时操作系统. 在UCOS II操作系统中将各个功能分发 ...

  6. 基于STM32的简易示波器项目(含代码)——HAL库

            前言:本文基于STM32的简易示波器项目,示波器作为嵌入式开发中必不可少的器件,其使用方式和工作原理是必须被掌握的.巧妙利用STM32可以实现媲美度非常高的示波器,本文中的简易示波器主 ...

  7. 基于STM32F103的简易示波器设计

    基于STM32F103的简易示波器设计(基于正点原子mini开发板) 摘要 本设计采用STM32F103微控制器,硬件为正点原子的MiniSTM32开发板,设计一个示波器,能够测量输入信号的频率.最大 ...

  8. 简易波形系统(简易示波器部分)

    简易波形系统(简易示波器部分) 具体知识内容: 1.整体框图 2.示波器重要驱动和软件设计 整体框图 一.示波器重要驱动和软件设计 <1>重要驱动设计(PWM) 1.ADC+DMA+TIM ...

  9. 基于stm32mini开发板的简易函数发生器和简易示波器

    基于stm32 mini开发板的简易函数发生器和简易示波器 前言:用正点原子的mini开发板,设计制作简易示波器和简易函数发生器,需要运用的知识是 ADC+DAC+DMA+通用定时器+外部中断. 一. ...

最新文章

  1. C#日期格式精确到毫秒 !!
  2. day 58 关于bootstrap
  3. 小程序canvas绘制商品海报实现分享朋友圈
  4. 产品更新教程-钉钉宜搭版本:手写签名和定位组件来了
  5. 判断1个整数的二进制形式的1的个数
  6. mcf5271如何使用数学库函数
  7. vagrant up 慢的解决方案
  8. 剑指offer之构建乘积数组
  9. 工作中遇到的问题 二 乱码问题
  10. java 微信导航栏_微信小程序教程系列之设置标题栏和导航栏
  11. websocket实时聊天(一)
  12. 恋爱APP软件开发基本功能
  13. 图像处理之图像分割(一)之活动轮廓模型:Snake算法简单梳理
  14. centos7 单机安装 greenplum6
  15. 9.11 myl模拟赛
  16. 软件测试与治学的三重境界
  17. android 播放器 sma,SMA测评软件下载-SMA测评安卓版v1.1.2-魅卓网
  18. Redhat7.4 同步阿里云镜像rpm包并自建本地yum仓库
  19. 传奇游戏应该选择什么样的服务器?
  20. 如何判断一个bean是不是pojo 或者说简单bean by Introspector 和反射

热门文章

  1. 百度地图这十年如何一步步干掉了强悍的对手?
  2. Python编程:itertools库排列组合
  3. freeCodeCamp Slasher Flick
  4. markdown快速插入图片技巧
  5. 18天精读掌握《费曼物理学讲义卷一》 第4天 2019.6.17
  6. HTML微信单页引流项目源码模板分享
  7. 【Linux-Windows】猫、路由器、交换机
  8. 【优化求解-单目标求解】基于黑猩猩算法求解单目标问题matlab源码
  9. 在Docker中安装Home Assistant系统(以群晖系统为例)【Home Assistant入门安装篇1-2】
  10. 软件测试面试题之用例设计题