基于RASC的keil电子时钟制作(瑞萨RA)(8)----按键修改数码管时间

基于RASC的keil电子时钟制作8_按键修改数码管时间

  • 概述
  • 硬件准备
  • 视频教程
  • 配置按键管脚
  • 按键设置
  • 主程序
  • timer_smg.c
  • timer_smg.h

概述

前几节课程已经单独驱动了数码管和RTC,同时已经整合成了能够用数码管显示具体时间,但是无法修改时间,这节就来配置使用按键修改具体的日期。

硬件准备

首先需要准备一个开发板,这里我准备的是芯片型号R7FA2E1A72DFL的开发板:

在这里插入图片描述

在这里插入图片描述

视频教程

https://www.bilibili.com/video/BV12h4y1C7HW/

基于RASC的keil电子时钟制作(瑞萨RA)----(8)按键修改数码管时间

配置按键管脚

这里的按键对应管脚如下所示。
在这里插入图片描述

配置管脚为输入模式,同时加个上拉,这样默认电平为高电平,按键按下对应管脚为低电平。
在这里插入图片描述

按键设置

可以用R_IOPORT_PinRead()函数进行读取IO口电平状态,该函数只能读取一个端口的电平。
定义变量保存按键状态。

bsp_io_level_t sw1;//按键SW1状态
bsp_io_level_t sw2;//按键SW2状态
bsp_io_level_t sw3;//按键SW3状态
bsp_io_level_t sw4;//按键SW4状态
bsp_io_level_t qe_sw;//触摸电容状态int sw1_num1=0;//按键SW1计数值,去抖和长按短按判断
int sw2_num1=0;//按键SW2计数值,去抖和长按短按判断
int sw3_num1=0;//按键SW3计数值,去抖和长按短按判断
int sw4_num1=0;//按键SW4计数值,去抖和长按短按判断
int qe_sw_num1=0;//触摸按键计数值,去抖和长按短按判断
void qe_touch_sw(void);//数码管显示状态,0正常显示,1修改小时,2修改分钟,3保存修改数据,4温度,5湿度
int smg_mode=0;
int sec=0,min=0,hour=0;//保存时间数据
uint16_t time_mode_num=0;//定时器刷新时间,实现闪烁效果

在这里插入图片描述
定义主程序的while循环为10ms执行一次,方便按键的读取以及时间设置。

       R_BSP_SoftwareDelay(10U, BSP_DELAY_UNITS_MILLISECONDS);

在timer_smg.c中添加变量的定义。

//按键变量
extern  bsp_io_level_t sw1;//按键SW1状态
extern  bsp_io_level_t sw2;//按键SW2状态
extern  bsp_io_level_t sw3;//按键SW3状态
extern  bsp_io_level_t sw4;//按键SW4状态
extern  bsp_io_level_t qe_sw;//触摸电容状态extern int sw1_num1;//按键SW1计数值,去抖和长按短按判断
extern int sw2_num1;//按键SW2计数值,去抖和长按短按判断
extern int sw3_num1;//按键SW3计数值,去抖和长按短按判断
extern int sw4_num1;//按键SW4计数值,去抖和长按短按判断
extern int qe_sw_num1;//触摸按键计数值,去抖和长按短按判断//数码管显示状态,0正常显示,1修改小时,2修改分钟,3保存修改数据,4温度,5湿度
extern int smg_mode;
extern int sec,min,hour;//保存时间数据
extern uint16_t time_mode_num;//定时器刷新时间,实现闪烁效果

在这里插入图片描述

设置按sw1按键下1s进入下个模式,sw2进行时间小时和分钟的向下修改,sw3进行时间小时和分钟的向上修改。

void set_smg_button(void)
{R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_02_PIN_07, &sw1);R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_02_PIN_08, &sw2);R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_09_PIN_13, &sw3);R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_09_PIN_14, &sw4);if(sw1+sw2+sw3+sw4==4&&qe_sw==0)//按键都没按下,清除按键按下计数值{sw1_num1=0;sw2_num1=0;sw3_num1=0;sw4_num1=0;qe_sw_num1=0;}else if(sw1==0&&sw2&&sw3&&sw4&&qe_sw==0)//只有SW1按下{if(sw1_num1<1001)//按下小于10s,1001是防止变量在1000时候一直切换模式sw1_num1++;if(sw1_num1%200==0)//模式切换,按下{//buzzer_num=20;//蜂鸣器叫200msif(smg_mode>2)smg_mode=0;elsesmg_mode++;}if(smg_mode==6)smg_mode=0;}else if(sw2==0&&sw1&&sw3&&sw4&&qe_sw==0)//只有SW2按下{if(sw2_num1<30)//300ms 减一次sw2_num1++;else{sw2_num1=0;if(smg_mode==1){if(hour>0)hour--;elsehour=23;}else if(smg_mode==2){if(min>0)min--;elsemin=59;}}}else if(sw3==0&&sw1&&sw2&&sw4&&qe_sw==0)//只有SW3按下{if(sw3_num1<30)//300ms 减一次sw3_num1++;else{sw3_num1=0;if(smg_mode==1){if(hour<23)hour++;elsehour=0;}else if(smg_mode==2){if(min<59)min++;elsemin=0;}}}}

在timer_smg.c中添加该函数。
在这里插入图片描述

同时需要在在timer_smg.h中声明。

void set_smg_button(void);//处理数码管显示,当前状态修改

在这里插入图片描述

由于需要修改我们的RTC时钟数值,需要引入定义RTC的结构体。

extern rtc_time_t set_time;//RTC时间定义

在这里插入图片描述
修改完毕之后可以在定时器种进行数码管闪烁来提示用户。


void timer0_callback(timer_callback_args_t *p_args)
{/* TODO: add your own code here */if (TIMER_EVENT_CYCLE_END == p_args->event){time_mode_num++;if(time_mode_num>200)time_mode_num=0;if(smg_mode==0){if(num_flag==0)smg_1(num1);else if(num_flag==1)smg_2(num2);else if(num_flag==2)smg_3(num3);else if(num_flag==3)smg_4(num4);else if(num_flag==4)smg_maohao_open(1);   //冒号}else if(smg_mode==1)//修改时间小时{if(time_mode_num<100){if(num_flag==0)smg_1(hour/10);else if(num_flag==1)smg_2(hour%10);else if(num_flag==2)smg_3(min/10);else if(num_flag==3)smg_4(min%10);else if(num_flag==4)smg_maohao_open(1);   //冒号}else{if(num_flag==0)smg_1_close();else if(num_flag==1)smg_2_close();else if(num_flag==2)smg_3(min/10);else if(num_flag==3)smg_4(min%10);else if(num_flag==4)smg_maohao_open(1);   //冒号}}else if(smg_mode==2)//修改时间分钟{if(time_mode_num<100){if(num_flag==0)smg_1(hour/10);else if(num_flag==1)smg_2(hour%10);else if(num_flag==2)smg_3(min/10);else if(num_flag==3)smg_4(min%10);else if(num_flag==4)smg_maohao_open(1);   //冒号}else{if(num_flag==0)smg_1(hour/10);else if(num_flag==1)smg_2(hour%10);else if(num_flag==2)smg_3_close();else if(num_flag==3)smg_4_close();else if(num_flag==4)smg_maohao_open(1);   //冒号}}else if(smg_mode==3)//保存数据{set_time.tm_sec=sec;set_time.tm_min =min;set_time.tm_hour  =hour ;R_RTC_CalendarTimeSet(&g_rtc0_ctrl, &set_time);smg_mode=0;}num_flag++;if(num_flag==5)num_flag=0;}
}

初始化完毕的时候我们需要将时间数据保存下来。

       sec=set_time.tm_sec;//时间数据 秒min=set_time.tm_min;//时间数据 分钟hour=set_time.tm_hour;//时间数据 小时

在这里插入图片描述

在主程序中,每当秒数为0时候,保存分钟和小时的数据到min与hour,方便在设置时间的时候进行读取以及设置完毕时间之后更新到RTC里面。

               if(rtc_second==0&&smg_mode==0)//这个时候刷新变量{sec=rtc_second;//时间数据 秒min=rtc_minute;//时间数据 分钟hour=rtc_hour;//时间数据 小时} 

在这里插入图片描述
在主程序中加入按键处理函数。

set_smg_button();

在这里插入图片描述

主程序

#include "hal_data.h"
#include <stdio.h>
#include "smg.h"
#include "timer_smg.h"FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER//数码管变量
uint8_t num1=1,num2=4,num3=6,num4=8;//4个数码管显示的数值
uint8_t num_flag=0;//4个数码管和冒号轮流显示,一轮刷新五次//RTC变量
/* rtc_time_t is an alias for the C Standard time.h struct 'tm' */
rtc_time_t set_time =
{.tm_sec  = 50,      /* 秒,范围从 0 到 59 */.tm_min  = 59,      /* 分,范围从 0 到 59 */.tm_hour = 23,      /* 小时,范围从 0 到 23*/.tm_mday = 29,       /* 一月中的第几天,范围从 0 到 30*/.tm_mon  = 11,      /* 月份,范围从 0 到 11*/.tm_year = 123,     /* 自 1900 起的年数,2023为123*/.tm_wday = 6,       /* 一周中的第几天,范围从 0 到 6*/
//    .tm_yday=0,         /* 一年中的第几天,范围从 0 到 365*/
//    .tm_isdst=0;        /* 夏令时*/
};//RTC闹钟变量
rtc_alarm_time_t set_alarm_time=
{.time.tm_sec  = 58,      /* 秒,范围从 0 到 59 */.time.tm_min  = 59,      /* 分,范围从 0 到 59 */.time.tm_hour = 23,      /* 小时,范围从 0 到 23*/.time.tm_mday = 29,       /* 一月中的第几天,范围从 1 到 31*/.time.tm_mon  = 11,      /* 月份,范围从 0 到 11*/.time.tm_year = 123,     /* 自 1900 起的年数,2023为123*/.time.tm_wday = 6,       /* 一周中的第几天,范围从 0 到 6*/.sec_match        =  1,//每次秒到达设置的进行报警.min_match        =  0,.hour_match       =  0,.mday_match       =  0,.mon_match        =  0,.year_match       =  0,.dayofweek_match  =  0,};bsp_io_level_t sw1;//按键SW1状态
bsp_io_level_t sw2;//按键SW2状态
bsp_io_level_t sw3;//按键SW3状态
bsp_io_level_t sw4;//按键SW4状态
bsp_io_level_t qe_sw;//触摸电容状态int sw1_num1=0;//按键SW1计数值,去抖和长按短按判断
int sw2_num1=0;//按键SW2计数值,去抖和长按短按判断
int sw3_num1=0;//按键SW3计数值,去抖和长按短按判断
int sw4_num1=0;//按键SW4计数值,去抖和长按短按判断
int qe_sw_num1=0;//触摸按键计数值,去抖和长按短按判断
void qe_touch_sw(void);//数码管显示状态,0正常显示,1修改小时,2修改分钟,3保存修改数据,4温度,5湿度
int smg_mode=0;
int sec=0,min=0,hour=0;//保存时间数据
uint16_t time_mode_num=0;//定时器刷新时间,实现闪烁效果//RTC回调函数
volatile bool rtc_flag = 0;//RTC延时1s标志位
volatile bool rtc_alarm_flag = 0;//RTC闹钟
/* Callback function */
void rtc_callback(rtc_callback_args_t *p_args)
{/* TODO: add your own code here */if(p_args->event == RTC_EVENT_PERIODIC_IRQ)rtc_flag=1;else if(p_args->event == RTC_EVENT_ALARM_IRQ)rtc_alarm_flag=1;
}fsp_err_t err = FSP_SUCCESS;
volatile bool uart_send_complete_flag = false;
void user_uart_callback (uart_callback_args_t * p_args)
{if(p_args->event == UART_EVENT_TX_COMPLETE){uart_send_complete_flag = true;}
}#ifdef __GNUC__                                 //串口重定向#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endifPUTCHAR_PROTOTYPE
{err = R_SCI_UART_Write(&g_uart9_ctrl, (uint8_t *)&ch, 1);if(FSP_SUCCESS != err) __BKPT();while(uart_send_complete_flag == false){}uart_send_complete_flag = false;return ch;
}int _write(int fd,char *pBuffer,int size)
{for(int i=0;i<size;i++){__io_putchar(*pBuffer++);}return size;
}/*******************************************************************************************************************//*** main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used.  This function* is called by main() when no RTOS is used.**********************************************************************************************************************/
void hal_entry(void)
{/* TODO: add your own code here *//* Open the transfer instance with initial configuration. */err = R_SCI_UART_Open(&g_uart9_ctrl, &g_uart9_cfg);assert(FSP_SUCCESS == err);
/**********************数码管测试***************************************/
//              ceshi_smg();
/**********************定时器开启***************************************//* Initializes the module. */err = R_GPT_Open(&g_timer0_ctrl, &g_timer0_cfg);/* Handle any errors. This function should be defined by the user. */assert(FSP_SUCCESS == err);/* Start the timer. */(void) R_GPT_Start(&g_timer0_ctrl);/**********************RTC开启***************************************//* Initialize the RTC module*/err = R_RTC_Open(&g_rtc0_ctrl, &g_rtc0_cfg);/* Handle any errors. This function should be defined by the user. */assert(FSP_SUCCESS == err);/* Set the RTC clock source. Can be skipped if "Set Source Clock in Open" property is enabled. */R_RTC_ClockSourceSet(&g_rtc0_ctrl);/* R_RTC_CalendarTimeSet must be called at least once to start the RTC */R_RTC_CalendarTimeSet(&g_rtc0_ctrl, &set_time);/* Set the periodic interrupt rate to 1 second */R_RTC_PeriodicIrqRateSet(&g_rtc0_ctrl, RTC_PERIODIC_IRQ_SELECT_1_SECOND);R_RTC_CalendarAlarmSet(&g_rtc0_ctrl, &set_alarm_time);uint8_t rtc_second= 0;      //秒uint8_t rtc_minute =0;      //分uint8_t rtc_hour =0;         //时uint8_t rtc_day =0;          //日uint8_t rtc_month =0;      //月uint16_t rtc_year =0;        //年uint8_t rtc_week =0;        //周rtc_time_t get_time;sec=set_time.tm_sec;//时间数据 秒min=set_time.tm_min;//时间数据 分钟hour=set_time.tm_hour;//时间数据 小时while(1){if(rtc_flag){R_RTC_CalendarTimeGet(&g_rtc0_ctrl, &get_time);//获取RTC计数时间rtc_flag=0;rtc_second=get_time.tm_sec;//秒rtc_minute=get_time.tm_min;//分rtc_hour=get_time.tm_hour;//时rtc_day=get_time.tm_mday;//日rtc_month=get_time.tm_mon;//月rtc_year=get_time.tm_year; //年rtc_week=get_time.tm_wday;//周printf(" %d y %d m %d d %d h %d m %d s %d w\n",rtc_year+1900,rtc_month,rtc_day,rtc_hour,rtc_minute,rtc_second,rtc_week);//时间显示num1=rtc_hour/10;num2=rtc_hour%10;num3=rtc_minute/10;num4=rtc_minute%10;if(rtc_second==0&&smg_mode==0)//这个时候刷新变量{sec=rtc_second;//时间数据 秒min=rtc_minute;//时间数据 分钟hour=rtc_hour;//时间数据 小时}}if(rtc_alarm_flag){rtc_alarm_flag=0;printf("/************************Alarm Clock********************************/\n");}set_smg_button();R_BSP_SoftwareDelay(10U, BSP_DELAY_UNITS_MILLISECONDS);}#if BSP_TZ_SECURE_BUILD/* Enter non-secure code */R_BSP_NonSecureEnter();
#endif
}

timer_smg.c

/** timer_smg.c**  Created on: 2023年7月3日*      Author: a8456*/
#include "timer_smg.h"
//数码管变量
extern uint8_t num1,num2,num3,num4;//4个数码管显示的数值
extern uint8_t num_flag;//4个数码管和冒号轮流显示,一轮刷新五次//按键变量
extern  bsp_io_level_t sw1;//按键SW1状态
extern  bsp_io_level_t sw2;//按键SW2状态
extern  bsp_io_level_t sw3;//按键SW3状态
extern  bsp_io_level_t sw4;//按键SW4状态
extern  bsp_io_level_t qe_sw;//触摸电容状态extern int sw1_num1;//按键SW1计数值,去抖和长按短按判断
extern int sw2_num1;//按键SW2计数值,去抖和长按短按判断
extern int sw3_num1;//按键SW3计数值,去抖和长按短按判断
extern int sw4_num1;//按键SW4计数值,去抖和长按短按判断
extern int qe_sw_num1;//触摸按键计数值,去抖和长按短按判断//数码管显示状态,0正常显示,1修改小时,2修改分钟,3保存修改数据,4温度,5湿度
extern int smg_mode;
extern int sec,min,hour;//保存时间数据
extern uint16_t time_mode_num;//定时器刷新时间,实现闪烁效果extern rtc_time_t set_time;//RTC时间定义void timer0_callback(timer_callback_args_t *p_args)
{/* TODO: add your own code here */if (TIMER_EVENT_CYCLE_END == p_args->event){time_mode_num++;if(time_mode_num>200)time_mode_num=0;if(smg_mode==0){if(num_flag==0)smg_1(num1);else if(num_flag==1)smg_2(num2);else if(num_flag==2)smg_3(num3);else if(num_flag==3)smg_4(num4);else if(num_flag==4)smg_maohao_open(1);   //冒号}else if(smg_mode==1)//修改时间小时{if(time_mode_num<100){if(num_flag==0)smg_1(hour/10);else if(num_flag==1)smg_2(hour%10);else if(num_flag==2)smg_3(min/10);else if(num_flag==3)smg_4(min%10);else if(num_flag==4)smg_maohao_open(1);   //冒号}else{if(num_flag==0)smg_1_close();else if(num_flag==1)smg_2_close();else if(num_flag==2)smg_3(min/10);else if(num_flag==3)smg_4(min%10);else if(num_flag==4)smg_maohao_open(1);   //冒号}}else if(smg_mode==2)//修改时间分钟{if(time_mode_num<100){if(num_flag==0)smg_1(hour/10);else if(num_flag==1)smg_2(hour%10);else if(num_flag==2)smg_3(min/10);else if(num_flag==3)smg_4(min%10);else if(num_flag==4)smg_maohao_open(1);   //冒号}else{if(num_flag==0)smg_1(hour/10);else if(num_flag==1)smg_2(hour%10);else if(num_flag==2)smg_3_close();else if(num_flag==3)smg_4_close();else if(num_flag==4)smg_maohao_open(1);   //冒号}}else if(smg_mode==3)//保存数据{set_time.tm_sec=sec;set_time.tm_min =min;set_time.tm_hour  =hour ;R_RTC_CalendarTimeSet(&g_rtc0_ctrl, &set_time);smg_mode=0;}num_flag++;if(num_flag==5)num_flag=0;}
}void set_smg_button(void)
{R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_02_PIN_07, &sw1);R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_02_PIN_08, &sw2);R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_09_PIN_13, &sw3);R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_09_PIN_14, &sw4);if(sw1+sw2+sw3+sw4==4&&qe_sw==0)//按键都没按下,清除按键按下计数值{sw1_num1=0;sw2_num1=0;sw3_num1=0;sw4_num1=0;qe_sw_num1=0;}else if(sw1==0&&sw2&&sw3&&sw4&&qe_sw==0)//只有SW1按下{if(sw1_num1<1001)//按下小于10s,1001是防止变量在1000时候一直切换模式sw1_num1++;if(sw1_num1%200==0)//模式切换,按下{//buzzer_num=20;//蜂鸣器叫200msif(smg_mode>2)smg_mode=0;elsesmg_mode++;}if(smg_mode==6)smg_mode=0;}else if(sw2==0&&sw1&&sw3&&sw4&&qe_sw==0)//只有SW2按下{if(sw2_num1<30)//300ms 减一次sw2_num1++;else{sw2_num1=0;if(smg_mode==1){if(hour>0)hour--;elsehour=23;}else if(smg_mode==2){if(min>0)min--;elsemin=59;}}}else if(sw3==0&&sw1&&sw2&&sw4&&qe_sw==0)//只有SW3按下{if(sw3_num1<30)//300ms 减一次sw3_num1++;else{sw3_num1=0;if(smg_mode==1){if(hour<23)hour++;elsehour=0;}else if(smg_mode==2){if(min<59)min++;elsemin=0;}}}}

timer_smg.h

/*

  • timer_smg.h
  • Created on: 2023年7月3日
  •  Author: a8456
    

*/

#ifndef TIMER_SMG_H_
#define TIMER_SMG_H_

#include “hal_data.h”
void set_smg_button(void);//处理数码管显示,当前状态修改
#endif /* TIMER_SMG_H_ */

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C# 基础精讲】为什么选择C# ?

C#&#xff08;C Sharp&#xff09;是由微软开发的一种通用、面向对象的编程语言。它最初于2000年发布&#xff0c;自那时以来逐渐成为开发者的首选之一。C#的设计目标是提供一种简单、现代、可靠且安全的编程语言&#xff0c;使开发者能够轻松构建各种类型的应用程序。 为什么…

Android Studio 的Gradle版本修改

使用Android Studio构建项目时&#xff0c;需要配置Gradle&#xff0c;与Gradle插件。 Gradle是一个构建工具&#xff0c;用于管理和自动化Android项目的构建过程。它使用Groovy或Kotlin作为脚本语言&#xff0c;并提供了强大的配置能力来定义项目的依赖关系、编译选项、打包方…

Python-flask项目入门

一、flask对于简单搭建一个基于python语言-的web项目非常简单 二、项目目录 示例代码 git路径 三、代码介绍 1、安装pip依赖 通过pip插入数据驱动依赖pip install flask-sqlalchemy 和 pip install pymysql 2.配置数据源 config.py DIALECT mysql DRIVER pymysql USERN…

抖音seo矩阵系统源代码开发搭建技术分享

抖音SEO矩阵系统是一个较为复杂的系统&#xff0c;其开发和搭建需要掌握一定的技术。以下是一些技术分享&#xff1a; 技术分享 抖音SEO矩阵系统的源代码可以使用JAVA、Python、PHP等多种语言进行开发。其中&#xff0c;JAVA语言的应用较为广泛&#xff0c;因为JAVA语言有良好…

Stephen Wolfram:ChatGPT 的训练

The Training of ChatGPT ChatGPT 的训练 OK, so we’ve now given an outline of how ChatGPT works once it’s set up. But how did it get set up? How were all those 175 billion weights in its neural net determined? Basically they’re the result of very large…

《UNIX 传奇:历史与回忆》读后感

《UNIX 传奇&#xff1a;历史与回忆》 是 bwk&#xff08;Brian W. Kernighan&#xff09;2019 年的新作&#xff0c;回忆了 UNIX 在大半个世纪的风雨历程&#xff0c;是一本引人入胜的书籍。通过对 UNIX 操作系统的历史和发展进行详细的叙述和回顾&#xff0c;让我对这个操作系…

SpringBoot整合redis集群实现读写分离(哨兵模式)

1 首先要在Linux虚拟机上安装redis # 安装包存放目录 cd /usr/local/redis # 下载最新稳定版 wget https://download.redis.io/releases/redis-6.2.6.tar.gz # 解压 tar -zxvf redis-6.2.6.tar.gz # 进入解压后的目录 cd /usr/local/redis/redis-6.2.6/ # 编译 make # 执行 &q…

iOS——Block循环引用

Capturing ‘self’ strongly in this block is likely to lead to a retain cycle 典型的循环引用 self持有了blockblock持有了self(self.name) 这样就形成了self -> block -> self的循环引用 解决办法 强弱共舞 使用 中介者模式 __weak typeof(self) weakSelf sel…

以产品经理的角度去讲解原型图---会议OA项目

目录 一.前言 二.原型图 2.1 原型图是什么 3.1 原型图的作用 三.演示讲解 3.1 项目背景 3.2 项目介绍 3.2.1 会议管理&#xff08;会议的发起&#xff0c;通知&#xff09; 3.2.2 投票管理&#xff08;会议的流程重大决策记录&#xff09; 3.2.3 会议室管理 3.2.4 系统管…

谷粒商城第九天-对商品服务中所涉及到的表的思考

目录 一、总述 二、spu、sku、规格参数、销售属性之间的关系理解 三、相关表设计 1. 属性表 2. 基本属性分组表 3. 分组-基本属性关系表 ​4. spu基本属性值表 5. spu详情信息表 6. spu评论表 7. 商品sku值表 8. sku详情表 9. sku图片表 10. 分类表 11. 品牌表 …

助力工业物联网,工业大数据之服务域:安装主题分析实现【二十七】

文章目录 09&#xff1a;服务域&#xff1a;安装主题分析实现10&#xff1a;服务域&#xff1a;维修主题分析实现 09&#xff1a;服务域&#xff1a;安装主题分析实现 目标&#xff1a;掌握安装主题的需求分析及实现 路径 step1&#xff1a;需求step2&#xff1a;分析step3&am…

深入解析人脸识别技术:原理、应用与未来发展

人脸识别技术&#xff1a;从原理到应用 引言人脸识别技术的重要性和应用领域 人脸识别的基本原理图像采集与预处理特征提取与表征数据匹配与比对 传统人脸识别方法主成分分析&#xff08;PCA&#xff09;线性判别分析&#xff08;LDA&#xff09;小波变换在人脸识别中的应用 深…

Grafana集成prometheus(3.Grafana添加promethus数据)

添加数据库 选择Connections -> Datasources&#xff0c;点击Add New data source&#xff0c;填写Promitheus Server Url,点击 save & test完成配置 添加DashBorad 选择prometheus数据库选择code填入对应的查询公式(监控公式参考Prometheus监控公式)修改面板名称Ti…

Centos虚拟机忘记密码-修改密码

1.重启系统 2.在这个选择界面&#xff0c;按e建 3.找到如下位置&#xff0c;插入init/bin/sh 4.填写完成后按Ctrlx引导启动 5.输入mount -o remount, rw / (注意空格) 6.重置密码 出现以下为重置成功 7.执行touch /.autorelabel 8.退出exec /sbin/init 9.输入你的新密…

flutter开发实战-video_player视频播放功能及视频缓存

flutter开发实战-video_player视频播放功能及视频缓存 最近开发过程中video_player播放视频&#xff0c; 一、引入video_player 在pubspec.yaml引入video_player video_player: ^2.7.0在iOS上&#xff0c;video_player使用的是AVPlayer进行播放。 在Android上&#xff0c;…

代码分析:循环创建N个子进程——为什么最后一个属于父进程?

黑马C/C 2018年32期代码分析 //循环创建n个子进程 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h>int main() {int i 0;for(i0; i<3; i){//创建子进程pid_t pid fork();if(pid&…

EMD经验模态分解介绍

EMD概述 其实一种信号分解方法&#xff0c;是一种自适应的数据处理方法&#xff0c;适合非线性和非平稳时间序列的分析和研究&#xff0c;其本质是对数据序列或信号的平稳化处理。 将上面6个信号叠加如下&#xff1a; 就是6个简单信号叠加&#xff0c;形成一个复杂信号。 核心…

关于 Ubuntu 长按 shift 无效, 按 Esc 直接进入 grub 改密码的解决方法

本次长按shift没有反应&#xff0c;直接进入了系统界面&#xff0c;所以改用长按Esc键&#xff0c;步骤如下&#xff1a; 1. 长按esc&#xff0c;进入grub>提示 2.输入grub>normal &#xff0c;回车 3.上一步回车后&#xff0c;继续敲击Esc &#xff0c;出现grub界面 …

2023.08.01 驱动开发day8

驱动层 #include <linux/init.h> #include <linux/module.h> #include <linux/of.h> #include <linux/of_irq.h> #include <linux/interrupt.h> #include <linux/fs.h> #include <linux/gpio.h> #include <linux/of_gpio.h>#…

嵌入式开发学习(STC51-7-矩阵按键)

内容 按下S1-S16键&#xff0c;对应数码管最左边显示0-F 矩阵按键简介 独立按键与单片机连接时&#xff0c;每一个按键都需要单片机的一个I/O 口&#xff0c;若某单片机系统需较多按键&#xff0c;如果用独立按键便会占用过多的I/O口资源&#xff1b;而单片机 系统中I/O口资…