\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] 将实验三的代码复制一份,并将exp3改名为exp4: \vspace{1em} \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} {\Huge$\longrightarrow$} \begin{minipage}[H]{0.3\linewidth} \begin{minted}[linenos=false]{text} exp4 │ .mxproject │ exp4.ioc │ ├─Core │ ├─Drivers │ └─MDK-ARM exp4.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-11-03-20-18-38.png} \end{frame} \begin{frame} 按键: (Key1、Key5、Key9和Key13的四个按键的一个端子与JP15的KL0$\sim $KL3相连。)核心板JP1 的 PB0$\sim$PB3 接 底板JP15 的 KL0$\sim$KL3。将JP16上面两个引脚的跳线帽拔下来插到下面两个引脚(即BTN)。 \includegraphics[width=0.3\linewidth]{imgs/IMG_20241103_194951_1.jpg} \includegraphics[width=0.3\linewidth]{imgs/IMG_20241103_195542_1.jpg} \includegraphics[width=0.3\linewidth]{imgs/IMG_20241103_195612.jpg} \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.23\linewidth]{imgs/IMG_20241103_194712_1.jpg} \includegraphics[width=0.23\linewidth]{imgs/IMG_20241103_194932.jpg} \includegraphics[width=0.23\linewidth]{imgs/IMG_20241103_144021.jpg} \includegraphics[width=0.23\linewidth]{imgs/IMG_20241103_144035.jpg} \end{frame} \subsection{代码修改} \begin{frame}[fragile] 添加DirectKey.h: \begin{multicols}{2} \begin{minted}[firstnumber=1]{C} #ifndef __DIRECTKEY_H #define __DIRECTKEY_H #include enum {State0=0, State1, State2}; #define NoKey 0x0F #define KeyPort GPIOC #ifdef __cplusplus extern "C" { #endif uint8_t ReadDirectKey(void); #ifdef __cplusplus } #endif #endif \end{minted} \end{multicols} \end{frame} \begin{frame}[fragile] 添加DirectKey.c: \begin{multicols}{2} \begin{minted}{C} #include "directkey.h" #include "main.h" uint8_t ReadDirectKey(void) { static uint8_t KeyState = State0; static uint8_t KeyOld; uint8_t KeyPress; uint8_t KeyValue = NoKey; KeyPress = KeyPort->IDR & 0x000F; // 读按键 switch (KeyState) { case State0: if (KeyPress != NoKey) { KeyOld = KeyPress; // 保存原来的键 KeyState = State1; // 切换状态 } break; case State1: if (KeyPress == KeyOld) { KeyState = State2; // KeyValue = KeyOld; // 按下有效 } else { KeyState = State0; } break; case State2: if (KeyPress == NoKey) { KeyState = State0; KeyValue = KeyOld; // 抬起有效 } else { } break; default: break; } return KeyValue; } \end{minted} \end{multicols} \end{frame} \begin{frame}[fragile] stm32g4xx_it.c: \begin{multicols}{2} \begin{minted}[firstnumber=182]{C} /** * @brief This function handles System tick timer. */ void SysTick_Handler(void) { /* USER CODE BEGIN SysTick_IRQn 0 */ /* USER CODE END SysTick_IRQn 0 */ HAL_IncTick(); /* USER CODE BEGIN SysTick_IRQn 1 */ Display(); if (++sSysTickTimer.mMilSecCount >= 10) { sSysTickTimer.mMilSecCount = 0; sSysTickTimer.bTenMilSecOk = 1; if (++sSysTickTimer.mTimeCount >= 100) { sSysTickTimer.mTimeCount = 0; sSysTickTimer.bTimeOk = 1; } } /* USER CODE END SysTick_IRQn 1 */ } \end{minted} \end{multicols} \end{frame} \begin{frame}[fragile] main.c: \begin{multicols}{2} \begin{minted}[firstnumber=24]{C} /* USER CODE BEGIN Includes */ #include "variable.h" #include "directkey.h" /* USER CODE END Includes */ \end{minted} \vspace{1em} \begin{minted}[firstnumber=46]{C} /* USER CODE BEGIN PV */ stSysTickTimer sSysTickTimer = { 0, 0, 0, 0 }; uint8_t tempValue; uint16_t display_tab[] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71 }; uint8_t DispBuff[8]; 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=79]{C} /* Private user code ----------------------------*/ /* USER CODE BEGIN 0 */ void DisplayOneLed(uint8_t dat, uint8_t pos, uint8_t dot) { uint16_t temp; temp = display_tab[dat]; if (dot) temp |= 0x80; GPIOA->ODR &= 0xFF00; GPIOA->ODR |= temp; // 数据段 GPIOB->ODR &= 0xFFF0; GPIOB->ODR |= pos; // 位选 } void Display(void) { static uint8_t mPos = 0; DisplayOneLed(DispBuff[mPos], mPos, 0); if (++mPos >= 8) mPos = 0; } void TimeToBuff(void) { uint8_t i; uint8_t temp; temp = DispBuff[0]; for (int i = 0; i < 7; i++) { DispBuff[i] = DispBuff[i + 1]; } DispBuff[7] = temp; } void DispToBuff(uint8_t val) { uint8_t i; for (int i = 0; i < 7; i++) { DispBuff[i] = DispBuff[i + 1]; } DispBuff[7] = val; } /* USER CODE END 0 */ \end{minted} \end{multicols} \end{frame} \begin{frame}[fragile] main.c: \begin{multicols}{2} \begin{minted}[firstnumber=119]{C} /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ uint8_t KeyValue = 0; /* USER CODE END 1 */ /* MCU Configuration--------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* 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 &= 0xff01; for (int i = 0; i < 8; i++) { DispBuff[i] = i; } /* 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.bTenMilSecOk) { sSysTickTimer.bTenMilSecOk = 0; KeyValue = ReadDirectKey(); if (KeyValue != NoKey) { switch (KeyValue) { case 0x0E: // K1 tempValue = 1; break; case 0x0D: // K5 tempValue = 2; break; case 0x0B: // K9 tempValue = 3; break; case 0x07: // K13 tempValue = 4; break; default: break; } DispToBuff(tempValue); } } if (sSysTickTimer.bTimeOk) { sSysTickTimer.bTimeOk = 0; // TimeToBuff(); HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); } } /* USER CODE END 3 */ } \end{minted} \end{multicols} \end{frame} \subsection{实验结果} \begin{frame} 数码管初始显示01234567,按下K1、K5、K9、K13并抬起时,数码管左移一位,并在右侧添加1、2、3、4。因此记K1、K5、K9、K13分别为1、2、3、4。例如,逐个按下1433223,数码管显示的数字变化为: $$ 01234567 \to 12345671 \to 23456714 \to \cdots\to 71433223 $$ \includegraphics[width=0.45\linewidth]{imgs/IMG_20241103_162322.jpg} \includegraphics[width=0.45\linewidth]{imgs/IMG_20241103_213225.jpg} 完整视频可以查看:\url{https://gitea.librastalker.top/423A35C7/STM32CubeMX-Keil_uVision5} \end{frame} \end{document}