【蓝桥杯嵌入式】第十四届蓝桥杯嵌入式[模拟赛1]程序设计试题及详细题解

这篇具有很好参考价值的文章主要介绍了【蓝桥杯嵌入式】第十四届蓝桥杯嵌入式[模拟赛1]程序设计试题及详细题解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

原题展示

【蓝桥杯嵌入式】第十四届蓝桥杯嵌入式[模拟赛1]程序设计试题及详细题解

原题分析

模拟赛1的题目中需要的准备的知识点不多,其中只用到了串口LCDLED按键定时器的PWM输出、以及ADC等几个模块,题目要求也简单详细并且数量不多,非常适合入门比赛,以及整合自己比赛的模块。
与模拟赛2相比,当然是模拟赛2的试题比较难啦,虽然需要的模块差不多,但是模拟赛2的功能要求相对较多、较为复杂。
与省赛相比嘛,只能说省赛的功能要求更多、功能更加复杂,其余的需要大家自己体会。😜😜😜

题解

LED相关

通过查询产品手册知,LED的引脚为PC8~PC15,外加锁存器74HC573需要用到的引脚PD2。(由于题目要求除题目要求需要使用的LED外其他LED都处于熄灭状态,此处特意将所有的LED都初始化以便于管理其他的LED灯)
CubeMX配置:
【蓝桥杯嵌入式】第十四届蓝桥杯嵌入式[模拟赛1]程序设计试题及详细题解
代码样例
由于G431的所有LED都跟锁存器74HC573连接,因此每次更改LED状态时都需要先打开锁存器,写入数据后再关闭锁存器。

/*****************************************************
* 函数功能:改变所有LED的状态
* 函数参数:
*			char LEDSTATE: 0-表示关闭 1-表示打开
* 函数返回值:无
******************************************************/
void changeAllLedByStateNumber(char LEDSTATE)
{
	HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_8
					|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12,(LEDSTATE==1?GPIO_PIN_RESET:GPIO_PIN_SET));
	//打开锁存器    准备写入数据
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
	//关闭锁存器 锁存器的作用为 使得锁存器输出端的电平一直维持在一个固定的状态
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}

/*****************************************************
* 函数功能:根据LED的位置打开或者是关闭LED
* 函数参数:
*			uint16_t LEDLOCATION:需要操作LED的位置
*			char LEDSTATE: 0-表示关闭 1-表示打开
* 函数返回值:无
******************************************************/
void changeLedStateByLocation(uint16_t LEDLOCATION,char LEDSTATE)
{
	HAL_GPIO_WritePin(GPIOC,LEDLOCATION,(LEDSTATE==1?GPIO_PIN_RESET:GPIO_PIN_SET));
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}

试题要求的LED显示其条件都比较单一,在满足点亮条件时直接点亮,否则,就直接熄灭即可,至于闪烁的周期控制,可以借助与sysTick中断实现,如果就因此再开一个定时器就有点浪费资源了。(虽然小编以前经常这样子干🤣🤣🤣)

小编写的LED工作逻辑函数:

/***************************************
* 函数功能:LED显示逻辑函数
* 函数参数:无
* 函数返回值:无
***************************************/
static void ledWork(void)
{
	// 外部声明的计数值
	extern uint16_t count;
	// 数据界面
	if(LCDmod == 0 && HAL_GetTick()%90==0)
	{
		changeLedStateByLocation(LED1,1);
		changeLedStateByLocation(LED2,0);
	}
	// 参数界面
	else if(LCDmod == 1 && HAL_GetTick()%90==0)
	{
		changeLedStateByLocation(LED1,0);
		changeLedStateByLocation(LED2,1);
	}
	// r37 > vTemp
	if(r37 > VTemp)
	{	
		if(count >= 100)
		{
			rollbackLedByLocation(LED3);
			count = 0;
		}
	}
	else 
		changeLedStateByLocation(LED3,0);
}

这边不能够直接使用HAL_GetTick()函数计时,因为使用该函数计时会LED闪烁时出现频率不一致的情况。
此处,特意使用count来计数定时,该变量是放置在一个1ms触发一次的定时器中。

LCD相关

样例代码
由于LCD的相关代码在官方给的比赛资源数据包中存在,因此,可以直接调用资源包中的.c、.h文件来完成LCD的相关初始化以及显示。这是一个简单的LCD初始化函数,其功能是将LCD显示屏初始化为一个背景色为黑色、字体颜色为白色的屏幕,具体代码如下:

/******************************************************************************
* 函数功能:LCD初始化
* 函数参数:无
* 函数返回值:无
*******************************************************************************/
void lcdInit(void)
{
	//HAL库的初始化
	LCD_Init();
	//设置LCD的背景色
	LCD_Clear(Black);
	//设置LCD字体颜色
	LCD_SetTextColor(White);
	//设置LCD字体的背景色
	LCD_SetBackColor(Black);
}

在显示时,可以借助于sprintf()函数将需要显示的数据格式成一个字符串,再在LCD上显示这个字符串。

	char temp[20];
	LCD_DisplayStringLine(Line1,(u8*) "       DATA    ");
	sprintf(temp,"   VR37:%4.2fV    ",r37);

为了操作LED与LCD显示方便,不让其相互干扰,小编这里对LCD进行了部分源码改写,使得每次LCD显示时不改变LED的显示状态,具体的方法各位可以点击查看【蓝桥杯】一文解决蓝桥杯嵌入式开发板(STM32G431RBT6)LCD与LED显示冲突问题,并讲述LCD翻转显示。

下面附上小编完成模拟赛的LCD部分的详细代码:

/**
  * @Name    lcdDisplay
  * @brief   LCD显示数据
  * @param   char mod:显示模式 可以切换显示数据
  * @retval  None
  * @author  黑心萝卜三条杠
  * @Data    2023-04-02
 **/
static void lcdDisplay()
{
	char temp[20];
	// 数据显示界面
	if(LCDmod == 0)
	{
		LCD_DisplayStringLine(Line1,(u8*) "       DATA    ");
		sprintf(temp,"   VR37:%4.2fV    ",r37);
		LCD_DisplayStringLine(Line3,(u8*)temp);
		sprintf(temp,"   PA7:%dHz     ",Pa7Frd);
		LCD_DisplayStringLine(Line5,(u8*)temp);
	}
	// 参数显示界面
	else if(LCDmod == 1)
	{
		LCD_ClearLine(Line1);
		LCD_DisplayStringLine(Line3,(u8*)"       PARA     ");
		sprintf(temp,"     VP1:%3.1fV   ",VTemp);
		LCD_DisplayStringLine(Line5,(u8*)temp);
	}
}

(是不是非常简单粗暴。哈哈哈哈)

按键相关

    通过查询产品手册知,开发板上的四个按键引脚为PB0~PB2、PA0
CubeMX配置
【蓝桥杯嵌入式】第十四届蓝桥杯嵌入式[模拟赛1]程序设计试题及详细题解
样例代码
由于主板上的按键数量较少,因此小编这里的按键读取操作相对简单粗暴,其实现步骤为:

  • 步骤一:判断按键是否按下以及按键锁是否打开,在两者同时满足的情况下进入下一步;
  • 步骤二:关闭按键锁并且延时10ms,实现按键的延时消抖;
  • 步骤三:再次读取每个按键的值,判断按键按下的位置;
  • 步骤四:读取每个按键的状态,如果都处于松开状态就打开按键锁;

具体代码实现:

/*********************************************
 * 函数功能:按键扫描 含按键消抖 无长按短按设计
 * 函数参数:无
 * 函数返回值:按键的位置
 *            返回值说明:B1-1 B2-2 B3-3 B4-4
*********************************************/
unsigned char scanKey(void)
{
	//按键锁
	static unsigned char keyLock = 1;
    //记录按键消抖时间
    // static uint16_t keyCount = 0;

	//按键按下
    if((HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0) == RESET || HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == RESET
      || HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2) == RESET || HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == RESET) 
      && keyLock == 1){
        //给按键上锁 避免多次触发按键
        keyLock = 0;
        
        //按键消抖 这里最好不要使用延时函数进行消抖 会影响系统的实时性
        // if(++keyCount % 10 < 5) return 0;
        // if(HAL_GetTick()%15 < 10) return 0;
        HAL_Delay(10);

        //按键B1
        if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0) == RESET){
            return 1;
        }
        //按键B2
        if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == RESET){
            return 2;
        }
        //按键B3
        if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2) == RESET){
            return 3;
        }
        //按键B4
        if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == RESET){
            return 4;
        }
    }
    //按键松开
    if((HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0) == SET && HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == SET
      && HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2) == SET && HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == SET) 
      && keyLock == 0){
        //开锁
        keyLock = 1;
    }
    return 0;
}

调用上述函数后,即可判断每次按键按下的位置,之后的按键逻辑函数就相对简单了,大家一起来看看吧!

/***************************************
* 函数功能:按键逻辑函数
* 函数参数:无
* 函数返回值:无
***************************************/
static void keyPro(void)
{
	// 按键扫描
	unsigned char keyRising = scanKey();
	switch(keyRising)
	{
		// B1  切换显示界面
		case 1:
			LCDmod ^= 1;
			break;
		// B2 参数界面下增加电压参数
		case 2:
			if(LCDmod)
			{
				VTemp += 0.3f;
				if(VTemp > 3.3f) VTemp = 0.0f;
			}
			break;
		// B3 数据界面下调节频率
		case 3:
			if(!LCDmod)
			{
				Pa7Frd += 1000;
				if(Pa7Frd > 10000) Pa7Frd = 1000;
			}
			break;
		// 其他
		default:
			break;
	}
}

定时器相关

CubeMX配置
本届试题定时器的功能为PWM输入,PWM输出时,如果大家不需要改变其占空比或者是频率,那么大家就可以不用再管理这些个定时器了。

大家一起来看看定时器的PWM输出的配置吧!
【蓝桥杯嵌入式】第十四届蓝桥杯嵌入式[模拟赛1]程序设计试题及详细题解

样例代码
模拟题中,需要大家能够改变PWM输出的频率或占空比,大家对这个也非常感兴趣吧,那么大家一起来看看吧!😉😉😉

/***************************************
* 函数功能:按键逻辑函数
* 函数参数:无
* 函数返回值:无
***************************************/
static void changePWMData(void)
{
	// 频率发生了更新 应该更新定时器频率
	if(Pa7Frd != oldPa7Frd)
	{
		__HAL_TIM_SetAutoreload(&htim3,1000000/Pa7Frd-1);
		HAL_TIM_GenerateEvent(&htim3,TIM_EVENTSOURCE_UPDATE);
		oldPa7Frd = Pa7Frd;
	}
	// 占空比发生了更新 应该更新定时器占空比
	if(Pa7Duty != oldPa7Duty || Pa7Frd != oldPa7Frd)
	{
		__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,(int)((Pa7Duty*1.0/100.0)*(1000000/Pa7Frd)+0.5));
		oldPa7Duty = Pa7Duty;
	}
}

哦!对了,大家在使用定时器前还需要使用函数开启定时器的PWM功能嗷(其实这里我更喜欢说初始化) HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);

还有一个重要的东西,小编在更改PWM周期后更新了定时器,因为小编发现不更新改变定时器输出PWM的频率是没啥用的。这里的更新有两种方法:

  • 方法一:直接更改定时器的寄存器——TIM2->EGR = TIM_EGR_UG;
  • 方法二:使用函数更新,这里我们使用的触发源为计时器更新事件——HAL_TIM_GenerateEvent(&htim2, TIM_EVENTSOURCE_UPDATE)

串口相关

CubeMX配置
    配置时一定一定记得改引脚!!!【蓝桥杯嵌入式】第十四届蓝桥杯嵌入式[模拟赛1]程序设计试题及详细题解
样例代码
本程序中小编使用的是中断接收PC发送的数据其函数原型为:

// 函数原型:
HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
// 参数解析:
UART_HandleTypeDef *huart:串口通道;
uint8_t *pData:存放数据的buff;
uint16_t Size:一次接收数据的长度

在使用时还需要使用该函数“中断初始化”,否则不能够进入中断接收数据;

下面就是一个串口接收定长数据的demo:

/**********************************************串口相关************************************/

//定义一个串口信息的结构
uint8_t _ucRxbuff[1];

/***使用HAL_UART_Receive_IT中断接收数据 每次接收完成数据后就会执行该函数***/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{	
	if(huart->Instance == USART1){
		// 重新使能中断		
		HAL_UART_Receive_IT(huart,(uint8_t *)&_ucRxbuff,sizeof(_ucRxbuff)); 
	}
}

本届试题要求的是定长数据,因此我们只要使用HAL_UART_Receive_IT(huart,(uint8_t *)&_ucRxbuff,sizeof(_ucRxbuff)); 触发中断即可,不需要改变串口接收数据的长度。

题中要求串口功能不仅仅是接收数据这么简单,其还需要能够解析串口接收的数据,并且以此为指令将合适的结果发送给PC。下面就是小编写的一个简单的数据处理demo:

/**
  * @Name    usartPro
  * @brief   串口处理逻辑函数
  * @param   None
  * @retval  None
  * @author  黑心萝卜三条杠
  * @Data    2023-04-02
 **/
static void usartPro(void)
{
#if 0
	/************* 串口接收一位数据*********/
	// 判断是否接收到串口数据
	if(_ucRxbuff[0] == '0' || strlen((char*)_ucRxbuff) == 0) return ;
	// 判断是否接收到串口数据
	if('0'<_ucRxbuff[0] && _ucRxbuff[0]<='9')
		Pa7Duty = (_ucRxbuff[0] - '0')*10;
	// 其他情况发送错误信息
	else
		HAL_UART_Transmit_IT(&huart1,(u8*)"error\r\n",sizeof((char*)"error"));
	// 清空有效值
	_ucRxbuff[0] = '0';
#else
	/************* 串口接收多位数据*********/
	// 判断是否接收到串口数据
	if(strlen((char*)ucRxbuff) == 0) return ;
	// 判断是否接收到串口数据长度是否合理 串口数据格式是否正确
	else if(strlen((char*)ucRxbuff) == 1 && '0'<ucRxbuff[0] && ucRxbuff[0]<='9')
		Pa7Duty = (ucRxbuff[0] - '0')*10;
	else
		HAL_UART_Transmit_IT(&huart1,(u8*)"error\r\n",sizeof((char*)"error\r\n"));
	memset(ucRxbuff,0,sizeof((char*)ucRxbuff));
	lenBuff = 0;
#endif
}

文章福利

下边是小编个人整理出来免费的蓝桥杯嵌入式福利,有需要的童鞋可以自取哟!🤤🤤🤤
省赛:

  • 【蓝桥杯嵌入式】第十一届蓝桥杯嵌入式省赛(第二场)程序设计试题及其题解
  • 【蓝桥杯嵌入式】第十二届蓝桥杯嵌入式省赛程序设计试题以及详细题解
  • 【蓝桥杯嵌入式】第十三届蓝桥杯嵌入式省赛程序设计试题及其详细题解
  • 【蓝桥杯嵌入式】第十三届蓝桥杯嵌入式省赛(第二场)程序设计试题及其题解
  • 【蓝桥杯嵌入式】第十三届蓝桥杯嵌入式省赛客观题以及详细题解
  • 【蓝桥杯嵌入式】第十二届蓝桥杯嵌入式省赛客观题及详细题解

国赛:

  • 【蓝桥杯嵌入式】第十二届蓝桥杯嵌入式国赛程序设计试题以及详细题解
  • 【蓝桥杯嵌入式】第十三届蓝桥杯嵌入式国赛客观题以及详细题解
  • 【蓝桥杯嵌入式】第十二届蓝桥杯嵌入式国赛客观题及详细题解

其他:

  • 【蓝桥杯嵌入式】第十四届蓝桥杯嵌入式[模拟赛1]客观题及详细题解
  • 【蓝桥杯嵌入式】第十四届蓝桥杯嵌入式[模拟赛2]客观题及详细题解
  • 【蓝桥杯嵌入式】第十四届蓝桥杯嵌入式[模拟赛2]程序设计试题及详细题解
  • 【蓝桥杯】一文解决蓝桥杯嵌入式开发板(STM32G431RBT6)LCD与LED显示冲突问题,并讲述LCD翻转显示

这是小编自创的嵌入式交流群Q:726128226,欢迎各位大佬加入交流哟!😁😁😁

也欢迎大家留言或私信交流,共同进步哟!😉😉😉文章来源地址https://www.toymoban.com/news/detail-412432.html

到了这里,关于【蓝桥杯嵌入式】第十四届蓝桥杯嵌入式[模拟赛1]程序设计试题及详细题解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【蓝桥杯嵌入式】第十四届蓝桥杯嵌入式省赛[第一场]程序设计题以及详细题解

    【蓝桥杯嵌入式】第十四届蓝桥杯嵌入式省赛[第一场]程序设计题以及详细题解

      今年的第一场比赛绝对np,官方将串口直接省掉了,将其替换成很多小功能,如:切换计时、频率均匀变化、锁机制等等,总的来说本届赛题的难度提升了不少。   本届试题需要用到的功能模块有 LCD 、 LED 、 按键 、 定时器输入捕获 、 定时器PWM输出 、 ADC获取 ,虽然这

    2023年04月17日
    浏览(41)
  • 第十四届蓝桥杯模拟赛(第一期)——C语言版

    问题描述 十进制整数 2 在十进制中是 1 位数,在二进制中对应 10 ,是 2 位数。 十进制整数 22 在十进制中是 2 位数,在二进制中对应 10110 ,是 5 位数。 请问十进制整数 2022 在二进制中是几位数? 答案提交 这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果

    2023年04月09日
    浏览(39)
  • 第十四届蓝桥杯单片机第二场模拟赛程序

    第十四届蓝桥杯单片机第二场模拟赛程序

    第十四届蓝桥杯单片机第二场模拟赛程序(少量bug) 题目来源于4T评测网 www.4t.wiki 使用大赛组委会提供的国信长天单片机竞赛实训平台,完成本试题的程序设计与调试。程序编写、调试完成后,选手需通过考试系统提交以准考证号命名的hex文件。不符合以上文件提交要求的作

    2023年04月14日
    浏览(40)
  • 2023第十四届蓝桥杯模拟赛第二期个人题解(Java实现)

    2023第十四届蓝桥杯模拟赛第二期个人题解(Java实现)

    2023第十四届蓝桥杯校内模拟赛第三期个人题解(Java实现) 蓝桥杯真题——单词分析(Java实现) 这篇文章为个人题解,假如我写的解法有误,欢迎大家在评论区指正👏👏!!!希望这篇文章对你有帮助❤❤ 请找到一个大于 2022 的最小数,这个数转换成二进制之后,最低的

    2023年04月23日
    浏览(430)
  • 蓝桥杯第十四届蓝桥杯模拟赛第三期考场应对攻略(C/C++)

    蓝桥杯第十四届蓝桥杯模拟赛第三期考场应对攻略(C/C++)

    这里把我的想法和思路写出来,恳请批评指正! 目录 考前准备 试题1: 试题2: 试题3: 试题4: 试题5: 试题6: 试题7: 试题8: 试题9: 试题10: 总结: 考前五分钟,开十个源文件,并把头文件等必须写的部分写出来,写完的程序一定要有顺序地保留 问题描述 请找到一个

    2024年02月02日
    浏览(399)
  • 第十四届蓝桥杯模拟赛(第三期)(大学B组)Java组

    第十四届蓝桥杯模拟赛(第三期)(大学B组)Java组

    修改了第六题余数为0时输出应为7的问题 修改了第五题和第九题可能超时的问题 前些天参加了第十四届蓝桥杯模拟赛(第三期),收获颇丰,自己也走了一点点弯路,记录一下自己考试中犯的一些错误。也希望在这期间可以提高一下自己的编程水平。 纯小白大佬请喷! 问题

    2023年04月24日
    浏览(37)
  • 第十四届蓝桥杯校模拟赛-编程大题详解+代码(二)

    第十四届蓝桥杯校模拟赛-编程大题详解+代码(二)

    前言: 这几天有不少小伙伴催促我尽快更新后五道编程题题解,然鄙人实在水平有限,实事求是,能力不足,不堪众望。思索良久,第九题有解题思路且已完成部分解题,但未完全完成,第十题尚未有思路。在此愿有大佬指点一二! 目录 一、做不完的核酸 问题描述 1.1 代码

    2024年02月02日
    浏览(8)
  • 【蓝桥杯Web】第十四届蓝桥杯(Web 应用开发)模拟赛 2 期 | 精品题解

    【蓝桥杯Web】第十四届蓝桥杯(Web 应用开发)模拟赛 2 期 | 精品题解

    🧑‍💼 个人简介:一个不甘平庸的平凡人🍬 🖥️ 蓝桥杯专栏:蓝桥杯题解/感悟 🖥️ TS知识总结:十万字TS知识点总结 👉 你的一键三连是我更新的最大动力❤️! 📢 欢迎私信博主加入前端交流群🌹 第十四届蓝桥杯 Web 应用开发模拟赛第二期昨天正式开始了(本来写的

    2024年02月02日
    浏览(37)
  • 2022 第十四届蓝桥杯模拟赛第二期题目题解(比赛时使用方法)

    2022 第十四届蓝桥杯模拟赛第二期题目题解(比赛时使用方法)

    目录 第一题:最小的2022 第二题:经过天数 第三题:特殊的十六进制数 第四题:矩阵的最小路径 第五题:质数拆分 第六题:拷贝时间 第七题:单词去重 第八题:最短回文串 第九题:多少个X? 第十题:最小交换 问题描述 请找到一个大于 2022 的最小数,这个数转换成二进

    2023年04月11日
    浏览(39)
  • 【蓝桥杯Web】第十四届蓝桥杯(Web 应用开发)模拟赛 1 期-职业院校组 | 精品题解

    【蓝桥杯Web】第十四届蓝桥杯(Web 应用开发)模拟赛 1 期-职业院校组 | 精品题解

    🧑‍💼 个人简介:一个不甘平庸的平凡人🍬 🖥️ Nodejs专栏:Node.js从入门到精通 🖥️ TS知识总结:十万字TS知识点总结 👉 你的一键三连是我更新的最大动力❤️! 📢 欢迎私信博主加入前端交流群🌹 上篇文章已经对大学组的十道题做了解析,有的小伙伴私信我说能不

    2024年02月02日
    浏览(36)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包