基于STM32的频谱分析和波形识别系统

这篇具有很好参考价值的文章主要介绍了基于STM32的频谱分析和波形识别系统。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1、概述

2、硬件设计

3、软件设计

 4、测试结果


1、概述

本篇介绍了以STM32F103单片机为核心的频谱分析和波形识别系统,并对其硬件组成和软件设计做了详细讲解。该系统通过STM32F103ZET6主控芯片进行ADC采样,再使用DSP库提供的FFT函数对采集到的信号进行处理,最后将输入信号的频谱图显示在TFTLCD液晶屏上,同时显示波形相关参数以及波形种类。

2、硬件设计

该装置由于是直接使用单片机开发板进行二次开发,所用单片机的芯片引脚图如下图3-2所示。因此整体上硬件较为简单。硬件主要包括信号发生器,正点原子精英板,4.3’TFTLCD,两根杜邦线,我选择使用PC1引脚接信号发生器的输出,作为该系统的输入信号,另一根杜邦线接信号发生器的GND。

本系统以STM32F103单片机为控制核心,对系统进行初始化,主要完成对开关的响应、发送指令等功能的控制,起到总控和协调各模块之间工作的作用。接入信号发生器后,单片机内部自带的ADC进行采样,经过FFT变换后变成频谱图显示在液晶屏上。系统主要包括主控器STM32F103ZET6,数模转换电路,LCD液晶屏显示电路,晶振电路以及外加复位电路组成。本设计的特点是装置一体化,外接输入信号后,便可直接经过单片机处理,实时显示频谱图以及相关参数,真正做到一步到位。

基于STM32的频谱分析和波形识别系统

3、软件设计

 该系统软件程序主要实现的就是对输入波形进行采样,然后通过FFT函数对采集到的信号进行处理,最后量化、频谱显示。还有一点就是分析不同输入信号在频域上的特征,利用该特征进行波形识别。

我直接使用了DSP库里面有FFT函数库,主要调用了里面的几个函数进行频谱分析,例如GetPowerMag()函数,其作用就是提取各次谐波的频率和对应的幅值,效率非常高,使用也方便,直接调用库函数即可。

至于波形识别的原理则是根据不同波形的特点来区分。正弦波只有基波分量,基本无谐波分量;方波除了基波,还有357次谐波分量,且3次谐波分量为基波分量的1/3;三角波除了基波,还有357次谐波分量,且3次谐波分量为基波分量的1/9;锯齿波除了基波,还有234次谐波分量,不同波形的特征分析如下图所示。

基于STM32的频谱分析和波形识别系统

基于STM32的频谱分析和波形识别系统

基于STM32的频谱分析和波形识别系统

基于STM32的频谱分析和波形识别系统

主函数

#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "timer.h"
#include "stm32_dsp.h"
#include "lcd.h"
#include "adc.h"
#include "fft.h"

/*   AD采样引脚:PC1      */
/*   采样频率  :2000Hz   */
/*   幅度3.0VPP  Z直流偏移量1.5V */

int main(void)
 {
	int i;

  delay_init();	    	 //延时函数初始化	  
	uart_init(115200);	
  LCD_Init();
  TIM1_Int_Init(500-1,72-1);//2000Hz的采样频率
		//TIM1_Int_Init(1000-1,30-1);//2400Hz的采样频率
	 //TIM1_Int_Init(74,4);    //192KHz采样频率(72MHz/5=14.4MHz,计数到75,定时为5/72M*75=1/192K)
	 //TIM1_Int_Init(75-1,150-1);    //9.6kHz采样频率(72MHz/5=14.4MHz,计数到150,定时为5/72M*75=1/9.6K)
	ADC1_Configuration();   //ADC初始化
	DMA_Configuration();    //DMA初始化
	//InitBufInArray2();//测试用的
	 LCD_Clear(BLACK);

	while(1)
	{
		for(i=0;i<NPT;i++)
		{
		  lBufInArray[i]=ADC_Value[i]<<16;
		}
		
		cr4_fft_1024_stm32(lBufOutArray, lBufInArray, NPT);    
	  GetPowerMag();
		
		lcd_show_fft(lBufMagArray);
		
   lcd_print_fft(lBufMagArray);
	}	 
}

    fft.c

#include "fft.h"
#include "math.h"
#include "lcd.h"
#include "delay.h"
u32 lBufInArray[NPT];
u32 lBufOutArray[NPT];
u32 lBufMagArray[NPT];
u32 lBUFPHASE[NPT];
float PI2=6.28318530717959;
float PI=3.14159265358979;
u32 Fs=2000;                     
/******************************************************************
函数名称:InitBufInArray()
函数功能:模拟采样数据,采样数据中包含3种频率正弦波
参数说明:
备    注:在lBufInArray数组中,每个数据的高16位存储采样数据的实部,
          低16位存储采样数据的虚部(总是为0)
*******************************************************************/
void InitBufInArray(void)
{
    unsigned short i;
    float fx;                                       //Fn=i*Fs/NPT		//由于此处i是从0开始的,所以不需要再减1
    for(i=0; i<NPT; i++)                            //频率分辨率Fs/1024=187.5Hz,所以每一个i就代表187.5Hz
    {                                               //因为采样频率=Fs,所以屏幕上的一个格子的长度代表(1/Fs)秒
        fx = 1000 * sin(PI2 * i * 350.0 / Fs) +     //2pi*f*t=2pi*i*f1/Fs,那么f=f1
             3000 * sin(PI2 * i * 8400.0 / Fs) +
             4000 * sin(PI2 * i * 10000.0 / Fs);
        lBufInArray[i] = ((signed short)fx) << 16;
    }
} 

void InitBufInArray2(void)
{
    unsigned short i;
    float fx;
    for(i=0; i<NPT; i++)
    {
        fx = 4000 * sin(PI2 * i * 375.2 / Fs) +
             1000 * sin(PI2 * i * 564.7 / Fs) +
             1500 * sin(PI2 * i * 937.1 / Fs)+1000;   //加了1000只是直流分量加了1000,其他都不变
        lBufInArray[i] = ((signed short)fx) << 16;
    }
}
/******************************************************************
函数名称:GetPowerMag()
函数功能:计算各次谐波幅值                          short 的范围,是-32767 到 32767 。也就是 -(2^15 - 1)到(2^15 - 1)。
参数说明:
备  注:先将lBufOutArray分解成实部(X)和虚部(Y),然后计算幅值(sqrt(X*X+Y*Y)
*******************************************************************/
void GetPowerMag(void)
{
    signed short lX,lY;                                                  //算频率的话Fn=i*Fs/NPT		//由于此处i是从0开始的,所以不需要再减1
    float X,Y,Mag;                                                      
    unsigned short i;
    for(i=0; i<NPT/2; i++)                                                  //经过FFT后,每个频率点处的真实幅值  A0=lBufOutArray[0]/NPT
    {                                                                       //                                 Ai=lBufOutArray[i]*2/NPT
        lX  = (lBufOutArray[i] << 16) >> 16;  //lX  = lBufOutArray[i];
        lY  = (lBufOutArray[i] >> 16);
			                                 
        X = NPT * ((float)lX) / 32768;//除以32768再乘65536是为了符合浮点数计算规律,不管他
        Y = NPT * ((float)lY) / 32768;
        Mag = sqrt(X * X + Y * Y) / NPT;
        if(i == 0)
            lBufMagArray[i] = (unsigned long)(Mag * 32768);   //0Hz是直流分量,直流分量不需要乘以2
        else
            lBufMagArray[i] = (unsigned long)(Mag * 65536);
    }
}


void PowerPhase(u16 nfill)

{
    unsigned short i;
    signed short lX,lY;  

		for (i=0; i < NPT/2; i++)
		{
						lX= (lBufOutArray[i]<<16)>>16; /* 取低16bit,sine_cosine --> cos */
						lY= (lBufOutArray[i] >> 16);   /* 取高16bit,sine_cosine --> sin */    
						{
								float X=  NPT*((float)lX)/32768;
								float Y = NPT*((float)lY)/32768;
								float phase = atan(Y/X);
								 if (Y>=0)
								 {
										if (X>=0)
											;
										else
										 phase+=PI;  
								 }
								 else
								 {             
										if (X>=0)
											phase+=PI2;                  
										else 
											phase+=PI;                    
								 }                            
								lBUFPHASE[i] = phase*180.0/PI;
						}    
				}
}

void lcd_show_fft(unsigned int *p)
{
	unsigned int *pp = p+1;             //p+1相当于我直接把0HZ部分滤掉了
	unsigned int i = 0;
	for(i = 0;i<480;i++)
	{
		//分辨率hz
		//每个小矩形宽度为1,其实这里没有显示完所有的
    //512个值,频率可达到 Hz	
    //0.11是我根据屏幕显示高度调整的一个值,频谱闪的话记得改这个值!!!!! 320*240屏幕		320*=780
		LCD_Fill(0,        i, *pp*0.11, (i+1), RED);     //有效部分白色       
		LCD_Fill(*pp*0.11, i, 270,       (i+1), BLACK);   //其他就黑色
    pp++;
	}
	
}
/***********************************************
找最大值,次大值……对应的频率,分析波形
*************************************************/
void select_max(float *f,float *a)
{
	  int i,j;
	  float k,k1,m;
    float aMax =0.0,aSecondMax = 0.0,aThirdMax = 0.0,aFourthMax=0.0;
    float fMax =0.0,fSecondMax = 0.0,fThirdMax = 0.0,fFourthMax=0.0;
	  int nMax=0,nSecondMax=0,nThirdMax=0,nFourthMax=0;
	  for ( i = 1; i < NPT/2; i++)//i必须是1,是0的话,会把直流分量加进去!!!!
    {
        if (a[i]>aMax)
        {
            aMax = a[i]; 
					  nMax=i;
					  fMax=f[nMax];
        }
    }
		for ( i=1; i < NPT/2; i++)
    {
				if (nMax == i)
				{
						continue;//跳过原来最大值的下标,直接开始i+1的循环
				}
        if (a[i]>aSecondMax&&a[i]>a[i+1]&&a[i]>a[i-1])
        {
            aSecondMax = a[i]; 
					  nSecondMax=i;
					  fSecondMax=f[nSecondMax];
        }
    }
		for ( i=1; i < NPT/2; i++)
    {
				if (nMax == i||nSecondMax==i)
				{
						continue;//跳过原来最大值的下标,直接开始i+1的循环
				}
        if (a[i]>aThirdMax&&a[i]>a[i+1]&&a[i]>a[i-1])
        {
            aThirdMax = a[i]; 
					  nThirdMax=i;
					  fThirdMax=f[nThirdMax];
        }
    }
		for ( i=1; i < NPT/2; i++)
    {
				if (nMax == i||nSecondMax==i||nThirdMax==i)
				{
						continue;//跳过原来最大值的下标,直接开始i+1的循环
				}
        if (a[i]>aFourthMax&&a[i]>a[i+1]&&a[i]>a[i-1])
        {
            aFourthMax = a[i]; 
					  nFourthMax=i;
					  fFourthMax=f[nFourthMax];
        }
    }
    POINT_COLOR=WHITE;	//画笔颜色
    BACK_COLOR=BLACK;  //背景色 
    LCD_ShowFloat4(270,0,fMax,4,24);
		LCD_ShowFloat3(270,16*2,aMax,4,24);
		LCD_ShowFloat4(270,16*5,fSecondMax,4,24);
		LCD_ShowFloat3(270,16*7,aSecondMax,4,24);
		LCD_ShowFloat4(270,16*10,fThirdMax,4,24);
		LCD_ShowFloat3(270,16*12,aThirdMax,4,24);
		LCD_ShowFloat4(270,16*15,fFourthMax,4,24);
		LCD_ShowFloat3(270,16*17,aFourthMax,4,24);
		
    k=fabs(2*fMax-fSecondMax);
		k1=fabs(3*fMax-fSecondMax);
		m=fabs((float)(aMax-3.0*aSecondMax));
//		LCD_ShowFloat3(270,370,k,4,24);
//		LCD_ShowFloat3(270,400,k1,4,24);
//		LCD_ShowFloat3(270,430,m,4,24);
		POINT_COLOR=RED;	//画笔颜色
		if(k<=5)
			  LCD_ShowString(270,340,24*4,24,24,"Sawtooth");
		else if(k1<=5&&m<0.3) 
			  LCD_ShowString(270,340,24*4,24,24," Square ");
		else if(k1<=5&&m>=0.3)
			  LCD_ShowString(270,340,24*4,24,24,"triangle");
		else LCD_ShowString(270,340,24*4,24,24,"  Sine  ");
}


void lcd_print_fft(unsigned int *p)
{
	unsigned int *pp = p;             //p+1相当于直接把0HZ部分滤掉了(改成了不过滤)
	unsigned int i = 0,j = 0;
  float f[NPT/2]={0.00},a[NPT/2]={0.00};
	for(i=0;i<NPT/2;i++)
  {
	  if(*pp>80)//看情况调,若是数字太跳就调大,把小的幅值过滤,以防干扰
		{
			f[j]=(float)i*Fs/NPT;
			//LCD_ShowFloat4(0,j*12,f[j],6,12);
			a[j]=(float)*pp*(3.3/4096);
			//LCD_ShowFloat4(100,j*12,a[j],2,12);
			j++;
		}
		pp++;
  }
	select_max(f,a);
}

   adc.c

#include <stdio.h>
#include "string.h"
#include "adc.h"
#include "sys.h"
#include "delay.h"
#include "lcd.h"
#include "stm32_dsp.h"
#include "fft.h"

u16 ADC_Value[NPT];


void ADC1_Configuration(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	ADC_InitTypeDef ADC_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_ADC1 | RCC_APB2Periph_AFIO ,ENABLE ); //使能 ADC1 通道时钟,各个管脚时钟
	RCC_ADCCLKConfig(RCC_PCLK2_Div6); //72M/6=12,ADC 最大时间不能超过 14M
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
																		
	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_1;//PC1 作为模拟通道输入引脚
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
	GPIO_Init(GPIOC, &GPIO_InitStructure);

	ADC_DeInit(ADC1); //将外设 ADC1 的全部寄存器重设为缺省值
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC1 和 ADC2工作在独立模式
	ADC_InitStructure.ADC_ScanConvMode =DISABLE; //模数转换工作在扫描模式
	ADC_InitStructure.ADC_ContinuousConvMode =DISABLE; //模数转换工作在连续转换模式
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;           //Timer1触发转换开启!!!!!!(定时器T1的CC1通道,控制采样频率)
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC 数据右对齐
	ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的 ADC 通道的数目
	ADC_Init(ADC1, &ADC_InitStructure); //根据 ADC_InitStruct 中指定的参数初始化外设ADCx 的寄存器

	ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_55Cycles5 );
	
	ADC_ExternalTrigConvCmd(ADC1, ENABLE);   //外部触发	
  
	ADC_DMACmd(ADC1, ENABLE);// 开启 ADC 的 DMA 支持(要实现 DMA 功能,还需独立配置 DMA 通道等参数)
	
	ADC_Cmd(ADC1, ENABLE); //使能指定的 ADC1
	ADC_ResetCalibration(ADC1); //复位指定的 ADC1 的校准寄存器
	while(ADC_GetResetCalibrationStatus(ADC1)); //获取 ADC1 复位校准寄存器的状态,设置状态则等待
	ADC_StartCalibration(ADC1); //开始指定 ADC1 的校准状态
	while(ADC_GetCalibrationStatus(ADC1)); //获取指定 ADC1 的校准程序,设置状态则等待
}


void DMA_Configuration(void)
{
		
	DMA_InitTypeDef DMA_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

	DMA_DeInit(DMA1_Channel1); //将 DMA 的通道 1 寄存器重设为缺省值
	DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR; //DMA 外设 ADC 基地址
	DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_Value; //DMA 内存基地址
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //内存作为数据传输的目的地
	DMA_InitStructure.DMA_BufferSize = NPT; //DMA 通道的 DMA 缓存的大小(1024)
	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(DMA1_Channel1, &DMA_InitStructure); //根据 DMA_InitStruct 中指定的参数初始DMA 的通道
	
/*  因为要显示刷屏,所以没用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_ITConfig(DMA1_Channel1, DMA_IT_TC , ENABLE);       //开启转换完成中断
		
	DMA_Cmd(DMA1_Channel1, ENABLE);
}


/*  因为要显示刷屏,所以没用DMA中断  */	
void ADC1_DMA1_IT_Hander(void)
{
	int i;
	if(DMA_GetFlagStatus(DMA1_FLAG_TC1))
	{
		for(i=0;i<NPT;i++)
		{
		 lBufInArray[i]=ADC_Value[i]<<16;
		}
	}
	DMA_ClearITPendingBit(DMA1_FLAG_TC1);
}	

 4、测试结果

基于STM32的频谱分析和波形识别系统基于STM32的频谱分析和波形识别系统

 基于STM32的频谱分析和波形识别系统基于STM32的频谱分析和波形识别系统

 基于STM32的频谱分析和波形识别系统基于STM32的频谱分析和波形识别系统

 基于STM32的频谱分析和波形识别系统基于STM32的频谱分析和波形识别系统

 实验数据分析

参数

波形

基波

频率

理论值

基波

频率

测量值

2次谐波频率

量值

3次谐波频率

测量值

4次谐波频率

测量值

5次谐

波频率

测量值

7次谐

波频率

测量值

基波频率测量误差Δ

Sine

90

89.84

0

0

0

0

0

0.17%

Square

120

119.14

0

359.37

0

599.60

839.84

0.71%

Triangle

120

119.14

0

359.37

0

0

0

0.71%

Sawtooth

200

199.21

400.39

599.60

800.78

0

0

0.39%

工程源码:基于STM32的频谱分析和波形识别系统-单片机文档类资源-CSDN下载文章来源地址https://www.toymoban.com/news/detail-435501.html

到了这里,关于基于STM32的频谱分析和波形识别系统的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于stm32的指纹识别系统设计与系统

    详细功能模块描述: 1、系统硬件模块设计与实现: 指纹通过指纹识别模块采集处理;并将处理后的指纹特征值等以数据包的形式发给主控模块;主控模块发送指令包对指纹识别模块进行控制以及对键盘模块、报警模块、液晶显示模块进行控制。在液晶显示屏上显示录入和识别

    2024年02月06日
    浏览(32)
  • 基于STM32&FFT(快速傅里叶变换)音频频谱显示功能实现

    + v hezkz17进数字音频系统研究开发交流答疑 一实验效果   二 设计过程 要用C语言实现STM32频谱显示功能,可以按照以下步骤进行操作: 1 确保已经安装好了适当的开发环境和工具链,例如Keil MDK或者GCC工具链。 2 创建一个新的STM32项目,并选择适合的MCU型号。 3 配置GPIO引脚用

    2024年02月12日
    浏览(27)
  • 基于STM32设计的口罩识别和无线测温系统

    基于STM32设计的口罩识别和无线测温系统 随着深度学习和计算机视觉的快读发展,与此有关的技术设备已经被大幅度的使用,并且不仅仅在这两个方面,更在许许多多的领域都有使用。众所周知,图像理解之中的最重要的一个步骤即为目标检测,和为目标检测,其实很简单,

    2024年02月13日
    浏览(28)
  • stm32F103RCT6使用FFT运算分析波形详解(细致教学)

    最近学校电赛队伍招新,出的招新题就是低频示波器的。之前一直没有弄懂FFT,借着这次机会实现了一下,做了一个小示波器 FFT原理简述 FFT,就是快速傅里叶变换,这个操作能够将时域信号转化成频域信号,然后对信号进行分析 这样说可能有点抽象。讲细点就是指能够直观

    2024年02月14日
    浏览(31)
  • 33、基于STM32单片机车牌识别系统摄像头图像处理系统设计

    毕设帮助、开题指导、技术解答(有偿)见文末。 目录 摘要 一、硬件方案 二、设计功能 三、实物图 四、原理图 五、PCB图 六、程序源码 七、资料包括 随着汽车工业的迅猛发展,我国汽车拥有量急剧增加。停车场作为交通设施的组成部分,随着交通运输的繁忙和不断发展,

    2024年02月15日
    浏览(31)
  • 【项目设计】基于STM32人脸识别系统 - 单片机 物联网 嵌入式

    项目设计主要是对于所学知识的整体回顾,需要结合各个学科,才能做出达到符合标准的设计。 文章的目的在分享优质的项目以及项目经验,提供设计思路,欢迎交流与指正不足之处。 由于人脸识别技术具有无需接触、安全性高、可靠性高等优点,在身份认证领域具有广阔

    2024年01月21日
    浏览(46)
  • 毕业设计——基于STM32的智能家具系统(语音识别控制、步进电机、舵机)

    智能家具系统分为两个不同版本系列: ①系列一:手机app远程控制、远程检测温湿度显示在app,(云平台)!!!!                   https://blog.csdn.net/m0_59113542/article/details/123737710 ②系列二:语音识别控制-------本文章 硬件采购链接: 步进电机及相关驱动 ULN2003步进电机驱动

    2024年02月05日
    浏览(36)
  • 71、基于STM32单片机的颜色识别感应传感器检测系统设计

    毕设帮助、开题指导、技术解答(有偿)见文末。 目录 摘要 一、硬件方案 二、设计功能 三、实物图 四、原理图 五、PCB图 六、硬件框图 七、程序源码 八、资料包括 随着现代工业生产向高速化、自动化方向的发展,色彩识别广泛应用于各种工业检测和自动控制领域,而生

    2024年02月16日
    浏览(38)
  • 物联网项目分享 基于Stm32的家庭智能监控系统 - 单片机 图像识别 人体检测 AI

    hr style=\\\" border:solid; width:100px; height:1px;\\\" color=#000000 size=1\\\" 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最

    2024年01月17日
    浏览(51)
  • 基于STM32的多功能门禁系统(AS608指纹识别、密码解锁、刷卡解锁)

    目录 一、项目功能 二、视频 三、原理图 4、材料选择 5、部分程序 1、AS608指纹解锁;可以录入、删除、验证指纹; 2、密码解锁;可以密码验证、修改密码和保存密码; 3、刷卡解锁; 4、OLED液晶显示; 基于STM32的多功能门禁系统(AS608指纹识别、密码解锁、刷卡解锁) AS608指纹

    2024年02月12日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包