STM32F103ZET6简易示波器

(需要源码私)

前言

基于正点原子STM32F103ZET6精英板、TFTLCD(320*240)、74hc165级联按键、信号发生器、示波器等制作的简易示波器。通过ADC+TIM+DMA的方式采样,并且按键可以控制采样频率,来实现波形的放大和缩小。对于波形的频率计算,一种是定时器的输入捕获,另一种是用快速傅里叶变换(FFT)计算。———————————————————————————————

运行图片

e9dfb118cfdf4e7f82416a2d992ffd72.png1ed4b4b897d94e8e9a482826ef93ee5d.png

deb6f4c6ccd34232904876aca822e747.png9775d3618ece4f2dbc85127a29d9da44.png

功能介绍

1.通过改变定时器的配置来改变采样频率

//TIM2配置,arr为重加载值,psc为预分频系数
void TIM2_Init(u16 arr,u16 psc)
{
	 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); 		//时钟使能	

	//定时器TIM2初始化	
	TIM_TimeBaseInitTypeDef   TIM_TimeBaseStructure;

	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);			//根据指定的参数初始化TIMx的时间基数单位
	
	TIM_OCInitTypeDef   TIM_OCInitStructure;     //输出比较  配置TIM2PWM模式

	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;		//选择定时器模式:TIM脉冲宽度调制模式1   pwm
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;		//比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;		//输出极性:TIM输出比较极性低
	TIM_OCInitStructure.TIM_Pulse = (arr+1)/2;
	TIM_OC2Init(TIM2, & TIM_OCInitStructure);		//初始化外设TIM2_CH2
	
	TIM_CtrlPWMOutputs(TIM2, ENABLE);        //PWM输出使能            这个函数是高级定时器使用的,通用定时器用了可能会让程序出现问题		
	TIM_Cmd(TIM2, ENABLE); 			//使能TIMx
}
void  Control_sampling(void)    //改变采样频率
{
			_74hc165_init();
			key_num=MatrixKey();

		switch(key_num)       //不同的按键代表不同的频率
		{
			case 8: 	TIM2_Init(9,17);   //400k
						psc_arr=180;     break;
			case 7: 	TIM2_Init(9,22);  //313043.478Hz
						psc_arr=230;     break;
			case 6: 	TIM2_Init(9,34);   //205714.2857Hz
						psc_arr=350;     break;
			case 13:    TIM2_Init(9,69);   //102857.142857Hz
						psc_arr=700;	 break;
			case 14: 	TIM2_Init(140,9);  //51428.5714Hz
						psc_arr=1410;    break;
			case 15: 	TIM2_Init(702,9);   //10241.820768Hz
						psc_arr=7030;    break;
		}
}

 2.两种频率计算

(a)适用于计算方波的频率和占空比——输入捕获

#include "tim.h"

void IC_Init(void)            //输入捕获
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能 TIM3 时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能 GPIOA 时钟
	
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //PA6                          TIM3CH1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

TIM_InternalClockConfig(TIM3);      //选择内部时钟
//初始化定时器3 TIM3
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;	
TIM_TimeBaseStructure.TIM_Period = 65535; //设定计数器自动重装值
TIM_TimeBaseStructure.TIM_Prescaler =5; //预分频器
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //初始化 TIMx 的时间基数单位

//初始化 TIM3 输入捕获参数
TIM_ICInitTypeDef TIM3_ICInitStructure;
TIM3_ICInitStructure.TIM_Channel = TIM_Channel_1; //选择输入端 IC1 映射到 TI1 上
TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获
TIM3_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到 TI1 上,直连通道
TIM3_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频  
TIM3_ICInitStructure.TIM_ICFilter = 0xF;//配置输入滤波器 
TIM_ICInit(TIM3, &TIM3_ICInitStructure);
TIM_PWMIConfig(TIM3,&TIM3_ICInitStructure);  //把通道2的配置设置成与通道1相反的配置

TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);   //触发源
TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);  //从模式  将CNT自动清零

TIM_Cmd(TIM3,ENABLE ); //使能定时器3
}

uint32_t  IC_GetFreq(void)
{
	uint32_t Freq1,Freq2;
	  Freq1 =12000000/ (TIM_GetCapture1(TIM3));      //计算频率       1k以下测量频率准
		Freq2 =12000000/ (TIM_GetCapture1(TIM3)+1);   //计算频率      1k以上测量频率准                                           分频后的除以计次  (测周法)     误差:对于高频信号用测频法好,对于低频信号用测周法好
	  if(Freq1>1000)
			return Freq2;
		else 
			return Freq1;
}
uint32_t  IC_GetDuty(void)
{
		return  (TIM_GetCapture2(TIM3)+1 ) *100/(TIM_GetCapture1(TIM3)+1 );     //计算占空比
}

(b)快速傅里叶变换 (FFT)

void GetPowerMag(void)
{
    signed short lX,lY;
    float X,Y,Mag;
    unsigned short i;
    for(i=0; i<NPT/2; i++)
    {
        lX  = (lBufOutArray[i] << 16) >> 16;          //取低16位
        lY  = (lBufOutArray[i] >> 16);                     //取高16位
			
		//除以32768再乘65536是为了符合浮点数计算规律
        X = NPT * ((float)lX) / 32768;
        Y = NPT * ((float)lY) / 32768;
        Mag = sqrt(X * X + Y * Y)*1.0/ NPT;
        if(i == 0)	
            lBufMagArray[i] = (unsigned long)(Mag * 32768);
        else
            lBufMagArray[i] = (unsigned long)(Mag * 65536);
    }
}

void ADC_sample(void)
{
	uint16_t i;
	for (i = 0; i < NPT; i++)
	{
		lBufInArray[i] =ADC_ConvertedValue[i];
	}
	cr4_fft_1024_stm32(lBufOutArray,lBufInArray, NPT);
	GetPowerMag();
	
	for(uint16_t a=0;a<512;a++ )
	{
		FFT_Date[a]=(float)lBufMagArray[a]/1024*2;              
//		printf("%d\tvalue:  %f \r\n",a,FFT_Date[a]);
//		printf("%d\tvalue:  %d \r\n",a,lBufMagArray);
	}
}

uint32_t  Freq_Count(void)    //通过FFT计算的信号频率
{
	float   FFT_max=0;             
  uint32_t  Freq=0;	
	for(uint16_t a=1;a<512;a++)   //a从1开始,去掉直流分量后,比较出幅值的最大值
	{					
				if(FFT_Date[a]>FFT_max)
				{			
						FFT_max=FFT_Date[a];
					  Freq =(72000000)/(psc_arr*1024)*a;    //信号输入频率=采样频率/1024*a
				}
	}	
    return Freq;
}

 Freq =(72000000)/(psc_arr*1024)*a;   这个计算出来的频率还是有一点误差的,原因是72M除以了psc*arr*1024,它不是一个整数。

3.按键

我一共使用了8个按键,板子自带的2个按键使用EXTI外部中断,KEY0按下显示波形,KEY1按下显示FFT频谱,剩下的6个按键控制采样频率,通过扫描按键电平的方式

4.LCD显示部分

   屏幕刷新问题:全部清屏还是局部清屏显得很不自然,屏幕一卡一卡的

    解决方法:制作一个背景板,每次刷完就用背景板覆盖上一次的

void Show_background(void)
{
	for(uint8_t j=0;j<7;j++)
	{
		for(uint8_t i=0;i<6;i++)
		{
			LCD_Color_Fill(0+i*40,120+j*30,39+i*40,149+j*30,background);	    
		}
	}
}

填充指定颜色制作一个“背景板”

***********************************************************************************

//在指定区域内填充指定颜色块			 
//(sx,sy),(ex,ey):填充矩形对角坐标,区域大小为:(ex-sx+1)*(ey-sy+1)   
//color:要填充的颜色
void LCD_Color_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 *color)
{  
	u16 height,width;
	u16 i,j;
	width=ex-sx+1; 			//得到填充的宽度
	height=ey-sy+1;			//高度
 	for(i=0;i<height;i++)
	{
 		LCD_SetCursor(sx,sy+i);   	//设置光标位置 
		LCD_WriteRAM_Prepare();     //开始写入GRAM
		for(j=0;j<width;j++)LCD->LCD_RAM=color[i*width+j];//写入数据 
	}		  
}  

 

 

 

### 回答1: STM32F103ZE精英版示波器是一款高性能的示波器产品,尤其适合用于电子工程师和电子爱好者进行电路测试和信号分析。 首先,STM32F103ZE示波器采用了STM32F103ZE微控制器作为核心芯片,该芯片具有高性能和低功耗的特点。它具有72MHz主频、512KB的Flash存储器和64KB的SRAM,这使得它能够快速、准确地捕捉和处理各种信号。 其次,示波器具有高分辨率的液晶显示屏,可清晰地显示捕获的波形信号。用户可以通过触摸屏进行直观、方便的操作,选择不同的测量通道和触发方式,并对波形进行放大、缩小和平移等操作。 此外,STM32F103ZE示波器还具有多种波形显示模式,如实时采样模式、块采样模式和自动识别模式等,可以满足不同使用场景的需求。 值得一提的是,STM32F103ZE示波器还支持USB接口和SD卡扩展,方便用户进行数据的导出和存储。用户可以将捕获的波形数据保存在SD卡中,或通过USB接口将数据传输到计算机中进行进一步的分析和处理。 综上所述,STM32F103ZE精英版示波器作为一款高性能、多功能的示波器产品,凭借其强大的处理能力、易于操作的界面和可扩展的接口,成为了电子工程师和电子爱好者理想的测试工具。无论是在学习、研究还是实际工程中,它都能够提供准确、可靠的波形显示和信号分析服务。 ### 回答2: STM32103ZE精英版示波器是一款高端示波器,具有很多优点和特点。 首先,STM32103ZE精英版示波器采用了先进的数字信号处理技术,能够实时获取、分析和显示电子信号。它具有非常高的频率响应和精准的采样率,可以捕捉到信号的细微变化,提供准确的波形分析结果。 其次,STM32103ZE精英版示波器具有多种触发模式和触发方式,可以根据用户的需求设置特定的触发条件,从而准确捕捉到特定的信号波形。它还具有多通道输入功能,可以同时测量多个信号源,提供更为全面的测试结果。 此外,STM32103ZE精英版示波器还提供了丰富的测量和分析功能。它可以进行自动测量,如峰值、频率、占空比等,使用户在测试过程中更加方便快捷。它还可以进行多种数学运算和波形处理,如加减乘除、积分、微分等,帮助用户进一步分析信号特征。 最后,STM32103ZE精英版示波器还具有友好的操作界面和强大的数据存储能力。它配备了高分辨率的液晶显示屏,用户可以清晰地观察波形变化。同时,它支持USB接口和存储卡插槽,用户可以将测试数据保存在外部设备中,方便以后的分析和查阅。 总之,STM32103ZE精英版示波器具有高精度、高效率、多功能的特点,适用于各种电子领域的测试和研究。它的出现,将为用户提供更为可靠和方便的电子信号分析工具。
评论 32
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

了了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值
>