嵌入式蓝桥杯做题总结

news2024/11/15 10:50:48

第十二届省赛

按键代码

——自认为比较巧妙,定时器3被设置为10ms进入一次中断,代替了HAL_Delay(10)的方法消抖;

运用状态机机思想实现检测多个按键检测——且分为两个状态,其中一个状态PB1和PB2的按键不可使用

struct Key key[4] = {0, 0, 0};
uint8_t f;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  if (htim->Instance == TIM3)
  {
    key[0].Key_sta = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0);
    key[2].Key_sta = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1);
    key[3].Key_sta = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2);
    key[1].Key_sta = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);
  }//注意B2和B3对应Key[2]和Key[3];而B4对应Key[1];
  // Note that B2 and B3 correspond to Key[2] and Key[3]; B4 corresponds to Key[1];
  if (Para_flag==0) f=2;
  else f=4;
  //让按键B2~B3不可以在界面一中使用
  //注意上面的赋值
  // Make keys B2 to B3 unavailable in interface 1
  // Note the above assignment
  for (int i=0; i<f; i++)
  {
    switch (key[i].sta)
    {
      case 0:
        if (key[i].Key_sta==0)
        {
          key[i].sta=1;
        }
        break;
      case 1:
        if (key[i].Key_sta==0)
        {
          key[i].sta=2;
        }
        else
        {
            key[i].sta=0;
        }
        break;
      case 2:
        if(key[i].Key_sta==1) 
        {
          key[i].sta=0;
          if(key[i].time<100)
          {
            key[i].flag=1;
            key[i].time=0;
          }
        }
        else
        {
          key[i].time++;
          if (key[i].time>=100)
          {
            key[i].long_flag=1;
            key[i].time=0;
          }
        }
        break;
    }
  }
}
//注意Time是用于检测长按按键的,本体用不上

菜单函数

在菜单中实现了按键二次检测 伏笔回收

#include "menu.h"
uint8_t data1=2, data2=4, data3=2;
double data4=3.5, data5=2;
char text1[30] = " ", text2[30] = " ",text3[30] = " ", text4[30] = " ";
char flag_m=0,Para_flag=0,PWM_Flag=1;

void Menu(void)
{
  if (key[0].flag==1)
  {
    flag_m=!flag_m;
    LCD_Clear(Black);//每次展示菜单前先清屏
    key[0].flag=0;
  }
  if (key[1].flag==1)
  {
    PWM_Flag=!PWM_Flag;
    key[1].long_flag=0;
    key[1].flag=0;
  }
  //PWM和低电平的设置
  if (PWM_Flag==0)  __HAL_TIM_SetCompare(&htim15, TIM_CHANNEL_1, 20);
  else              __HAL_TIM_SetCompare(&htim15, TIM_CHANNEL_1, 0);
  if (flag_m==0)
  {
    Para_flag = 0;
    show_Data();
  }
  else
  {
    Para_flag = 1;
    show_Para();
  }
}
void show_Data(void)
{
  data3=8-data1-data2;
  sprintf(text1, "       Data         ");
  sprintf(text2, "   CNBR:%d          ",data1);
  sprintf(text3, "   VNBR:%d          ",data2);
  sprintf(text4, "   IDLE:%d          ",data3);
  LCD_DisplayStringLine(Line2, (unsigned char *)text1);
  LCD_DisplayStringLine(Line4, (unsigned char *)text2);
  LCD_DisplayStringLine(Line6, (unsigned char *)text3);
  LCD_DisplayStringLine(Line8, (unsigned char *)text4);  
}

void show_Para(void)
{
  sprintf(text1, "       Para         ");
  sprintf(text2, "   CNBR:%.2f          ",data4);
  sprintf(text3, "   VNBR:%.2f          ",data5);
  LCD_DisplayStringLine(Line2, (unsigned char *)text1);
  LCD_DisplayStringLine(Line4, (unsigned char *)text2);
  LCD_DisplayStringLine(Line6, (unsigned char *)text3);
  
  if (key[2].flag==1)
  {
    data4+=0.5;
    data5+=0.5;
    key[2].long_flag=0;
    key[2].flag=0;
  }
  if (key[3].flag==1)
  {
    data4-=0.5;
    data5-=0.5;
    key[3].long_flag=0;
    key[3].flag=0;
  }
}


我认为最难的就是串口部分

也可能是我的方法过于难了,应该可以使用先把串口数据存到数组,然后在数组中依靠下标来检测错误

遇到的难题--就是串口接收时检测到数据不符合格式,虽然重新开始存入数据,但是数据缓存区的数据没有被清空,会被带到下一次数据中,因此在寻找清空缓存区的方法过程中浪费很多时间,所幸也找到了对应的方法--暂时关闭中断接收,再在while循环中打开

//printf函数重写
int fputc(int c, FILE *stream)
{
  uint8_t ch[1]={c};
  HAL_UART_Transmit(&huart1, (unsigned char *)ch, 1, 0xFFFF);
  return c;
}


uint8_t rx=0;
uint8_t Index=0;
char temp_t[5];
char temp_n[5];
char temp_time[11];
char temp_minute[3];
char trash;
uint8_t usart_state=0;//用于标志是否接收完数据 是否可以进入处理函数

//方法1 在串口处初步处理信息——出现bug是无法清除串口缓存区导致的
//串口接收中断函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  if (huart->Instance == USART1)
  {
    if (Index<4)
    {
      HAL_UART_Receive_IT(&huart1, &rx, 1);
      temp_t[Index++]=rx;
    }
    else if(Index==4)
    {
      HAL_UART_Receive_IT(&huart1, &rx, 1);
      if (rx!=':')
      {
        //目的:出现错误时会打印出两个Error,尝试在出现错误后读取数据并清空数据来解决问题
        //方法一:失败——找不到对应的寄存器
        //把剩下的数据读出即可
        //实现方法while(sr&rx_flag)xxx=dr
//        while(USART1->ISR&0x10)
//        {
//          HAL_UART_Receive_IT(&huart1, &rx, 1);
//          trash=rx;
//        }
        //方法二:这个函数似乎不起作用
//        __HAL_UART_FLUSH_DRREGISTER(&huart1);
//        //方法三:似乎也不起作用
//        while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_RXNE)==SET)
//        {
//          HAL_UART_Receive_IT(&huart1, &rx, 1);
//        }
//        __HAL_UART_CLEAR_FLAG(&huart1,UART_FLAG_RXNE);
        
        //方法三:直接在这关闭串口中断接收,然后在while循环中再打开 效果出奇地好
        //可能关闭中断接收后,对应的缓存区的数据也被清除了
        HAL_UART_AbortReceive_IT(&huart1);
        
        
        Index=0;
        printf("Erorr\r\n");
      }
      else
      {
        Index++;
      }
    }
    else if (Index<9)
    {
      HAL_UART_Receive_IT(&huart1, &rx, 1);
      temp_n[(Index++)-5]=rx;
    }
    else if (Index==9)
    {
      HAL_UART_Receive_IT(&huart1, &rx, 1);
      if (rx!=':')
      {
//        while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_RXNE)==SET)
//        {
//          HAL_UART_Receive_IT(&huart1, &rx, 1);
//        }
//        __HAL_UART_CLEAR_FLAG(&huart1,UART_FLAG_RXNE);
        HAL_UART_AbortReceive_IT(&huart1);
        Index=0;
        printf("Erorr\r\n");
      }
      else
      {
        Index++;
      }
    }
    else if (Index>9)//前大段数字
    {
      if(Index<20)
      {
        HAL_UART_Receive_IT(&huart1, &rx, 1);
        temp_time[(Index++)-10]=rx;
      }
      else//只有分
      {
        HAL_UART_Receive_IT(&huart1, &rx, 1);
        temp_minute[(Index++)-20] = rx;
      }
    }
    if (Index==22)
    {
      usart_state=1; 
      Index=0;//表示一组数据接收完成 置标志位 可以进入数据处理函数
    }
//    if (Index==22)
//    {
//      for (int i=0;i<4;i++) printf("%c", temp_t[i]);
//      printf(":");
//      for (int i=0;i<4;i++) printf("%c", temp_n[i]);
//      printf(":");
//      for (int i=0;i<12;i++) printf("%c", temp_time[i]);
//    }
  }
}
#include "Myusart.h"

struct In in[8]={0};
uint8_t yn=0;//是否在车库内
uint8_t outcar_index=0;
double Money=0;
uint16_t Time_parking=0;
struct Time temp_time_struct;

void USART_Deal(void)
{
  if (usart_state==1)
  {
    //置零以便下次工作
    usart_state=0;
    //先把字符串数组的最后一位置为'\0'——必要操作
    temp_n[4]='\0';
    temp_t[4]='\0';
    temp_time[10]='\0';
    temp_minute[2]='\0';
    //对时间进行处理
    //注意strtol最大只能转int32_t的数 
    uint64_t number=strtol(temp_time, NULL, 10);//字符串数字转int类型
    uint8_t number1=strtol(temp_minute, NULL, 10);
    temp_time_struct.Y=number/1000000;//year
    temp_time_struct.M=number/10000%100;//month
    temp_time_struct.D=number/100%100;//day
    temp_time_struct.h=number%100;//hour
    temp_time_struct.m=number1;//min
    
    //Error情况
    if ((temp_time_struct.M>12)&& (temp_time_struct.D>31)&& (temp_time_struct.h>23)&& (temp_time_struct.m>59))
    {
      printf("Erorr\r\n");
      return ;
    }
    
    //遍历结构体数组寻找number1;//min是否已经停在车库
    for(int i=0; i<8; i++)
    {
      if (in[i].YN==1)
      {
        if (!strcmp(temp_n, in[i].num))
        {
          outcar_index=i;
          yn=1;
          //出停车库
          //并把对应车辆所有清零
        }
        else {yn=0;}
      }
      else {yn=0;}
    }
    //是否在车库内之后的操作
    if (yn==1)
    {
      //出停车库
      //并把对应车辆所有清零
      in[outcar_index].YN=0;
      Time_parking = (temp_time_struct.Y-in[outcar_index].t.Y)*8760
              +(temp_time_struct.M-in[outcar_index].t.M)*720
              +(temp_time_struct.D-in[outcar_index].t.D)*24
              +(temp_time_struct.h-in[outcar_index].t.h)
              +(bool)(temp_time_struct.m-in[outcar_index].t.m);
      
      if(!(strcmp(temp_t, "CNBR\0")))
      {
        Money=Time_parking*data4;
        data1--;
      }
      if ((!strcmp(temp_t, "VNBR\0")))
      {
        Money=Time_parking*data5;
        data2--;
      }
      printf("%s:%s:%d:%.2f\r\n", temp_t, temp_n, Time_parking, Money);
      printf("%d\r\n", in[outcar_index].YN);
    }
    else//进入停车库 记录信息
    {
      //判断车位是否已满 如果已满则取消操作
      data3=8-data1-data2;
      if ((data3-1)<0)
      {
        printf("Erorr\r\n");
        return ;
      }
      else
      {
        if(!(strcmp(temp_t, "CNBR\0")))
        {
          data1++;
        }
        if ((!strcmp(temp_t, "VNBR\0")))
        {
          data2++;
        }
        
      }
      //寻找结构体数组中的空位
      uint8_t temp_index=0;
      for(int i=0; i<8; i++)
      {
        if (in[i].YN==0)
        {
          temp_index=i;
        }
      }
      //赋值
      strcpy(in[temp_index].type, temp_t);
      strcpy(in[temp_index].num, temp_n);
      //注意strtol最大只能转int32_t的数 
      uint64_t number=strtol(temp_time, NULL, 10);//字符串数字转int类型
      uint8_t number1=strtol(temp_minute, NULL, 10);
      in[temp_index].t.Y=number/1000000;//year
      in[temp_index].t.M=number/10000%100;//month
      in[temp_index].t.D=number/100%100;//day
      in[temp_index].t.h=number%100;//hour
      in[temp_index].t.m=number1;//min
      in[temp_index].YN=1;
      printf("%s-",in[temp_index].type);
      printf("%s-",in[temp_index].num);
      printf("%d-%d-%d-%d-%d\r\n",in[temp_index].t.Y,in[temp_index].t.M,in[temp_index].t.D,in[temp_index].t.h,in[temp_index].t.m);
    }
  }
  
}

串口代码的优化

这次采取的方法是先把数据存到数组中,再根据下标判断数据是否符合规范

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  if (huart->Instance == USART1)
  {
    HAL_UART_Receive_IT(&huart1, &rx, 1);
    data[data_index++] = rx;
    if (data_index>=22)
    {
      //关闭串口接收中断——清空缓存区,以免有多余信息
      HAL_UART_AbortReceive_IT(&huart1);
      data_index=0;
      usart_state=1;
//      printf("%s", data);
    }
  }
}
void Usart_Deal_Better(void)
{
  if (usart_state==1)
  {
    //置零以便下次工作
    usart_state=0;
    if (!(data[3]==':')&&!(data[9]==':'))//判断':'格式
    {
      printf("Error");
      return ;
    }
    //判断数字是否正确
    strncpy(temp_time, data+10, 10);
    strncpy(temp_minute, data+20, 2);
    temp_time[10]='\0';
    temp_minute[2]='\0';
    uint64_t number=strtol(temp_time, NULL, 10);//字符串数字转int类型
    uint8_t number1=strtol(temp_minute, NULL, 10);
    temp_time_struct.Y=number/1000000;//year
    temp_time_struct.M=number/10000%100;//month
    temp_time_struct.D=number/100%100;//day
    temp_time_struct.h=number%100;//hour
    temp_time_struct.m=number1;//min
    
    if ((temp_time_struct.Y>2099)||(temp_time_struct.Y<2000)||(temp_time_struct.M>12)||(temp_time_struct.D>31)||(temp_time_struct.h>23)||(temp_time_struct.m>59))
    {
      printf("Error\r\n");
      return ;
    }
    
    //判断是否在停车场中
    //复制编号出来
    strncpy(temp_n, data+5, 4); 
    for (int i=0; i<8; i++)
    {
      if (in[i].YN==1)
      {
        if (!strcmp(temp_n, in[i].num))//如果在停车场中
        {
          if (strncmp(data, in[i].type, 4))
          {
            printf("Error\r\n");
            return ;
          }
          else 
          {
            outcar_index=i;
            yn=1;
            break;
          }
        }
        else//不在停车场中
        {
          yn=0;
        }
      }
      else yn=0;
    }
    
    uint8_t temp_index=0;//用于寻找结构体数组内的空位
    
    if (yn==0)//新来的
    {
      if (strncmp(data,"CNBR", 4)&&strncmp(data,"VNBR", 4))//判断停车类型
      {
        printf("Error\r\n");
        return ;
      }
      else//类型输入正确
      {
        data3=8-data1-data2;
        if ((data3-1)<=0)
        {
          printf("Error\r\n");
          return ;
        }
        else//停车位充足
        {
          if (!strncmp(data,"CNBR", 4))
          {
            data1++;
          }
          if (!strncmp(data,"VNBR", 4))
          {
            data2++;
          }
          for (int i=0; i<8; i++)//寻找结构体数组中的空位
          {
            if (in[i].YN==0)
            {
              temp_index=i;
              break;
            }
          }
          //登记信息
          strncpy(in[temp_index].type, data, 4);
          strncpy(in[temp_index].num, data+5, 4);
          strncpy(temp_time, data+10, 10);
          strncpy(temp_minute, data+20, 2);
          temp_time[10]='\0';
          temp_minute[2]='\0';
          uint64_t number=strtol(temp_time, NULL, 10);//字符串数字转int类型
          uint8_t number1=strtol(temp_minute, NULL, 10);
          
          in[temp_index].t.Y=temp_time_struct.Y;
          in[temp_index].t.M=temp_time_struct.M;
          in[temp_index].t.D=temp_time_struct.D;
          in[temp_index].t.h=temp_time_struct.h;
          in[temp_index].t.m=temp_time_struct.m;
          in[temp_index].YN=1;
          printf("%s-",in[temp_index].type);
          printf("%s-",in[temp_index].num);
          printf("%d-%d-%d-%d-%d\r\n",in[temp_index].t.Y,in[temp_index].t.M,in[temp_index].t.D,in[temp_index].t.h,in[temp_index].t.m);
        }
      }
    }
    else//出停车库 
    {
      in[outcar_index].YN=0;
      strncpy(temp_t, data, 4);
      Time_parking = (temp_time_struct.Y-in[outcar_index].t.Y)*8760
              +(temp_time_struct.M-in[outcar_index].t.M)*720
              +(temp_time_struct.D-in[outcar_index].t.D)*24
              +(temp_time_struct.h-in[outcar_index].t.h);
      if ((temp_time_struct.m-in[outcar_index].t.m>0))
      {
        Time_parking++;
      }  
      if(!(strcmp(temp_t, "CNBR\0")))
      {
        Money=Time_parking*data4;
        data1--;
      }
      if ((!strcmp(temp_t, "VNBR\0")))
      {
        Money=Time_parking*data5;
        data2--;
      }
      printf("%s:%s:%d:%.2f\r\n", temp_t, temp_n, Time_parking, Money);
      
    }
  }
}

十三届省赛

IIC部分

IIC的读写eeprom和读读eeprom之间必须要有时间间隔,否则会出现写入错误或者读出错误

例如图中的Delay10ms

ADC采样部分

由于之前ADC采集两个电位器电压是用了不同的两个ADC,而这次题目要求是用同一个ADC的不同通道,这就涉及到了ADC多通道采集的问题了

首先cubemx配置,打开对应的输入引脚

再打开扫描模式,连续转换,DMA转运

 

 代码甚至只需要一句

自己创建一个数组存储数据

HAL_ADC_Start_DMA(&hadc2, (uint32_t *)ADC_value,2);

仔细看芯片手册,板子上的电压采集是J11和J12口,因为没看清楚,导致浪费了3个小时检查错误

且要注意一直打开DMA转运会严重拖慢程序的执行,即导致板子上程序运行极为缓慢,所以可以在交互后需要获取ADC的值时打开ADC_DMA转运,接收好数据后立马关闭,这样就不会太大地影响板子的运行速度了

if (B4==0)//Data
      {
        HAL_ADC_Start_DMA(&hadc2, (uint32_t *)ADC_value,2);
        HAL_Delay(10);
        data1=ADC_value[0]*3.3/4096;
        data2=ADC_value[1]*3.3/4096;
        recd1++;
        recd1_5++;
        recdPA4_buff[PA4_Index++]=data1;
        recdPA5_buff[PA5_Index++]=data2;
        if (recd2<data1)    {recd2=data1;}
        if (recd3>data1)    {recd3=data1;}
        if (recd2_5<data2)  {recd2_5=data2;}
        if (recd3_5>data2)  {recd3_5=data2;}
        HAL_ADC_Stop_DMA(&hadc2);//记得关闭DMA,否则会导致程序运行缓慢
      }

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Claude 3 模型列表

claude-3-opus-20240229 这个模型就好

解锁AI大模型秘籍:未来科技的前沿探索

在当今这个技术高速发展的时代&#xff0c;人工智能&#xff08;AI&#xff09;已经成为了我们生活中不可或缺的一部分。从简单的个人助手到复杂的数据分析和决策制定&#xff0c;AI的应用范围日益扩大&#xff0c;其目的是为了让我们的生活变得更加智能化。本文旨在探讨AI如何…

计网面试题整理下

1. HTTP常见的状态码有哪些&#xff1f; 常见状态码&#xff1a; 200&#xff1a;服务器已成功处理了请求。 通常&#xff0c;这表示服务器提供了请求的网页。301 &#xff1a; (永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时&am…

STM32CubeMX学习笔记10 ---低功耗模式

在实际使用中很多产品都需要考虑低功耗的问题&#xff0c;STM32F10X提供了三种低功耗模式&#xff1a;睡眠模式&#xff08;Sleep mode&#xff09;、停机模式&#xff08;Stop mode&#xff09;和待机模式&#xff08;Standby mode&#xff09;。这些低功耗模式可以有效减少系…

gRPC-第二代rpc服务

在如今云原生技术的大环境下&#xff0c;rpc服务作为最重要的互联网技术&#xff0c;蓬勃发展&#xff0c;诞生了许多知名基于rpc协议的框架&#xff0c;其中就有本文的主角gRPC技术。 一款高性能、开源的通用rpc框架 作者作为一名在JD实习的Cpper&#xff0c;经过一段时间的学…

使用postman测试若依登录接口API-2

请求方式 由于登录控制器可知&#xff1a;该请求方式为Post请求 请求地址 在请求路径栏输入请求地址&#xff0c;如下图所示&#xff1a; 参数体 在Body键入所需参数&#xff0c;类型选择raw,数据格式选择"JSON"&#xff1a;如下图所示&#xff1a; 认证成功与失败…

SpringBoot-Thymeleaf

1.概念 Thymeleaf是一个模板引擎&#xff0c;它可以在我们开发前后端混合应用时发挥动态的从后端获取数据&#xff0c;并且展示在前端页面&#xff0c;它的出现代替了JSP 2.入门程序 分析Thymeleaf的源码可知&#xff0c;他的默认路径是templates&#xff0c;并且文件的后缀必须…

低代码平台开发实践:基于React的高效构建与创新【文末送书-29】

文章目录 背景低代码平台简介基于React的优势低代码平台的实际应用 低代码平台开发实践&#xff1a;基于React【文末送书-29】 背景 随着技术的不断进步和业务需求的日益复杂&#xff0c;低代码平台成为现代软件开发领域中备受关注的工具之一。在这个快节奏的时代&#xff0c;…

【QT】Qt Charts概述

目录 1 QtCharts模块 2 图表的主要组成部分 2.1 QChartView的功能 2.2 序列 2.3 坐标轴 2.4 图例 3 一个简单的QChart绘图程序 QtCharts是Qt提供的图表模块&#xff0c;在Qt5.7以前只有商业版才有Qt Charts&#xff0c;但是从Qt5.7开始&#xff0c;社区版本也包含了Qt C…

fortigate 防火墻通過CLT命令行 downgrade降級IOS

​Troubleshooting Tip: Downgrade of FortiOS fails due to BIOS check 通過u盤放入2個文件(Os命名為image.out,配置文件命名為fgt_system.conf),插入 fortigate 防火墻。一般防火墻就自動更新OS,但如果要降級,不會自動更新,需要在CLT裡頭操作一些設置後才能順利降級 …

指针中的回调函数与qsort的深度理解与模拟

今天给大家在更新一下指针类型的知识&#xff0c;这里讲到了一个库函数sqort&#xff0c;以及回调函数的理解。 望喜欢 目录 回调函数 qsort函数 qsort模拟实现 回调函数 回调函数就是⼀个通过函数指针调用的函数。 如果你把函数的指针&#xff08;地址&#xff09;作为参数…

Java - 获取汉字大写首字母输出

背景 有个项目需要将一批字符串的拼音首字母输出并大写&#xff0c;写了个工具类。 实现 需要引入外部jar。 <dependency><groupId>com.belerweb</groupId><artifactId>pinyin4j</artifactId><version>2.5.1</version> </dep…

数字人解决方案——阿里EMO音频驱动肖像生成能说话能唱歌的逼真视频

前言 数字可以分为3D数字人和2D数字人。3D数字人以虚幻引擎的MetaHuman为代表&#xff0c;而2D数字人则现有的图像或者视频做为输入&#xff0c;然后生成对口型的数字人&#xff0c;比如有SadTalker和Wav2Lip。 SadTalker&#xff1a;SadTalker是一种2D数字人算法&#xff0c;…

Android 中get请求网络数据 详细举例

请求链接 https://api.bilibili.com/x/web-interface/ranking 1.添加网络权限 依赖等 implementation com.squareup.okhttp3:okhttp:4.9.3 implementation com.google.code.gson:gson:2.8.92.写请求类network package com.example.myapplication;import android.graphics.Bi…

【C语言】Leetcode 876. 链表的中间节点

主页&#xff1a;17_Kevin-CSDN博客 专栏&#xff1a;《Leetcode》 题目 通过题目的要求可以判断出有两种示例要解决&#xff0c;一种是偶数节点的链表&#xff0c;一种是奇数节点的链表&#xff0c;应对这两种情况我们需要使程序对二者都可以兼容。 解决思路 struct ListNode…

【论文精读】I-JEPA

摘要 计算机视觉中&#xff0c;常采用基于不变性和基于生成的方法进行自监督学习。对比学习&#xff08;CL&#xff09;是典型的基于不变性的方法&#xff0c;通过预训练方法优化编码器&#xff0c;使其能生成同一图像的两个或多个视图的相似嵌入&#xff0c;其中图像视图通常由…

Linux安全加固功能

提示:工具下载链接在文章最后 目录 一.加固功能介绍二.配置加固功能1.配置安全加固功能1.1 开放目前设备监听的所有端口1.2 只开放80、443、20、21、22端口1.3 防火墙配置工具1.3.1 开放允许访问的端口1.3.2 删除允许访问的端口1.3.3 添加IP地址允许访问规则1.3.4 添加IP地址禁…

脾胃论笔记

焦虑会导致脾胃受伤 焦虑等不良情绪也会导致脾胃受伤&#xff0c;我们称其为肝气不舒。肝气不舒会导致脾胃系统出问题&#xff0c;这叫肝木横逆克脾土&#xff0c;木克土&#xff0c;脾胃就容易受伤。 这样的情况在现代社会特别多。这跟古人就不一样&#xff0c;古人生活相对…

matplotlib.animation 3d姿态动画

目录 演示效果&#xff1a; 演示代码&#xff1a; 保存为gif 演示效果&#xff1a; 演示代码&#xff1a; import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from matplotlib.animation import FuncAnimation# 定义人体关键点…