毕业设计 - 基于stm32的示波器设计


1 简介

Hi,大家好,今天向大家介绍一个学长做的单片机项目

基于stm32的示波器设计

大家可用于 课程设计 或 毕业设计

2 主要器件

在这里插入图片描述

在这里插入图片描述

3 实现效果

在这里插入图片描述

在这里插入图片描述

4 设计原理

学长设计的示波器采用了一套成本低廉但高效的硬件,配合层次化的软件框架,实现对常规低频信号波形的采集、分析、显示。

硬件部分的主要工作有:电源管理(5V、2.5V、-5V);对信号的衰减、限幅、偏置。最后将处理好的电压信号送入MCU的ADC外设,进行数据采集。由于ADC外设只能采集正电压,因此我们通过增加偏置电压的方式,将负电压抬高来采集。

软件部分的主要工作有:底层驱动SDK框架、ADC滤波算法、波形数据处理、人机交互界面。SDK提供基本的模块和外设驱动支持,滤波算法去除噪声和毛刺,波形处理计算电压值和频率,并为波形显示做准备;人机交互界面提供屏幕显示(OLED屏)和操作方式(旋钮和按键)。

5 部分实现代码

在这里插入图片描述
部分核心代码:

/**********************************************************
简介:ADC1-CH6初始化函数
***********************************************************/															   
void  Adc_Init(void)
{ 	
	ADC_InitTypeDef ADC_InitStructure; 
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1, ENABLE );	  //使能ADC1通道时钟
 

	RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M

	//PA6 作为模拟通道输入引脚                         
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;		//模拟输入
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);	

	ADC_DeInit(ADC1);  //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值

	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;	//ADC工作模式:ADC1工作在独立模式
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;	//模数转换工作在单通道模式
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;	//模数转换工作在非连续转换模式
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2;	//转换由定时器2的通道2触发(只有在上升沿时可以触发)
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;	//ADC数据右对齐
	ADC_InitStructure.ADC_NbrOfChannel = 1;	//顺序进行规则转换的ADC通道的数目
	ADC_Init(ADC1, &ADC_InitStructure);	//根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器   

	ADC_Cmd(ADC1, ENABLE);	//使能指定的ADC1
	
	ADC_DMACmd(ADC1, ENABLE);	//ADC的DMA功能使能
	
	ADC_ResetCalibration(ADC1);	//使能复位校准  
	 
	ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 1, ADC_SampleTime_1Cycles5 );//ADC1通道6,采样时间为239.5周期	 
	 
	ADC_ResetCalibration(ADC1);//复位较准寄存器
	 
	while(ADC_GetResetCalibrationStatus(ADC1));	//等待复位校准结束
	
	ADC_StartCalibration(ADC1);	 //开启AD校准
 
	while(ADC_GetCalibrationStatus(ADC1));	 //等待校准结束
 
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);		//使能指定的ADC1的软件转换启动功能

}			

/******************************************************************
函数名称:TIM2_PWM_Init(u16 arr,u16 psc)
函数功能:定时器3,PWM输出模式初始化函数
参数说明:arr:重装载值
		 psc:预分频值
备    注:通过TIM2-CH2的PWM输出触发ADC采样
*******************************************************************/ 	
void TIM2_PWM_Init(u16 arr,u16 psc)
{  
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);	//使能定时器2时钟
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA  | RCC_APB2Periph_AFIO, ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟
 
   //设置该引脚为复用输出功能,输出TIM2 CH2的PWM脉冲波形	GPIOA.1
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //TIM_CH2
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
 
   //初始化TIM3
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
	
	//初始化TIM2 Channel2 PWM模式	 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性高
	TIM_OCInitStructure.TIM_Pulse=1000;	//发生反转时的计数器数值,用于改变占空比
	TIM_OC2Init(TIM2, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM2

	TIM_CtrlPWMOutputs(TIM2, ENABLE);//使能PWM输出
	
	TIM_Cmd(TIM2, ENABLE);  //使能TIM2
}
/******************************************************************
函数名称:MYDMA1_Config()
函数功能:DMA1初始化配置
参数说明:DMA_CHx:DMA通道选择
		 cpar:DMA外设ADC基地址
		 cmar:DMA内存基地址
		 cndtrDMA通道的DMA缓存的大小
备    注:
*******************************************************************/
void MYDMA1_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
	DMA_InitTypeDef DMA_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
 	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);	//使能DMA传输
	
    DMA_DeInit(DMA_CHx);   //将DMA的通道1寄存器重设为缺省值
	DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;  //DMA外设ADC基地址
	DMA_InitStructure.DMA_MemoryBaseAddr = cmar;  //DMA内存基地址
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  //数据传输方向,从外设读取发送到内存//
	DMA_InitStructure.DMA_BufferSize = cndtr;  //DMA通道的DMA缓存的大小
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;  //数据宽度为16位
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度为16位
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  //工作在循环模式
	DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道 x拥有高优先级 
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMA通道x没有设置为内存到内存传输
	DMA_Init(DMA_CHx, &DMA_InitStructure);  //ADC1匹配DMA通道1
	
	DMA_ITConfig(DMA1_Channel1,DMA1_IT_TC1,ENABLE);	//使能DMA传输中断	
	
	//配置中断优先级
	NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;		
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			
	NVIC_Init(&NVIC_InitStructure);	

	DMA_Cmd(DMA1_Channel1,ENABLE);//使能DMA通道
}
#define NPT 1024//一次完整采集的采样点数

/******************************************************************
函数名称:GetPowerMag()
函数功能:计算各次谐波幅值
参数说明:
备  注:先将lBufOutArray分解成实部(X)和虚部(Y),然后计算幅值(sqrt(X*X+Y*Y)
*******************************************************************/
void GetPowerMag(void)
{
    float X,Y,Mag,magmax;//实部,虚部,各频率幅值,最大幅值
    u16 i;
	
	//调用自cr4_fft_1024_stm32
	cr4_fft_1024_stm32(fftout, fftin, NPT);	
	//fftin为傅里叶输入序列数组,ffout为傅里叶输出序列数组
	
    for(i=1; i<NPT/2; i++)
    {
		X = (fftout[i] << 16) >> 16;
		Y = (fftout[i] >> 16);
		
		Mag = sqrt(X * X + Y * Y); 
		FFT_Mag[i]=Mag;//存入缓存,用于输出查验
		//获取最大频率分量及其幅值
		if(Mag > magmax)
		{
			magmax = Mag;
			temp = i;
		}
    }
	F=(u16)(temp*(fre*1.0/NPT));//源代码中此公式有误,将此复制进去
	
	LCD_ShowNum(280,180,F,5,16);
}					
u16 magout[NPT];
/******************************************************************
函数名称:InitBufInArray()
函数功能:正弦波值初始化,将正弦波各点的值存入magout[]数组中
参数说明:
备    注:
*******************************************************************/
void InitBufInArray(void)
{
    u16 i;
    float fx;
    for(i=0; i<NPT; i++)
    {
        fx = sin((PI2*i)/NPT);
        magout[i] = (u16)(2048+2048*fx);
    }
}

/******************************************************************
函数名称:sinout()
函数功能:正弦波输出
参数说明:
备    注:将此函数置于定时器中断中,可模拟输出正弦波
*******************************************************************/
void sinout(void)
{
	static u16 i=0;
	DAC_SetChannel1Data(DAC_Align_12b_R,magout[i]);
	i++;
	if(i>=NPT)
		i=0;
}
void Dac2_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	DAC_InitTypeDef DAC_InitType;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );	  //使能PORTA通道时钟
   	RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE );	  //使能DAC通道时钟 

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;				 // 端口配置
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; 		 //模拟输入
 	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOA, &GPIO_InitStructure);
					
	DAC_InitType.DAC_Trigger=DAC_Trigger_T4_TRGO;	//定时器4触发
	DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_Noise;//产生噪声
	//DAC_WaveGeneration_Triangle产生三角波
	DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_TriangleAmplitude_4095;//幅值设置为最大,即3.3V
	DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable ;	//DAC1输出缓存关闭 BOFF1=1
    DAC_Init(DAC_Channel_2,&DAC_InitType);	 //初始化DAC通道2

	DAC_Cmd(DAC_Channel_2, ENABLE);  //使能DAC-CH2
	
	DAC_SetChannel1Data(DAC_Align_12b_R, 0);  //12位右对齐数据格式设置DAC值	
}



6 最后

  • 5
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
华北理工大学轻工学院 Qing Gong College North China University of Science and Technology 毕业设计说明书 设计题目:基于单片机的简易数字示波器设计 学生姓名: 学 号: 专业班级:测控技术与仪器 学 部:信息科学部 指导教师: 2015年5月30日 摘 要 数字存储示波器是依据数字集成电路技术的发展而出现的智能化示波器,现在已经成 为电子测量领域的基础测量仪器。数字存储示波器的技术基础是数据采集,该技术已经 广泛应用于数据采集产品中,对相关仪器的研发与创新具有深远意义。矚慫润厲钐瘗睞 枥庑赖。 随着技术与元器件的发展与创新,数字存储示波器正在向宽带化、模块化、多功能和 网络化的方向发展。数字存储示波器可以实现高带宽和强大的分析能力。高端的数字存 储示波器实时带宽已经可以达到20GHz,可以广泛的应用各种千兆以太网、光通讯等测试 领域。而中低端的数字存储示波器已经可以广泛应用于各个领域的通用测试,也可以广 泛应用于高校及职业院校的教学。聞創沟燴鐺險爱氇谴净。 但是现在国内外数字存储示波器在几千到几十万不等,普遍价格偏高,不适用于简单 用途的使用与测量。所以这里介绍了数字存储示波器的原理与基本概念并设计了一个简 易的基于单片机的数字存储示波器,简化制作成成本,并能实现其基本功能与主要技术 指标。残骛楼諍锩瀨濟溆塹籟。 关键词 数据采集、单片机 Abstract Digital storage oscilloscope is based on the development of Digital IC technology and intelligent oscilloscope, now electronic measurement field of basic measurement instrument. The technology of digital storage oscilloscope is the data acquisition, which has been widely used in data acquisition products, and it has far-reaching significance for the development and innovation of the related instruments..酽锕极額閉镇桧猪訣锥。 With the development and innovation of technology and components, digital storage oscilloscope is developing to broadband, modular, multi- function and network.. Digital storage oscilloscope can achieve high bandwidth and strong analytical skills. High end digital storage oscilloscope real-time bandwidth has been reached 20GHz, can be widely used in various Gigabit Ethernet, optical communications and other test areas. And the low-end digital storage oscilloscope has been widely used in various fields of universal testing, can also be widely used in Colleges and universities and vocational colleges teaching.彈贸摄尔霁毙攬砖卤庑。 But now the digital storage oscilloscope at home and abroad, ranging from thousands to hundreds of thousands, the general price is high, not for simple purposes and measurement. So here the basic concepts and principles of digital storage oscilloscope and design a simple digital storage oscilloscope based on MCU, simplify the prod

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值