主頁 >  其他 > 【STM32】兩輪自平衡小車學習筆記2

【STM32】兩輪自平衡小車學習筆記2

2020-12-03 10:49:08 其他

文章目錄

  • 前言
  • 一、外部中斷按鍵消抖
    • 1、工程配置
    • 2、工程代碼
  • 二、 Usart與Printf函式重定向
    • 1、工程配置
    • 2、工程代碼
  • 三、STM32 Uart 接收資料
    • 1、工程代碼
  • 四、定時器編碼器模式讀取脈沖資料
    • 1、工程配置
    • 2、工程代碼
  • 五、PWM與TB6612FNG驅動電機
    • 1、工程配置
    • 2、工程代碼
  • 遇到的問題
  • 總結


前言

上周講到的消除按鍵抖動代碼用的是阻塞式等待
這次用第二種方式——非阻塞等待,就是判斷當前uwTick基準uwTick之間的差值是否大于目標“閾值”,使用這種結構相比較阻塞式等待能大幅提升效率

所用工具:

1、芯片: STM32F103C8T6

2、STM32CubeMx軟體

3、IDE: MDK-Keil軟體

4、STM32F1xx/STM32F4xxHAL庫


提示:以下是本篇文章正文內容,下面案例可供參考

一、外部中斷按鍵消抖

1、工程配置

  • 1、設定RCC
  • 2、設定串口
    1、設定按鍵PA8為GPIO_EXTI8
    2、設定GPIO mode 為 External lnterrupt Mode with Falling edge trigger detection(具有下降沿觸發檢測的外部中斷模式)
    3、設定GPIO Pull-up

    1、設定按鍵PB12為GPIO_Output
    2、設定GPIO mode 為 Output Push Pull(輸出推拉)
    3、設定GPIO NO pull-up and no pull-down
    4、設定Maximum output speed為High
  • 3、打開中斷
    點擊NVIC打開對應的Enabled按鈕
  • 4、創建工程
    點擊 GENERATE CODE,重新生成代碼,

2、工程代碼

點開工程的stm32f1xx_it.c可以看到下面的代碼

void EXTI9_5_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI9_5_IRQn 0 */

  /* USER CODE END EXTI9_5_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8);
  /* USER CODE BEGIN EXTI9_5_IRQn 1 */

  /* USER CODE END EXTI9_5_IRQn 1 */
}

右鍵 HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8)
點擊GO to Definition
可以看見下面的代碼

__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(GPIO_Pin);
  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_GPIO_EXTI_Callback could be implemented in the user file
   */
}

復制void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)到main.c的下面USER CODE BEGIN 4 和 USER CODE END 4 之間,然后加入下面的代碼,代碼中的HAL_GetTick() 也可以替換為 uwTick

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	static uint32_t TickBase=0;
    if(GPIO_Pin==Button_Pin && HAL_GetTick() - TickBase >= 30)
   {		
				TickBase = HAL_GetTick();
        HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
	}
}

二、 Usart與Printf函式重定向

1、工程配置

  • 1、設定
    在 Pinout&Configuration 界面中點擊左側 Connectivity 選擇 USART1,然后在 USART1 Mode and Configuration 的 Mode 中選擇 Asynchronous,Asynchronous 為異步通信的意思,Parameter Setting(基礎設定)為默認設定,其中波特率115200 Bits/s位元組長度8 Bits
  • 2、開啟中斷
  • 選擇 NVIC Setting,將Enable打鉤 ,啟用 USART1 中斷,

  • 3、創建工程
    點擊 GENERATE CODE,重新生成代碼,

2、工程代碼

在 MDK-ARM 工程里要把 USE MicroLIB 選上

打開 usart.c,在 /* USER CODE BEGIN 0 / 和 / USER CODE END 0 */ 把標準輸入輸入頭檔案 stdio.h 加進去,并且加入以下代碼

#include "stdio.h"
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */

繼續在 /* USER CODE BEGIN 1 / 和 / USER CODE END 1 */ 之間加入以下代碼:

/**
* @brief  Retargets the C library printf function to the USART.
* @param  None
* @retval None
*/
PUTCHAR_PROTOTYPE
{
    /* Place your implementation of fputc here */
    /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);

    return ch;
}


至此,我們已經完成了Printf函式的重定向,之后的代碼里面就可以直接使用Print函式了

三、STM32 Uart 接收資料

1、工程代碼

打開usart.c,在 /* USER CODE BEGIN 0 / 和 / USER CODE END 0 */ 之間加入以下代碼:

uint8_t uart1Rx[1024];//申請1024個位元組的陣列
uint8_t *pUart1Rx =uart1Rx;//定義一個指標,用來指向存放資料的陣列
uint16_t uart1Size;//接收到資料的長度

在 stm32f1xx_it.c 中右鍵 HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8);
GO to Definition
在HAL_UART_IRQHandler() 函式里加上這一段,

	/* UART in mode Idle -------------------------------------------------*/
  if(((isrflags & USART_SR_IDLE) != RESET) && ((cr1its & USART_CR1_IDLEIE) != RESET))
  {
     HAL_UART_IdleCpltCallback(huart);      
     return;
  } 

然后在HAL_UART_IRQHandler() 函式外面加上這段

__weak void HAL_UART_IdleCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);
  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_UART_TxCpltCallback could be implemented in the user file
   */
}

至此,整個 HAL_UART_IRQHandler() 函式,是這樣的,

void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
{
  uint32_t isrflags   = READ_REG(huart->Instance->SR);
  uint32_t cr1its     = READ_REG(huart->Instance->CR1);
  uint32_t cr3its     = READ_REG(huart->Instance->CR3);
  uint32_t errorflags = 0x00U;
  uint32_t dmarequest = 0x00U;

  /* If no error occurs */
  errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));
  if (errorflags == RESET)
  {
    /* UART in mode Receiver -------------------------------------------------*/
    if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
    {
      UART_Receive_IT(huart);
      return;
    }
  }

  /* If some errors occur */
  if ((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))
  {
    /* UART parity error interrupt occurred ----------------------------------*/
    if (((isrflags & USART_SR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
    {
      huart->ErrorCode |= HAL_UART_ERROR_PE;
    }

    /* UART noise error interrupt occurred -----------------------------------*/
    if (((isrflags & USART_SR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
    {
      huart->ErrorCode |= HAL_UART_ERROR_NE;
    }

    /* UART frame error interrupt occurred -----------------------------------*/
    if (((isrflags & USART_SR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
    {
      huart->ErrorCode |= HAL_UART_ERROR_FE;
    }

    /* UART Over-Run interrupt occurred --------------------------------------*/
    if (((isrflags & USART_SR_ORE) != RESET) && (((cr1its & USART_CR1_RXNEIE) != RESET) || ((cr3its & USART_CR3_EIE) != RESET)))
    {
      huart->ErrorCode |= HAL_UART_ERROR_ORE;
    }

    /* Call UART Error Call back function if need be --------------------------*/
    if (huart->ErrorCode != HAL_UART_ERROR_NONE)
    {
      /* UART in mode Receiver -----------------------------------------------*/
      if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
      {
        UART_Receive_IT(huart);
      }

      /* If Overrun error occurs, or if any error occurs in DMA mode reception,
         consider error as blocking */
      dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
      if (((huart->ErrorCode & HAL_UART_ERROR_ORE) != RESET) || dmarequest)
      {
        /* Blocking error : transfer is aborted
           Set the UART state ready to be able to start again the process,
           Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
        UART_EndRxTransfer(huart);

        /* Disable the UART DMA Rx request if enabled */
        if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
        {
          CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);

          /* Abort the UART DMA Rx channel */
          if (huart->hdmarx != NULL)
          {
            /* Set the UART DMA Abort callback :
               will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */
            huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError;
            if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
            {
              /* Call Directly XferAbortCallback function in case of error */
              huart->hdmarx->XferAbortCallback(huart->hdmarx);
            }
          }
          else
          {
            /* Call user error callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
            /*Call registered error callback*/
            huart->ErrorCallback(huart);
#else
            /*Call legacy weak error callback*/
            HAL_UART_ErrorCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
          }
        }
        else
        {
          /* Call user error callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
          /*Call registered error callback*/
          huart->ErrorCallback(huart);
#else
          /*Call legacy weak error callback*/
          HAL_UART_ErrorCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
        }
      }
      else
      {
        /* Non Blocking error : transfer could go on.
           Error is notified to user through user error callback */
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
        /*Call registered error callback*/
        huart->ErrorCallback(huart);
#else
        /*Call legacy weak error callback*/
        HAL_UART_ErrorCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */

        huart->ErrorCode = HAL_UART_ERROR_NONE;
      }
    }
    return;
  } /* End if some error occurs */

  /* UART in mode Transmitter ------------------------------------------------*/
  if (((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
  {
    UART_Transmit_IT(huart);
    return;
  }

  /* UART in mode Transmitter end --------------------------------------------*/
  if (((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
  {
    UART_EndTransmit_IT(huart);
    return;
  }

}

開啟中斷,將 usart.c 中MX_USART1_UART_Init(void) 函式的

if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }

改寫成

    if (HAL_UART_Init(&huart1) != HAL_OK)
    {
        Error_Handler();
    }
    else
    {
        HAL_UART_Receive_IT(&huart1,pUart1Rx,1);
    }
    __HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);

然后在 /* USER CODE BEGIN 1 / 和 / USER CODE END 1 */ 之間加入以下代碼:

/* USER CODE BEGIN 1 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if(huart == &huart1)
    {
        pUart1Rx++;
        uart1Size++;
        //HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
        HAL_UART_Receive_IT(&huart1,pUart1Rx,1);
    }
}

void HAL_UART_IdleCpltCallback(UART_HandleTypeDef *huart)
{
    __HAL_UART_CLEAR_IDLEFLAG(huart);

    if(huart == &huart1)
    {
        HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
        HAL_UART_Transmit(&huart1,uart1Rx,uart1Size,1000);
        pUart1Rx = uart1Rx;
        uart1Size=0;
    }
}
/* USER CODE END 1 */

STM32收到的資料,是這樣處理的,

    HAL_UART_Transmit(huart, &RxLenHi, 1, 1000);      // 發送長度高位
    HAL_UART_Transmit(huart, &RxLenlo, 1, 1000);      //  發送長度低位
    HAL_UART_Transmit(huart, uart4Rx, uart4RxLength, 1000);    // 發送接收到的資料

參考博客——STM32 Uart 接收不定長資料

四、定時器編碼器模式讀取脈沖資料

1、工程配置

  • 1、設定
    在左側 Pinout&Configuration 界面中的 Timers 下拉中點擊 TIM4,然后在 TIM4 Mode and Configuration 的 Mode 中將 Combined Channels 選擇為 Encoder Mode,即編碼器模式

    在 Configuration 中選擇 Parameter Setting 選項卡,,Counter Mode 默認為 Up,即向上計數,Counter Period 設定為 65535,即計數器周期,這是一個 16 位的自動加載暫存器,填寫范圍為 0~65535,Encoder Mode 設定為 Encoder Mode TI1 and TI2,即兩個輸入 TI1 和 TI2 都被用來作為增量編碼器的介面,Polarity 默認為 Rising Edge,即為捕獲上升沿,其他引數默認,

注意: 當 Encoder Mode 設定為 Encoder Mode TI1 and TI2 模式時,AB 兩相的上升沿和下降沿都會計數,所以計數值是實際脈沖值的 4 倍,即四倍頻,Channel1 和 Channel2 的 Polarity 引數默認是 Rising Edge,意思是在檢測到上升沿的時候就觸發編碼器模式介面捕獲 AB 相的值,并不是指只檢測 AB 相的上升沿,下降沿還是同樣會計數的,

  • 2、創建工程
    點擊 GENERATE CODE,重新生成代碼,

2、工程代碼

打開 MDK-ARM 工程,按下組合鍵 Ctrl+N(按住 Ctrl 鍵再按 N 鍵),新建一個檔案,再按下組合鍵 Ctrl+S,檔案名改為 encoder.c,保存到 MiaowLabs-DEMO 的 Src 檔案夾里,接著在 MDK-ARM 工程界面左側 Project 欄目雙擊 Application/User 檔案夾,把 encoder.c 加進來,
雙擊 encoder.c 檔案,把下面代碼敲進去

#include "tim.h"//包含tim頭檔案
#include "encoder.h"

int iTim4Encoder;//存放從TIM4定時器讀出來的編碼器脈沖

int GetTim4Encoder(void)//獲取TIM4定時器讀出來的編碼器脈沖
{
    iTim4Encoder = (short)(__HAL_TIM_GET_COUNTER(&htim4));//先讀取脈沖數
    __HAL_TIM_SET_COUNTER(&htim4,0);//再計數器清零
    return iTim4Encoder;//回傳脈沖數


再新建一個檔案 encoder.h 頭檔案,把檔案保存到 Inc 檔案夾,然后,把下面代碼敲進去,

#ifndef __ENCODER_H
#define __ENCODER_H

int GetTim4Encoder(void);//宣告函式

#endif

打開 main.c 檔案,在 main 函式中的 /* USER CODE BEGIN 1 / 和 / USER CODE END 1 */ 之間定義一個變數:

int iTempTim4Encoder; //臨時存放從TIM4編碼器介面捕獲到的脈沖資料

![在這里插入圖片描述](https://img-blog.csdnimg.cn/20201202001525804.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0NTRE5fQXJ0aHVy,size_16,color_FFFFFF,t_70)

在主回圈 while(1) 里,把以下代碼敲進去:

HAL_Delay(5000);//延時5秒
iTempTim4Encoder = GetTim4Encoder();//捕獲TIM4脈沖資料
printf("TIM4定時器編碼器模式捕獲脈沖 = %d \n",iTempTim4Encoder);//把脈沖資料列印出來
HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);//翻轉指示燈LED的電平

上面這段加入主回圈的代碼的意思,是 TIM4 定時器的編碼器捕獲脈沖,每隔 5 秒累計輸出一次脈沖資料,通過串口顯示在上位機上,

這里補充一個知識點:M 法測速,就是數固定時間內產生的脈沖數,像這里每隔 5 秒數一次累計起來的脈沖資料,就是用了 M 法測速,

代碼還沒寫完,有一句重要的代碼必須要加進去,TIM4 的編碼器介面模式才會啟用,我們在 main 函式的 /* USER CODE BEGIN 2 / 和 / USER CODE END 2 */ 之間加入:

HAL_TIM_Encoder_Start(&htim4, TIM_CHANNEL_ALL);//開啟TIM4的編碼器介面模式

五、PWM與TB6612FNG驅動電機

STM32 與 TB6612FNG 的主要接線:

PB0 --> AIN1
PB1 --> AIN2
PA3 --> BIN1
PA4 --> BIN2
TIM3_CH1 --> PWMA
TIM3_CH2 --> PWMB

1、工程配置

  • 1、設定
    打開工程,在左側 Pinout&Configuration 界面中的 Timers 下拉中點擊 TIM3,然后在 TIM3 Mode and Configuration 的 Mode 中將 Channel2 選擇為 PWM Generation CH2,并在下方的引數設定選項卡中將 Prescaler 設為 72,即預分頻系數(TIMx_PSC)設為 72Counter Period 設為 100,即計數周期(自動加載值 TIMx_ARR)設為 100Pulse 設為 100,即占空比設定為 100%
    回到 STM32CubeMX 軟體界面,在右側界面的芯片中分別點擊 PA3、PA4,并將其配置為 GPIO_Output,在 System Core 下拉選單中選擇 GPIO,然后在左側的 System Core 下拉選單中選擇 GPIO,然后在 GPIO Mode and Configuration 中對 PA3、PA4 引腳進行配置,GPIO output level 代表 GPIO 默認輸出電平,在這里設定為低電平GPIO mode 代表 GPIO 引腳模式,在這里設定為推挽輸出GPIO Pull-up/Pull-down 即 GPIO 上拉或下拉,在這里設定為既不上拉也不下拉Maximum output speed 即 最大輸出速度,在這里設定為低速User Label 即用戶標簽,在這里將 PA3 改為 BIN1,PA4 改為 BIN2,

  • 2、創建工程
    點擊 GENERATE CODE,重新生成代碼,

2、工程代碼

在 main.c 中的 /* USER CODE BEGIN 2 / 和 / USER CODE END 2 */ 之間加入以下代碼:

  /* USER CODE BEGIN 2 */
  HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);//開啟TIM3_CH2的PWM輸出
  HAL_GPIO_WritePin(BIN1_GPIO_Port, BIN1_Pin, GPIO_PIN_SET);//初始化BIN1引腳為低電平
  HAL_GPIO_WritePin(BIN2_GPIO_Port, BIN2_Pin, GPIO_PIN_RESET);//初始化BIN2引腳為高電平
  /* USER CODE END 2 */

然后,在主回圈中加入以下代碼:

	ButtonScan();
if(g_iButtonState == 1)//如果按鍵被按下
    {
        HAL_GPIO_TogglePin(BIN1_GPIO_Port,BIN1_Pin);//翻轉BIN1引腳電平,如果是低電平則翻轉為高電平,如果是高電平則翻轉為低電平
        HAL_GPIO_TogglePin(BIN2_GPIO_Port,BIN2_Pin);//翻轉BIN2引腳電平,如果是低電平則翻轉為高電平,如果是高電平則翻轉為低電平
        g_iButtonState = 0;//按鍵狀態歸0,代表松開
    }

上面這段代碼的意思是,每次按下按鍵,左側電機的轉動方向都會更換一次,默認是全速轉動(占空比 100%),

遇到的問題

1、以CubeMX生成的代碼為基礎,添加用戶代碼

使用時發現每一次重新生成代碼的時候,自己添加進去的代碼就會消失不見,網上查資料發現所有用戶自定義添加的代碼必須在BEGIN和END之間, 還有工程配置也要修改,若是下面的沒有配置,即使把代碼寫在了USER CODE BEGINE 中也會被覆寫,

2、編碼器資料為什么會輸出負數

如果 TI1 和 TI2 分別接電機的 A 相和 B 相的話,那么,當電機正轉的時候,如下圖計數器會向上計數,反轉的時候會向下計數,但是向下計數并不會出現負的值,依舊是從(0-ARR)計數,

獲取編碼器脈沖的代碼如下

int GetTim4Encoder(void)//獲取TIM4定時器讀出來的編碼器脈沖
{
    iTim4Encoder = (short)(__HAL_TIM_GET_COUNTER(&htim4));//先讀取脈沖數
    __HAL_TIM_SET_COUNTER(&htim4,0);//再計數器清零
    return iTim4Encoder;//回傳脈沖數

注意看,上面的代碼 iTim4Encoder = (short)(__HAL_TIM_GET_COUNTER(&htim4)); 使用了強制型別裝換,把暫存器的值讀出來了之后,轉換成了 short 型(2 位元組),范圍為(-32768-32767),此時當我們把計數器的初始值設定為 0 之后,如果出現反轉,它就會從 0 開始向下計數(0,65535,65534,…)但是經過強制型別轉換之后就變成了(0,-1,-2,…),

但是為什么 65535 會變成 -1 ?此時我們回到 short 的表示范圍(-32768-32767),也就是說原來 int 型變數當讀出來的值為 32767, 32768, 32769,…,65535,65536,65537… 的時候會因為強制轉換成 short 型變數而溢位轉換為 32767,-32768,-32767,…,-1,0,1 就這樣不斷地回圈下去,所以電機反轉的時候讀出的數就是反方向的速度值,不需要用 65535 去減去讀出的值再加上負號才可以得到方便觀察的值,我們只需要運用一個強制型別轉換就可以了,

3、為什么按鍵按下無法控制電機反轉
記得在主回圈里添加 ButtonScan(); 函式


總結

好多好多……沖沖沖!

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/229290.html

標籤:其他

上一篇:福建中煙RFID托盤運輸環節的出入庫管理

下一篇:關于LPC824Lite開發板下載程式時提示"Invalid ROM Table"

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more