\documentclass[全部作业]{subfiles}

\begin{document}

\date{2024年10月29日}
\begin{frame}
    %\maketitle
    \titlepage
\end{frame}

\begin{frame}
	\frametitle{目录}
	\tableofcontents[hideallsubsections]
\end{frame}

\section{第二次作业}

\subsection{准备}
\begin{frame}[fragile]
    将实验一的代码复制一份，并将exp1改名为exp2：
    \vspace{1em}

    \begin{minipage}[H]{0.3\linewidth}
        \begin{minted}[linenos=false]{text}
exp1
│  .mxproject
│  exp1.ioc
│
├─Core
│
├─Drivers
│
└─MDK-ARM
        exp1.uvprojx
        startup_stm32g473xx.s
        \end{minted}
    \end{minipage}
    {\Huge$\longrightarrow$}
    \begin{minipage}[H]{0.3\linewidth}
        \begin{minted}[linenos=false]{text}
    exp2
    │  .mxproject
    │  exp2.ioc
    │
    ├─Core
    │
    ├─Drivers
    │
    └─MDK-ARM
            exp2.uvprojx
            startup_stm32g473xx.s
        \end{minted}
    \end{minipage}
    \vspace{1em}

    需要改文件夹名、.ioc、.uvprojx这三个地方。
\end{frame}

\begin{frame}
    打开.uvprojx文件，修改调试器：
    \includegraphics{imgs/2024-10-29-11-36-58.png}
    \vspace{1em}

    \includegraphics[width=1\linewidth]{imgs/2024-10-29-11-35-44.png}
\end{frame}

\begin{frame}
    修改调试设置，把reset and run打勾，就不需要手动按重置按钮了。
    \includegraphics[width=1\linewidth]{imgs/2024-10-29-14-54-11.png}
\end{frame}

\subsection{端口修改}
\begin{frame}
    这样设置端口，点击生成代码。
    \includegraphics[width=1\linewidth]{imgs/2024-10-29-16-44-16.png}
\end{frame}

\begin{frame}
    将STM32核心板JP1的PA0~PA7与系统底板跑马灯控制端JP21相连。

    \includegraphics[width=0.3\linewidth]{imgs/IMG_20241029_204905_1.jpg}
    \includegraphics[width=0.3\linewidth]{imgs/IMG_20241029_205023.jpg}
\end{frame}

\subsection{代码修改}
\begin{frame}[fragile]
    main.c:
    \begin{multicols}{2}
        \begin{minted}[firstnumber=62]{C}
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration-------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */
  uint8_t FlashFlag = 0;
  uint16_t nShift = 0x0001;
  uint8_t i = 0;
  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */
  FlashLeds_GPIO_Port->ODR &= 0xffff;
  /* USER CODE END 2 */

        \end{minted}
    \end{multicols}
\end{frame}

\begin{frame}[fragile]
    main.c:
    \begin{multicols}{2}
        \begin{minted}[firstnumber=last]{C}
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    if (sSysTickTimer.bTimeOk) {
      sSysTickTimer.bTimeOk = 0;
      HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
      
      HAL_GPIO_WritePin(FlashLeds_GPIO_Port, nShift, GPIO_PIN_SET);


      // FlashLeds_GPIO_Port->ODR &= 0xFF00;
      // FlashLeds_GPIO_Port->ODR |= (~nShift) & 0x00FF;

      if (i < 7) 
        nShift <<= 1;
      else
        nShift >>= 1;

      i++;

      if (i >= 14) {
        i = 0;
        nShift = 0x0001;
      }

      HAL_GPIO_WritePin(FlashLeds_GPIO_Port, nShift, GPIO_PIN_RESET);

      // if (FlashFlag != 0) {

      // }
    }
  }
  /* USER CODE END 3 */
}
        \end{minted}
    \end{multicols}
\end{frame}

\subsection{改进}
\begin{frame}[fragile]
    目前的闪烁频率较慢，可以修改部分代码使灯闪烁得更快。
    在variable.h中增加10毫秒计数和100毫秒标志位：
    \begin{minted}[firstnumber=9]{C}
typedef struct {
    uint8_t mMilSecCount;           // 毫秒计数
    uint8_t bTenMilSecOk;           // 10毫秒标志位
    uint8_t mTenMilSecCount;        // 10毫秒计数
    uint8_t bHundredMilSecOk;       // 100毫秒标志位
    uint8_t mTimeCount;             // 秒计数
    uint8_t bTimeOk;                // 秒标志位
} stSysTickTimer;
    \end{minted}
\end{frame}

\begin{frame}[fragile]
    相应地，在 \mintinline{C}{SysTick_Handler()} 中也需要在100毫秒标志位时设置相应标志。
    \begin{minted}[firstnumber=192]{C}
  if (++sSysTickTimer.mMilSecCount >= 10) {
    sSysTickTimer.mMilSecCount = 0;
    sSysTickTimer.bTenMilSecOk = 1;
    if (++sSysTickTimer.mTenMilSecCount >= 10) {
      sSysTickTimer.mTenMilSecCount = 0;
      sSysTickTimer.bHundredMilSecOk = 1;
      if (++sSysTickTimer.mTimeCount >= 10) {
        sSysTickTimer.mTimeCount = 0;
        sSysTickTimer.bTimeOk = 1;
      }
    }
  }
    \end{minted}
\end{frame}

\begin{frame}[fragile]
    在 \mintinline{C}{main.c} 中在100毫秒标志为1时进行流水灯的操作（时钟滴答仍然在1秒标志位为1时操作）。
    \begin{minted}[firstnumber=103]{C}
    /* USER CODE BEGIN 3 */
    if (sSysTickTimer.bTimeOk) {
      sSysTickTimer.bTimeOk = 0;
      HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
    }
    if (sSysTickTimer.bHundredMilSecOk) {
      sSysTickTimer.bHundredMilSecOk = 0;
      HAL_GPIO_WritePin(FlashLeds_GPIO_Port, nShift, GPIO_PIN_SET);
      ...
    }
    \end{minted}
\end{frame}

\subsection{实验结果}

\begin{frame}
    每次只有一个灯亮，从最左边的灯亮向右移动，直到最右边的灯亮，再向左移动，直到最左边的灯亮。
    
    \includegraphics[width=0.5\linewidth]{imgs/IMG_20241029_205440.jpg}

    完整视频可以查看：\url{https://gitea.librastalker.top/423A35C7/STM32CubeMX-Keil_uVision5}
\end{frame}

\end{document}