标题: STM32数字示波器+详细注释+上位机程序+硬件 [打印本页]
作者: 51hei大小 时间: 2016-6-17 12:25
标题: STM32数字示波器+详细注释+上位机程序+硬件
从朋友得知ST公司在搞活动,可以申请STM32F429的探索套件,作为穷学生一枚的我不免动了心。大二上学期参加完全国大学生电子设计竞赛之后闲来无事,就自己做了一个数字示波器来作为学习STM32的实战检验,前后花费了大概1个月的时间完成了初稿,之后又断断续续的完善我的示波器,并且为它编写了上位机程序和制定了通信协议。使用了前端程控模拟电路和上层电路板,uCOS-II,uCGUI,FFT,SD,上位机等等,现在因为参加老师的项目研发也就暂时闲置了下来,之前就打算在各大论坛开源,但是一直没有时间整理设计文档,恰巧现在ST公司这个活动,所以就全部开源分享给大家吧,一起学习。下一步计划重新设计模拟电路部分使用CPLD和高速AD实现更高的采样率。
由于程序量比较大,所以在程序中我完成了大量的注释,详细的说明了具体的实现方法,其中的示波器原理和FFT原理请自己查阅相关教材。我个人认为最值得参考的就是如何制定一个效率较高的通信协议。我查阅了很多资料最后结合实际设计了一套通信协议,这套通信协议效传输速率理论最大可达16000bps,实际采用10666bps速率传输。协议的编码、解码算法的详细说明附在附件中。随着程序量的增加,F103也渐渐感到比较吃力了,其中FFT的运算就是典型代表,也希望借此机会申请到F429带DSP指令的MCU来进一步提高示波器的性能。
限于目前的知识水平,这套示波器是实践大于理论的产物,其中很多设计存在先天的不足,以后会继续改进,向更高性能迈进。
设计指标:
主控: STM32F103ZET6
液晶屏: 4.3寸TFT480×272 65K彩色LCD显示屏 FSMC
AD: 12位1MHz采样率
最高实时取样率: 1MSa/s 12Bits
取样缓冲器深度: 5K
垂直灵敏度: 5V,1V,500mV,200mV,100mV,50mV,20mV,10mV;
水平时基范围:2S,1S,500mS,200mS,100mS,50mS,20mS,10mS,5mS,2mS,1mS,500uS,200uS,100uS,50uS,20uS,10uS,5uS,2uS,1uS
输入阻抗: ≥1MΩ
最高输入电压: 30Vpp
耦合方式: AC/DC
触发功能: 实现自动、常规、单次触发方式 ,上升或下降边沿触发
参数计算: 频率、周期、占空比、交流峰-峰值、平均值、光标追踪显示
RUN/STOP
功能:
1、波形发生器:使用STM32一路DA实现正弦,三角波,方波,白噪声输出。 任意一种波形幅值在0-3.3V任意可调、频率在一定范围任意可调、方波占空比可调。调节选项可以通过触摸屏完成设置。
2、SD卡存储: SD卡波形存储输出,能够对当前屏幕截屏,以JPG格式存储在SD卡上。能够存储1S内的波形数据,可以随时调用查看。
3、数据传输: 用C#编写上位机,通过串口完成对下位机的控制。(1)实现STOP/RUN功能(2)输出波形电压、时间参数(3)控制截屏(4)控制波形发生器(5)控制完成FFT(6)波形的存储和显示
4、图形接口: UCGUI
2、水平扫速: 250 ns*、500ns、1μs、5 μs、10μs、50μs、500 μs、5ms 、50ms
3、垂直电压灵敏度:10mV/div, 20mV/div, 50mV/div, 0.1V/div, 0,2V/div, 0.5V/div, 1V/div,
2V/div, 5V/div
4、被测信号的各种参数屏幕显示,包括频率、电压峰峰值等。
这是上位机的程序
测试时候的照片
测试正弦波
PCB
模拟电路板
侧面的照片
源代码的注释
|
- /*---------------------------------------------------------
- ADC配置驱动程序
- 说明: 示波器AD采样配置,经过初步测试,AD采样速率为1.286M
- 正弦波最大不失真测量频率300kHz
- 三角波最大不失真测量频率150kHz
- 矩形波最大不失真测量频率100kHz
- 时间: 2013年11月19日
- ---------------------------------------------------------*/
- #include "stm32f10x.h"
- #include "adc.h"
- #include "oscilloscope.h"
- #include "ucos_ii.h"
- #include "tft_api.h"
- /*-----------------------------------------
- 声明变量
- ------------------------------------------*/
- extern WaveType WaveInfo;
- extern WaveMode WaveCtrl;
- volatile u16 ADCConvertedValue[SAMPDEPTH];//AD转换缓冲区,占用RAM 0.8KB
- /*-----------------------------------------
- ADC1端口初始化
- ------------------------------------------*/
- void ADC1_GPIO_Init(void)
- {
- GPIO_InitTypeDef IO_Init;
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC,ENABLE);
- //C1模拟输入
- IO_Init.GPIO_Pin = GPIO_Pin_1;
- IO_Init.GPIO_Mode = GPIO_Mode_AIN;
- GPIO_Init(GPIOC,&IO_Init);
- }
- /* #define ADC1_DR_Address ((unsigned int)0x40012400+0x4c) */
- /* unsigned short int ADC1_DMA_Value; */
- /*--------------------------------------------------
- 函数说明:配置ADC1完成AD采集,是本示波器最核心的部分.
- 配置方案:ADC1由TIM3提供的触发事件进行触发AD转换,控
- 制TIM3的速率就可以完成采样率的改变.同时采
- 用DMA完成数据传输,注入通道1完成内部温度传
- 感器AD采集.
- --------------------------------------------------*/
- void ADC1_Mode_Config(void)
- {
- //配置DMA
- DMA_InitTypeDef DMA_csh;
- ADC_InitTypeDef ADC_csh;
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
- DMA_DeInit(DMA1_Channel1); //DMA复位,通道1
- DMA_csh.DMA_PeripheralBaseAddr = ADC1_DR_Address; //ADC1地址
- DMA_csh.DMA_MemoryBaseAddr = (unsigned int)ADCConvertedValue; //内存地址
- DMA_csh.DMA_DIR = DMA_DIR_PeripheralSRC;
- DMA_csh.DMA_BufferSize = SAMPDEPTH; //缓冲大小为采样深度
- DMA_csh.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址固定
- DMA_csh.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址自增
- DMA_csh.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
- DMA_csh.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
- DMA_csh.DMA_Mode = DMA_Mode_Circular; //循环传输
- DMA_csh.DMA_Priority = DMA_Priority_High; //DMA优先级高
- DMA_csh.DMA_M2M = DMA_M2M_Disable;
- DMA_Init(DMA1_Channel1,&DMA_csh); //写入DMA1配置参数
- DMA_Cmd(DMA1_Channel1,ENABLE); //使能DMA1通道1
- DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE); //使能DMA CH1中断
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
- NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- //配置TIM3工作在18MHz,为AD提供触发
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
- TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
- TIM_TimeBaseStructure.TIM_Period = 1;
- TIM_TimeBaseStructure.TIM_Prescaler = 99; //工作在18M,每格最大值时,不至于溢出
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
- TIM_SelectOutputTrigger(TIM3,TIM_TRGOSource_Update); //使用TIM3事件更新作为ADC触发
-
- //配置ADC
- ADC_csh.ADC_Mode = ADC_Mode_Independent; //独立ADC模式
- ADC_csh.ADC_ScanConvMode = DISABLE; //关闭扫描模式
- ADC_csh.ADC_ContinuousConvMode = DISABLE; //连续AD转换开启
- ADC_csh.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T3_TRGO; //由TIM3提供的触发事件进行触发AD转换
- ADC_csh.ADC_DataAlign = ADC_DataAlign_Right; //数据右对齐
- ADC_csh.ADC_NbrOfChannel = 1; //要转换的通道数目1
- ADC_Init(ADC1,&ADC_csh); //写入ADC1配置参数
- ADC_RegularChannelConfig(ADC1,ADC_Channel_11,1,ADC_SampleTime_1Cycles5);//采样速率1M
- ADC_DMACmd(ADC1,ENABLE); //使能ADC1 DMA
- ADC_ExternalTrigConvCmd(ADC1,ENABLE); //打开ADC1外部触发
-
- ADC_InjectedChannelConfig(ADC1,ADC_Channel_16,1,ADC_SampleTime_239Cycles5); //配置ADC1通道16为注入通道1
- ADC_ExternalTrigInjectedConvConfig(ADC1,ADC_ExternalTrigInjecConv_None); //软件触发注入通道的转换
- ADC_TempSensorVrefintCmd(ENABLE); //使能温度传感器
- ADC_Cmd(ADC1,ENABLE); //使能ADC1
- ADC_ResetCalibration(ADC1); //复位校准寄存器
- while(ADC_GetResetCalibrationStatus(ADC1)); //等待校准寄存器复位完成
- ADC_StartCalibration(ADC1); //开始校准
- while(ADC_GetCalibrationStatus(ADC1)); //等待校准完成
- TIM_Cmd(TIM3,ENABLE);
- }
- /*-----------------------------------------
- 函数说明:通过注入通道1转换内部温度传感器
- AD值,读取10次有效数据取平均返回
- ------------------------------------------*/
- u16 GetTempSensor(void)
- {
- u16 temp=0,i,k=0;
- for(i=0; i<10; )
- {
- ADC_SoftwareStartInjectedConvCmd(ADC1,ENABLE); //软件触发注入通道的转换
- k = (0x6EE - ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_1)) / 0x05 + 25;
- if(k>0 && k<100)
- {
- temp += k;
- i++;
- }
- }
- temp /= 10;
- return temp;
- }
- /*-----------------------------------------
- 函数说明:ADC1初始化
- ------------------------------------------*/
- void ADC1_Init(void)
- {
- ADC1_GPIO_Init();
- ADC1_Mode_Config();
- }
- /*-----------------------------------------
- 函数说明:ADC传输DMA通道1中断服务程序
- DMA把AD值传输到缓冲区完成后关闭定
- 时器3(作为触发AD转换的定时器)同时
- 置更新完成标志位为1,开定时器3在应
- 用中开启.
- ------------------------------------------*/
- void DMA1_Channel1_IRQHandler()
- {
- OSIntNesting++;
- DMA_ClearFlag(DMA1_FLAG_TC1); //清除DMA传输完成中断
- TIM_Cmd(TIM3,DISABLE); //关闭TIM3
- WaveCtrl.UpdatTrue = 1; //已经完成一次波形FIFO,可以批量读出数据
- OSIntExit();
- }
- /*-----------------------------------------
- 函数说明:擦除AD缓冲区
- ------------------------------------------*/
- void Earse_AD_FIFO(void)
- {
- uint32_t i;
- for(i=0; i<sampdepth; i++)
- {
- ADCConvertedValue[i] = 0;
- }
- }
复制代码
- /*------------------------------------------------------------------------------------
- STM32示波器
- 硬件平台:
- 主控器: STM32F103ZET6 64K RAM 512K ROM
- 屏幕器: SSD1963
- 分辨率: 480x272 16位色
- 触摸屏: TSC2046
- 模拟电路: OP - TL084
- OP - u741
- SW - CD4051
- CMP - LM311
- PWR - LM7805
- - LM7905
- - MC34063
- - AMS1117-3.3
- DRI - ULN2003
- 继电器:信号继电器
- 电源: DC +12V
- 软件平台:
- 开发环境: RealView MDK-ARM uVision4.10
- C编译器 : ARMCC
- ASM编译器:ARMASM
- 连接器: ARMLINK
- 实时内核: uC/OS-II 2.90实时操作系统
- GUI内核 : uC/GUI 3.90图形用户接口
- 底层驱动: 各个外设驱动程序
-
- ROM Size = Code + RO-data +RW-data
- RAM Size = RW-data + ZI-data
- Program Size: Code=56024 RO-data=8272 RW-data=256 ZI-data=29912
-
- 时间: 2013年11月9日 BoX编写于大二上学期
-
- 版本: V1.0 - 2013/11/9
- V1.1 - 2014/2/8
- V3.0 - 2014/2/19
- -------------------------------------------------------------------------------------*/
- #include "stm32f10x.h"
- #include "ucos_ii.h"
- #include "app.h"
- #include "GUI.h"
- #include "usart1.h"
- #include "pincfg.h"
- #include "delay.h"
- #include "tft_api.h"
- #include "dac.h"
- #include "adc.h"
- #include "iwdg.h"
- #include "timer.h"
- #include "EXTI.H"
- #include "oscilloscope.h"
- #include "indkey.h"
- #include "tsc2046.h"
- #include "task_rtc.h"
- #include "task_gui.h"
- #include "task_sd.h"
- /*-----------------------------------------
- 声明起始任务栈
- ------------------------------------------*/
- OS_STK Task_Start_Stk[TASK_START_STK_SIZE];
- /*-----------------------------------------
- 因为涉及到对共享资源的访问,创建互斥信号量
- ------------------------------------------*/
- OS_EVENT *LCD_Buffer_MUTEX;
- OS_EVENT *USART_Buffer_MUTEX;
- OS_EVENT *SDtoRAM_Buffer_MUTEX;
- /*-----------------------------------------
- 主 函 数
- ------------------------------------------*/
- int main(void)
- {
- INT8U err;
- SystemInit(); //初始化RCC时钟
- OSInit();
-
- LCD_Buffer_MUTEX = OSMutexCreate(4,&err); //创建3个共享资源互斥信号量
- USART_Buffer_MUTEX = OSMutexCreate(4,&err);
- SDtoRAM_Buffer_MUTEX = OSMutexCreate(4,&err);
-
- OSTaskCreate(Task_Start,(void *)0,&Task_Start_Stk[TASK_START_STK_SIZE-1],TASK_START_PRIO); //起始任务
-
- OSStart();
- }
- /*-------------------------------------------------------------------------------
- 函数功能:初始化各种外设
- 说 明:因为跑操作系统,所以外设的初始化应该放在操作系统的初始任务中完成,不能
- 在while(1)循环外部完成外设的初始化工作,否则操作系统可能无法启动.
- 本函数在app.c中被调用
- -------------------------------------------------------------------------------*/
- void BSP_Init(void)
- {
- OS_CPU_SR cpu_sr = 0u;
- OS_ENTER_CRITICAL();
- DelayInit(); //初始化延时
- PinCfg(); //外部器件控制配置
- FSMC_LCD_Init(); //FSMC总线配置
- GUI_Init(); //初始化UCGUI界面
- TSC2046_Config(); //初始化触摸控制器
- USART1_Config(); //初始化串口
- DAC_Config(); //初始化DAC1
- ADC1_Init(); //初始化ADC1
- EXTI_Config(); //初始化外部中断
- Key_EXTI_Config(); //初始化按键中断
- TIM5_Config(1999,71); //TIM5以1MHz频率计数,每2ms溢出中断
- // TIM4_Config(59999,71); //TIM4以1MHz频率计数,每60ms溢出中断
- RTC_Init(); //初始化RTC
- // SD_Init();
- JDQ_ACDC = 1; //交流耦合
- ManualGainScan(3); //调试用
- IWDG_Init(4,625); //喂狗时间为1000ms
- OS_EXIT_CRITICAL();
- }
复制代码
由于完整程序包较大,完整程序包可到百度网盘下载,下载链接在附件里
作者: admin 时间: 2016-8-14 14:49
51黑有你更精彩!!!
作者: justtalk 时间: 2016-8-18 13:35
有分享精神必须赞。
作者: 飞翔的土豆 时间: 2016-8-19 12:36
多谢分享哦
作者: angelsrc123 时间: 2016-8-19 14:36
有分享精神必须赞。
作者: 泪珠儿 时间: 2016-8-19 18:48
楼主你的百度云链接失效了,可以给我发下你设计的详细资料吗?万分感谢。
qq邮箱819534212@qq.com
作者: az_cc 时间: 2016-8-22 08:14
谢谢分享!
作者: at87c573 时间: 2016-9-20 09:33
版主厉害啊
作者: dmgy343 时间: 2016-11-14 15:51
好东西,收藏了
作者: dmgy343 时间: 2016-11-14 15:52
好东西收藏了
作者: mayao7 时间: 2016-11-17 10:38
51有你更精彩
作者: 邰夏留 时间: 2016-11-21 08:43
谢谢楼主分享,下载了就顶贴,养成良好的习惯,也方便新手学习。。
作者: ahljj 时间: 2017-1-28 00:14
版主厉害
作者: aliceqiu123 时间: 2017-2-7 14:00
感谢分享。
作者: 心若在 时间: 2017-3-11 11:02
学习一下
作者: zltwork 时间: 2017-3-14 17:49
好东西,谢谢
作者: zhanglu 时间: 2017-3-15 20:56
51有你更精彩
作者: 51jia 时间: 2017-4-4 01:04
感谢楼主分享,下来学习一下。
作者: 唐不是甜的 时间: 2017-4-14 22:44
想问一下大神们 如果用STM32F103RCT6这种不同型号 有差不多的单片机 需要改哪些东西啊?
作者: alai318 时间: 2017-4-15 09:23
牛啊

作者: 嗳IC任性 时间: 2017-5-6 14:47
新人求教
作者: 田田园 时间: 2017-5-6 15:22
zhen ligai
作者: llyybb1 时间: 2017-5-8 10:33
非常好,真好参考一下

作者: 157369709502 时间: 2017-6-11 10:53
谢大神了
作者: fontex 时间: 2017-6-15 08:27
值得学习,谢谢!
作者: ln19970505 时间: 2017-6-20 21:20
感谢楼主 链接失效了
能补发一下吗?
作者: 1911487838 时间: 2017-6-20 22:14
这有pcb电路图吗?
作者: zhenghaili101 时间: 2017-6-21 22:53
这个资料给力。其实,调理电路也特别重要
作者: zhnagrui95 时间: 2017-7-19 10:28
51黑有你更精彩!!!
作者: 596546 时间: 2017-11-14 17:19
51黑有你更精彩!!!
作者: longyo 时间: 2017-11-19 22:43
不错 下来研究学习一下
作者: yinyq888 时间: 2018-1-17 16:13
学习学习
作者: zh123456 时间: 2018-1-21 16:25
看到警告就浑身不舒服,消除之后就清爽多了
作者: 云涯舞袖 时间: 2018-5-23 09:26
k = (0x6EE - ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_1)) / 0x05 + 25;
能解释一下这一句吗?
作者: boo851011 时间: 2018-5-23 19:15
好资料
作者: zhaoqshan 时间: 2018-5-24 10:18
必须赞一个
作者: 13131901715 时间: 2018-5-25 19:52
下载后,代码用keil打不开啊
作者: kaixin8318 时间: 2018-5-28 15:38
有没有成品我想购买一套研究下
作者: happy82828 时间: 2018-5-29 21:27
谢谢分享!
作者: a1726947341 时间: 2018-5-31 22:15
楼主厉害了,谢谢楼主分享


作者: hogen408 时间: 2018-6-10 06:36
非常好的学习资料,可以引用其中的技术,百度网盘链接失效了,能重新发一下么?谢谢
作者: mike198300 时间: 2019-1-15 05:19
相当优秀!!!!楼主的分享正是我现在急需的!
作者: 2467933313 时间: 2019-6-9 17:48
多谢分享
作者: hbthgsli 时间: 2019-8-14 13:47
不错 下来研究学习一下
作者: hbthgsli 时间: 2019-8-14 13:48
非常好的学习资料,可以引用其中的技术,百度网盘链接失效了,能重新发一下么?谢谢
作者: 强32学习小白 时间: 2019-8-14 21:24
真的厉害
作者: wtmkimmy 时间: 2019-8-28 11:08
感谢分享。
作者: dspmomo 时间: 2019-8-30 06:11
非常详细的注释,好文章
作者: liuhiong 时间: 2019-8-30 13:34
楼主:你好,能否将电路图传上来看看。
作者: kobeing2018 时间: 2019-10-15 16:51
调理电路也特别重要
作者: kobeing2018 时间: 2019-10-16 09:26
连接没有失效,我刚下了
作者: feihangdan 时间: 2019-12-30 09:22
很不错的资料哦!
作者: shiyang800 时间: 2019-12-30 10:55
2013年大二就有这样的水平 ,赞
作者: 指路明灯 时间: 2020-5-4 17:30
51黑有你更精彩!!!
作者: kpsilence 时间: 2020-5-19 12:18
下下来看看,可以学习一下。
作者: qwerty_sz 时间: 2020-5-19 15:02
这资料不错!!!
作者: a425623964 时间: 2020-5-22 23:42
谢谢分享,多谢!
作者: 严冬的雪 时间: 2020-5-28 21:55
谢谢分享
作者: haijenny 时间: 2020-5-30 15:54
没有板的资料吗?
作者: swustlx86 时间: 2020-6-1 02:05
好资料,51黑有你更精彩!!!
作者: wangyuedong7 时间: 2020-6-9 10:38
好东西
作者: 中恒电子asus 时间: 2020-6-9 23:36
膜拜的对象,相当牛
作者: 15285507312 时间: 2020-6-13 18:23
楼主这个分享可以滴,就是那个链接能否重新发一份
作者: htzsz 时间: 2020-6-15 19:56
谢谢楼主分享!
作者: hzd530 时间: 2020-6-16 10:30
楼主牛,很有参考价值,谢谢分享!
欢迎光临 (http://www.51hei.com/bbs/) |
Powered by Discuz! X3.1 |