\documentclass[全部作业]{subfiles}

\begin{document}

\date{2024年11月3日}
\begin{frame}
    %\maketitle
    \titlepage
\end{frame}

\begin{frame}
	\frametitle{目录}
	\tableofcontents
\end{frame}

\section{第三次实验}

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

    \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}
    {\Huge$\longrightarrow$}
    \begin{minipage}[H]{0.3\linewidth}
        \begin{minted}[linenos=false]{text}
    exp3
    │  .mxproject
    │  exp3.ioc
    │
    ├─Core
    │
    ├─Drivers
    │
    └─MDK-ARM
            exp3.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=0.8\linewidth]{imgs/2024-11-03-13-47-47.png}
\end{frame}

\begin{frame}
    将 STM32 核心板 JP1 的 PA0$\sim$PA7 与系统的七段数码管电路的 JP19 相连，PA0$\sim$PA7 分别对应于JP19的D0$\sim$D7，用1x4的杜邦线将STM32核心板的JP2的PB0$\sim$PB3 分别连接到系统底板上JP20的A、B、C和OE接口。

    \includegraphics[width=0.2\linewidth]{imgs/IMG_20241103_194712_1.jpg}
    \includegraphics[width=0.2\linewidth]{imgs/IMG_20241103_194932.jpg}
    \includegraphics[width=0.2\linewidth]{imgs/IMG_20241103_144021.jpg}
    \includegraphics[width=0.2\linewidth]{imgs/IMG_20241103_144035.jpg}
\end{frame}

\subsection{代码修改}
\begin{frame}[fragile]
    main.c:
    \begin{multicols}{2}
        \begin{minted}[firstnumber=45]{C}
/* USER CODE BEGIN PV */
stSysTickTimer sSysTickTimer = {
  0, 0, 0, 0
};
uint16_t display_tab[] = {
  0x3f,
  0x06,
  0x5b,
  0x4f,
  0x66,
  0x6d,
  0x7d,
  0x07,
  0x7f,
  0x6f,
  0x77,
  0x7c,
  0x39,
  0x5e,
  0x79,
  0x71
};
uint16_t PosSel = 0;
/* USER CODE END PV */
        \end{minted}
    \end{multicols}
\end{frame}

\begin{frame}[fragile]
    main.c:
    \begin{multicols}{2}
        \begin{minted}[firstnumber=117]{C}
  /* 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);
    }
    // if (sSysTickTimer.bTenMilSecOk) {
      SegLedData_GPIO_Port->ODR = 0x00;
      AddrA_GPIO_Port->ODR = PosSel;
      SegLedData_GPIO_Port->ODR = display_tab[PosSel % 8];
      if (++PosSel >= 8) {
        PosSel = 0;
      }
    // }
  }
  /* USER CODE END 3 */
        \end{minted}
    \end{multicols}
\end{frame}


\subsection{思考题}
\begin{frame}[fragile]
    我们的需求是将数字一位一位向前推进，那么考虑现在的位选信号（控制哪一位上显示数字）与段选信号（控制显示哪个数字）之间的关系，根据 \mintinline{C}{SegLedData_GPIO_Port->ODR = display_tab[PosSel % 8];} 
    可知
    $$
    \text{段选信号}_0=f(\text{位选信号}_0)
    $$
    而修改后就变成了（时间用$t$表示）
    $$
    \text{段选信号}_{t}=g(\text{位选信号}_{t}, t)
    $$
    因此，只需要加一个随时间变化的变量，例如 $bias = bias(t)$，再把之前的f看做是时间为0时的静止状态，则可以得到
    $$
    \begin{cases}
    \text{段选信号}_0=g(\text{位选信号}_0, 0) = h(\text{位选信号}_0, bias(0)) = f(\text{位选信号}_0) \\
    \text{段选信号}_{t}=g(\text{位选信号}_{t}, t) = h(\text{位选信号}_{t}, bias(t)) \\
    \end{cases}
    $$
    其中的$h$和$bias$就是我们需要构造的函数和变量。
\end{frame}

\begin{frame}[fragile]
    确定$bias(0)$的值：
    \begin{minted}[firstnumber=68]{C}
uint8_t bias = 0;
    \end{minted}

    在bTimeOk时改变$bias$的值，使$bias$随时间变化：
    \begin{minted}[firstnumber=128]{C}
      if (++bias >= 8) {
        bias = 0;
      }
    \end{minted}

    构造$h(\text{段选信号}, bias)$使得$h(\text{段选信号},0)=f(\text{段选信号})$
    \begin{minted}[firstnumber=136]{C}
      SegLedData_GPIO_Port->ODR = display_tab[(PosSel + bias) % 8];
    \end{minted}
\end{frame}

\subsection{实验结果}
\begin{frame}
    初始显示01234567，每过一秒，数字向左循环移位一位，即
    $$
    01234567 \to 12345670 \to 23456701 \to \cdots \to 70123456 \to 01234567
    $$
    \includegraphics[width=0.5\linewidth]{imgs/IMG_20241103_162322.jpg}

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