基于51单片机FM数字收音机设计

基于51单片机FM数字收音机

(程序+原理图+PCB+设计报告)

功能介绍

具体功能:

该系统利主要由STC89C51单片机、液晶显示器、按键、调频收音模块TEA5767、功放LM386组成。

1.收音芯片采用TEA5767模块,采用LM386芯片放大音频功率;

2.LCD1602液晶显示当前所收听的FM频道;

3.可以通过按键进行调换,实现87.5MHz~108MHz调频广播的接收;

​演示视频:

基于51单片机FM数字收音机设计 

添加图片注释,不超过 140 字(可选)

程序

/**************************************************************** 
/***公众号:木子单片机****
工程名称:数字收音机
功能: 以LCD1602为显示的TEA5767模块的收音机

***************************************************************/

#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define DELAY5US _nop_();_nop_();_nop_();_nop_();_nop_();
//**************TEA5767模块接线方法********************
sbit SDA=P1^0;     
sbit SCL=P1^1;
//*************频率调节按键接线************************
sbit Key1=P1^2;
sbit Key2=P1^3;
//==============LCD1602接口连接方法=====================
/*-----------------------------------------------------
       |DB0-----P0.0 | DB4-----P0.4 | RW-------P2.3    |
       |DB1-----P0.1 | DB5-----P0.5 | RS-------P2.4    |
       |DB2-----P0.2 | DB6-----P0.6 | E--------P2.2    |
       |DB3-----P0.3 | DB7-----P0.7 | 
    ---------------------------------------------------*/
//================================================*/              
#define LCM_Data     P0    //LCD1602数据接口
#define Busy         0x80   //用于检测LCM状态字中的Busy标识
sbit    LCM_RW     = P2^6;  //读写控制输入端,LCD1602的第五脚
sbit    LCM_RS     = P2^5;  //寄存器选择输入端,LCD1602的第四脚
sbit    LCM_E      = P2^7;  //使能信号输入端,LCD1602的第6脚
//*****************参数定义*****************************
unsigned long int  FM_FREQ;  //频率
unsigned short int FM_PLL;   //PLL
uchar idata sbuf[5];   		// 数据发送缓冲区
uchar idata numbyte;
uchar idata numbyte_AMP;
uchar idata ADDRESS_AMP;
uchar idata ADDRESS_SEND;    //TEA5767发送地址
uchar idata ADDRESS_RECEIVE; //TEA5767接收地址
uchar idata rbuf[5];   		 // 数据接收缓冲区
uchar idata ampint[5];
uchar bdata PLL_HIGH;  
uchar bdata PLL_LOW;   //设定用于搜索和预设的可编程频率合成器
uchar bdata I2C_byte1;//发送的五字节TEA5767可位寻址的设置值
uchar bdata I2C_byte2;
uchar bdata I2C_byte3;
uchar bdata I2C_byte4;
uchar bdata I2C_byte5;
sbit MUTE =I2C_byte1^7;//如果MUTE=1,则左右声道被静音;MUTE=0,左右声道正常工作	 
sbit SM = I2C_byte1^6; //SM=1,则处于搜索模式;SM=0,不处于搜索模式
sbit SUD=I2C_byte3^7;  //SUD=1,增加频率搜索;SUD=0,减小频率搜索
uchar   byte1;  
uchar   byte2;
uchar   byte3;
uchar   byte4;
uchar   byte5;
uchar num1,num2,num3,num4;
uchar   tab1[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
bit   bdata NACK;    		// 错误标志位
//**********相关函数声明**************************************
void    init(void);	    //TEA5767初始化
void    delay600ms(void);  //延迟600ms
void    delay100ms(void);	//延迟100ms
void    delay10ms();
void    delay1ms(void);	//延迟1ms
void    sendnbyte(uchar idata *sla, uchar n);//与sendbyte函数构成I2C 数据发送函数
void    I2C_start(void);	//I2C 传输开始
void    sendbyte(uchar idata *ch);	
void    checkack(void);   //检查应答讯号
void    stop(void);		//I2C传输结束
void    AMP_sendnbyte(uchar idata *sla,uchar numbyte_AMP);
void    key_scan(void);	//键扫描
void    search_up(void);   //接收频率向上加
void    search_down(void); //接收频率向下减
void    setByte1Byte2(void);  //设置第一第二字节频率
void    LCMInit(void);//LCD初始
void    DelayMs(uint Ms);//1MS基准延时程序
void    WriteDataLCM		(uchar WDLCM);//LCD模块写数据
void    WriteCommandLCM	(uchar WCLCM,BuysC); //LCD模块写指令
uchar   ReadStatusLCM(void);//读LCD模块的忙标
void    DisplayOneChar(uchar X,uchar Y,uchar ASCII);//在第X+1行的第Y+1位置显示一个字符
void    LCDshow(void);
void    DelayMs(uint Ms);
void    show();     //开机问候语
//*****************主程序******************************
void main(void)
{   
	  
    numbyte = 5;
	  numbyte_AMP=5;
    ADDRESS_SEND = 0xC0;// TEA5767写地址 1100 0000
	  ADDRESS_RECEIVE=0XC1;//TEA5767读地址 1100 0001
    ADDRESS_AMP=0X8E;
    init();      //  初始化TEA5767
	  show();     //开机问候语
    LCMInit();//LCD初始
    LCDshow();
    while(1)
    {          
	    key_scan();			 //键扫描
    }

}

//**************开机问候语**************************
void show()
{
	     LCMInit();//LCD初始
	   
	     DisplayOneChar(0, 1,'H');//
       DisplayOneChar(0, 2,'e');//
       DisplayOneChar(0, 3,'l');//
       DisplayOneChar(0, 4,'l');//
       DisplayOneChar(0, 5,'o');//
       DisplayOneChar(0, 6, ',');
	     DisplayOneChar(0, 7,'W');//
       DisplayOneChar(0, 8,'e');//
       DisplayOneChar(0, 9, 'l');
       DisplayOneChar(0, 10, 'c');
       DisplayOneChar(0, 11, 'o');
       DisplayOneChar(0, 12, 'm');
       DisplayOneChar(0, 13, 'e');
       DelayMs(500);
	     
	     DisplayOneChar(1, 1,' ');// 显示姓名
	     DisplayOneChar(1, 2,' ');//
       DisplayOneChar(1, 3,' ');//
       DisplayOneChar(1, 4,' ');//
       DisplayOneChar(1, 5,' ');//
       DisplayOneChar(1, 6,' ');//
       DisplayOneChar(1, 7,' ');
	     DisplayOneChar(1, 8,' ');//
       DisplayOneChar(1, 9,' ');//
       DisplayOneChar(1, 10,' ');
       DisplayOneChar(1, 11,' ');
       DisplayOneChar(1, 12,' ');
       DisplayOneChar(1, 13,' ');
       DisplayOneChar(1, 14,' ');
	     
	     DelayMs(500);
	
	    
  
}
//**************按键扫描程序************************
void key_scan(void)
{
  if(Key1==0)
  {
 	 delay10ms();
 	 if(Key1==0)
 	 {
          while(Key1==0);
    	  search_up();	  //频率向上
          LCDshow();
    	  delay600ms();
  	  }
  }
  if(Key2==0)
  {
 	 delay10ms();
 	 if(Key2==0)
 	 {
        while(Key2==0);
        search_down();  //频率向下
        LCDshow();
        delay600ms();
 	  }
  }
}
//*********************LCD1602显示程序*********************
void LCDshow(void)
{
      num1=FM_FREQ/100000000;
      num2=(FM_FREQ%100000000)/10000000;
      num3=(FM_FREQ%10000000)/1000000;
      num4=(FM_FREQ%1000000)/100000;
      DisplayOneChar(0, 4,'F');//
       DisplayOneChar(0, 5,'M');//
       DisplayOneChar(0, 6,'R');//
       DisplayOneChar(0, 7,'a');//
       DisplayOneChar(0, 8,'d');//
       DisplayOneChar(0, 9,'i');//
       DisplayOneChar(0, 10,'o');//
       DisplayOneChar(1, 4, tab1[num1]);
       DisplayOneChar(1, 5, tab1[num2]);
       DisplayOneChar(1, 6, tab1[num3]);
       DisplayOneChar(1, 7, '.');
       DisplayOneChar(1, 8, tab1[num4]);
       DisplayOneChar(1, 9,'M');//
       DisplayOneChar(1, 10,'H');//
       DisplayOneChar(1, 11,'Z');//
}
/*======================================================================
 LCM初始化
======================================================================*/
void LCMInit(void) 
{
 LCM_Data = 0;
 WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
 DelayMs(5);
 WriteCommandLCM(0x38,0);
 DelayMs(5);
 WriteCommandLCM(0x38,0);
 DelayMs(5);
 WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
 WriteCommandLCM(0x08,1); //关闭显示
 WriteCommandLCM(0x01,1); //显示清屏
 WriteCommandLCM(0x06,1); // 显示光标移动设置
 WriteCommandLCM(0x0C,1); // 显示开及光标设置
 DelayMs(100);
}
//==============================LCD1602显示子程序================================================
// 写数据函数: E =高脉冲 RS=1 RW=0
//======================================================================*/
void WriteDataLCM(uchar WDLCM)
{
 ReadStatusLCM(); //检测忙
 LCM_Data = WDLCM;
 LCM_RS = 1;
 DelayMs(1);
 LCM_RW = 0;
 DelayMs(1);
 LCM_E = 0; //若晶振速度太高可以在这后加小的延时
 LCM_E = 0; //延时
 DelayMs(1);
 LCM_E = 1;
}
/*====================================================================
  写指令函数: E=高脉冲 RS=0 RW=0
======================================================================*/
void WriteCommandLCM(uchar WCLCM,BuysC) //BuysC为0时忽略忙检测
{
 if (BuysC) ReadStatusLCM(); //根据需要检测忙
 LCM_Data = WCLCM;
 LCM_RS = 0;
 LCM_RW = 0;
 LCM_E = 0;
 LCM_E = 0;
 LCM_E = 1;
}
/*====================================================================
  正常读写操作之前必须检测LCD控制器状态:E=1 RS=0 RW=1;
  DB7: 0 LCD控制器空闲,1 LCD控制器忙。
  读状态
======================================================================*/
uchar ReadStatusLCM(void)
{
 LCM_Data = 0xFF;
 LCM_RS = 0;
 LCM_RW = 1;
 LCM_E = 0;
 LCM_E = 0;
 LCM_E = 1;
 while (LCM_Data & Busy); //检测忙信号  
 return(LCM_Data);
}
/*======================================================================
功 能:     在1602 指定位置显示一个字符:第一行位置0~15,第二行16~31
说 明:     第 X 行,第 y 列  注意:字符串不能长于16个字符
======================================================================*/
void DisplayOneChar( uchar X, uchar Y, uchar ASCII)
{
  X &= 0x1;
  Y &= 0xF; //限制Y不能大于15,X不能大于1
  if (X) Y |= 0x40; //当要显示第二行时地址码+0x40;
  Y |= 0x80; // 算出指令码
  WriteCommandLCM(Y, 0); //这里不检测忙信号,发送地址码
  WriteDataLCM(ASCII);
}
/*====================================================================
  设定延时时间:x*1ms
====================================================================*/
void DelayMs(uint Ms)
{
  uint i,TempCyc;
  for(i=0;i<Ms;i++)
  {
    TempCyc = 250;
    while(TempCyc--);
  }
}
//******************************************
void init(void)
{ 
    uchar idata sbuf[5]={0XF0,0X2C,0XD0,0X10,0X40};  //FM模块预设值
    uchar idata rbuf[5]={0X00,0X00,0X00,0X00,0X00};
    uchar idata ampint[5]={0X27,0X40,0X42,0X46,0XC3};
    FM_PLL=0X302C;
    FM_FREQ=97000000; //开机预设频率 
    PLL_HIGH=0;
    PLL_LOW=0;
    delay100ms();
    delay100ms();
    P1=0XFF;
    P2=0XFF;
    I2C_byte1=0XF0;  //FM模块预设值
    I2C_byte2=0X2C;
    I2C_byte3=0XD0;
    I2C_byte4=0X10;
    byte1=0X27;  
    byte2=0X40;
    byte3=0X42;
    byte4=0X46;
    sendnbyte(&ADDRESS_SEND,numbyte);
    delay100ms();
    AMP_sendnbyte(&ADDRESS_AMP,numbyte_AMP);
}
//************************************************
//送n字节数据子程序 
void sendnbyte(uchar idata *sla, uchar n)
{          
	uchar idata *p;
    sbuf[0]=I2C_byte1;
    sbuf[1]=I2C_byte2;
    sbuf[2]=I2C_byte3;
    sbuf[3]=I2C_byte4;
	I2C_start();			// 发送启动信号
	sendbyte(sla);    		// 发送从器件地址字节
	checkack();    			// 检查应答位
    if(F0 == 1)
	{ 
		NACK = 1;
		return;    		// 若非应答表明器件错误置错误标志位NACK
	}
	p = &sbuf[0];
	while(n--)
	{ 
		sendbyte(p);
		checkack();    	// 检查应答位
		if (F0 == 1)
		{
			NACK=1;
			return;    	// 若非应答表明器件错误置错误标志位NACK
		}
		p++;
	}
	stop();    			// 全部发完则停止
}
//***********************************************
延迟100ms
void delay100ms()				
{
	uchar i;
	for(i=100;i>0;i--){delay1ms();}
}
//**********************************************
//延迟1ms

void delay1ms(void)	          	
{
	uchar i;
	for(i=1000;i>0;i--){;}
}
//*************************************************
//在SCL为高时,SDA由高变低即为I2C传输开始
void I2C_start(void)   
{
   SDA=1;
   SCL=1;
   DELAY5US;
   SDA=0;
  
}
//****************************************************
//发送一个字节数据子函数
void sendbyte(uchar idata *ch)

{ 
	uchar idata n = 8;  
	uchar idata temp;
	temp = *ch;
	while(n--)
	{ 
		if((temp&0x80) == 0x80)    // 若要发送的数据最高位为1则发送位1
		{
			SDA = 1;    // 传送位1
			SCL = 1;
			DELAY5US;
		  
		}
		else
		{  
			SDA = 0;    // 否则传送位0
			SCL = 1;
			DELAY5US;
			SCL = 0;  
		}
		temp = temp<<1;    // 数据左移一位
	}
}
//发送n字节数据子程序
void AMP_sendnbyte(uchar idata *sla, uchar n)
{          
	uchar idata *p;
    ampint[0]=byte1;
    ampint[1]=byte2;
    ampint[2]=byte3;
    ampint[3]=byte4;
    ampint[4]=byte5;	
	I2C_start();			// 发送启动信号
	sendbyte(sla);    		// 发送从器件地址字节
	checkack();    			// 检查应答位
    if(F0 == 1)
	{ 
		NACK = 1;
		return;    		// 若非应答表明器件错误置错误标志位NACK
	}
	p=&ampint[0];
	while(n--)
	{ 
		sendbyte(p);
		checkack();    	// 检查应答位
		if (F0 == 1)
		{
			NACK=1;
			return;    	// 若非应答表明器件错误置错误标志位NACK
		}
		p++;																		  
	}
	stop();    			// 全部发完则停止
}
//****************************************

硬件设计

使用元器件:

单片机:STC89C51;

(注意:单片机是通用的,无论51还是52、无论stc还是at都一样,引脚功能都一样。程序也是一样的。)

9*15万用板;40脚IC座;

LCD1602液晶;103电位器(蓝白);

16P排阵;16脚液晶IC座;

220uf电解电容;100uf电解电容;

10k电阻;10uf电容;30pf电容*2;

12M晶振;轻触按键*3;

TEA5767模块;104pf*2;

103电位器(精密大号);

耳机插口;伸缩天线;

LM386;8脚IC座;

2P白色插口;红黑并线;

8欧5W喇叭;

导线:若干;

添加图片注释,不超过 140 字(可选)

流程图:

 

设计资料

01原理图

本系统原理图采用Altium Designer19设计,具体如图!

添加图片注释,不超过 140 字(可选)

02PCB

本系统pcb采用Altium Designer19设计,具体如图!

添加图片注释,不超过 140 字(可选)

03程序

本设计使用软件Keil5版本编程设计!具体如图!

添加图片注释,不超过 140 字(可选)

04设计报告

一万两千字设计报告,具体如下!

添加图片注释,不超过 140 字(可选)

05设计资料

        资料获取请关注同名公众号,全部资料包括程序(含注释)、AD原理图、PCB、设计报告、流程图、答辩PPT、实物图、元件清单等。具体内容如下,全网最全! !

 

可以关注下方公众号!

点赞分享一起学习成长。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/724264.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

# 消息中间件 RocketMQ 高级功能和源码分析(四)

消息中间件 RocketMQ 高级功能和源码分析&#xff08;四&#xff09; 一、 消息中间件 RocketMQ 源码分析&#xff1a;回顾 NameServer 架构设计。 1、RocketMQ 架构设计 消息中间件的设计思路一般是基于主题订阅发布的机制&#xff0c;消息生产者&#xff08;Producer&…

CSS3基本语法

文章目录 一、CSS引入方式二、选择器1、标签选择器2、类选择器3、id选择器4、通配符选择器 三、字体操作1、字体大小2、字体粗细3、字体样式&#xff08;是否倾斜&#xff09;4、字体修改常见字体系列 修改字体系列语法 四、文本操作1、文本缩进2、文本水平对齐方式3、文本修饰…

汽车IVI中控开发入门及进阶(二十七):车载摄像头vehicle camera

前言: 在车载IVI、智能座舱系统中,有一个重要的应用场景就是视频。视频应用又可分为三种,一种是直接解码U盘、SD卡里面的视频文件进行播放,一种是手机投屏,就是把手机投屏软件已视频方式投屏到显示屏上显示,另外一种就是对视频采集设备(主要就是摄像头Camera)的视频源…

智能温室大棚在无土栽培中的应用

在全球范围内&#xff0c;农业面临着前所未有的挑战&#xff0c;包括气候变化、土地资源短缺、水资源匮乏等。为了应对这些问题&#xff0c;智能温室大棚成为了一种创新的解决方案。无土栽培作为现代农业的前沿技术&#xff0c;在智能温室的支持下&#xff0c;展现出了巨大的潜…

QT/基于TCP的服务端实现

代码 widget.cpp #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget),p(new QTcpServer(this))//给服务器指针申请空间 {ui->setupUi(this); }Widget::~Widget() {delete ui; }void W…

室内灰尘对老人小孩危害不容忽视,资深家政推荐除灰尘空气净化器

正所谓“病从口入&#xff0c;尘从窗入”&#xff0c;室内灰尘问题不容小觑。尤其是对老人和小孩来说&#xff0c;灰尘中的有害物质更是威胁健康的重要因素。近期天气炎热&#xff0c;家家户户每天都会开窗通风&#xff0c;然而这也带来了灰尘和毛絮的问题。即使每天打扫&#…

使用asyncua模块的call_method方法调用OPC UA的Server端方法报错:asyncio.exceptions.TimeoutError

使用asyncua模块的call_method方法调用OPC UA的Server端方法报错&#xff1a;asyncio.exceptions.TimeoutError 报错信息如下&#xff1a; Traceback (most recent call last): asyncio.run(main()) File “D:\miniconda3\envs\py31013\lib\asyncio\runners.py”, line 44, in…

PID控制算法学习笔记分享

目录 一、参数设定 二、PID计算公式 三、位置式PID代码实现 四、增量式PID代码实现 五、两种控制算法的优缺点 六、PID算法的改进 一、参数设定 比例系数&#xff08;kp&#xff09;&#xff1a;P项的作用是根据当前误差的大小来产生一个控制量。它直接与误差成正比&#…

Codeforces Round 953 (Div. 2) A - C 题解

因为有事只做了A-C&#xff0c;都比较简单&#xff0c;全是很简单的思维&#xff0c;明天有空还会添加上D&#xff0c;如果有人需要可以明天常来看看&#xff01; 进入正题&#xff1a; A. Alice and Books 题意&#xff1a;给你n个数字&#xff0c;将这些数字分到两堆里&am…

【C++初阶路】--- 类和对象(中)

目录 一、this指针1.1 this指针的引出1.2 this指针的特性1.3. C语言和C实现Stack的对比 二、类的6个默认成员函数三、构造函数3.1 概念3.2 特性 一、this指针 1.1 this指针的引出 如下定义一个日期类Date class Date { public://void InitDate(Date* const this, int year …

APP自动化测试-Appium常见操作之详讲

一、基本操作 1、点击操作 示例&#xff1a;element.click() 针对元素进行点击操作 2、初始化&#xff1a;输入中文的处理 说明&#xff1a;如果连接的是虚拟机&#xff08;真机无需加这两个参数&#xff0c;加上可能会影响手工输入&#xff09;&#xff0c;在初始化配置中…

Java--Arrays类

1.数组的工具java.util.Arrays 2.由于数组对象本身并没有什么方法可以供我们调用&#xff0c;但API中提供了一个工具类Arrays供我们使用&#xff0c;从而可以对数据对象进行一些基本的操作。 3.查看JDK帮助文档 4.Arrays类中的方法都是static修饰静态的静态方法&…

minSdkVersion、targetSdkVersion、compileSdkVersion三者的作用解析

minSDK和targetSDK&#xff0c;这两者相当于一个区间。你能够用到targetSDK中最新的API和最酷的新功能&#xff0c;但又需要向后(向下)兼容到minSDK&#xff0c;保证这个区间内的设备都能够正常的执行你的APP。换句话说&#xff0c;想使用Android刚刚推出的新特性&#xff0c;但…

6 PXE高效批量网络装机

6.1部署PXE远程安装服务 在大规模的Liunx应用环境中&#xff0c;如web群集&#xff0c;分布式计算等&#xff0c;服务器往往并不配备光驱设备&#xff0c;在这种情况下&#xff0c;如何为数十乃至上百台服务器裸机快速安装系统呢&#xff1f;传统的USB光驱&#xff0c;移动硬盘…

零编程数据可视化展示:十个简易案例!

数据可视化是呈现数据内在价值的最终手段。数据可视化实例利用各种图表和图形设计手段&#xff0c;合乎逻辑地展示复杂而不直观的数据。为了让用户直观清楚地了解他们想要的数据及其比较关系&#xff0c;数据可视化实例的呈现至关重要。即时设计整理了10个数据可视化实例&#…

17-C语言中的变量生命周期——自动存储期、青苔存储期、自定义存储期

17-C语言中的变量生命周期——自动存储期、青苔存储期、自定义存储期 文章目录 17-C语言中的变量生命周期——自动存储期、青苔存储期、自定义存储期一、自动存储期示例 二、静态存储期2.1 示例 三、自定义存储期3.1 如何申请内存3.2 如何释放内存3.3 如何清空内存3.4 示例 概念…

【学习DayNa】信息系统开发整理

✍&#x1f3fb;记录学习过程中的输出&#xff0c;坚持每天学习一点点~ ❤️希望能给大家提供帮助~欢迎点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;指点&#x1f64f; 结构化方法 结构是指系统内各个组成要素之间的相互联系、相互作用的框架。结构化开发方法就是…

需求工程师的基本职责(合集)

需求工程师的基本职责1 职责&#xff1a; 1、负责用户需求调研、用户需求分析&#xff0c;明确用户需求分析&#xff0c;明确用户功能需求、业务需求&#xff0c;转换成软件需求说明。 2、收集、分析、整理、提炼系统需求&#xff0c;能够对业务流程提出优化建议并写成系统功能…

音视频入门基础:H.264专题(1)——H.264官方文档下载

音视频入门基础&#xff1a;H.264专题系列文章&#xff1a; 音视频入门基础&#xff1a;H.264专题&#xff08;1&#xff09;——H.264官方文档下载 音视频入门基础&#xff1a;H.264专题&#xff08;2&#xff09;——使用FFmpeg命令生成H.264裸流文件 音视频入门基础&…

SpringBoot整合Minio(支持公有及私有bucket)

&#x1f60a; 作者&#xff1a; 一恍过去 &#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390 &#x1f38a; 社区&#xff1a; Java技术栈交流 &#x1f389; 主题&#xff1a; SpringBoot整合Minio(支持公有及私有bucket) ⏱️ 创作时间&#xff1…