专业版
#第十届立创电赛#三子棋人机对弈装置

创建时间:2个月前

148 0

视频

描述

<div> <p style="line-height:1.8;">注:* 为必填项</p> <p style="line-height:1.8;"><strong><span style="color:#0093e6;">请在报名阶段填写 ↓</span></strong></p> <p style="line-height:1.8;"> </p> <h3 style="line-height:1.8;">* 1、项目功能介绍</h3> <p>本项目基于STM32F407ZET6最小系统板作为核心控制单元,结合树莓派5构建的高性能视觉处理模块,共同实现了一套实时、精准的智能棋局分析与自动落子系统。在硬件架构上,STM32F407主控模块负责接收视觉系统的分析结果,并精确驱动执行机构完成落子操作,其丰富的外设接口与强大的实时处理能力为系统的稳定运行与快速响应提供了坚实保障。</p> <p>视觉处理部分以树莓派5为平台,充分利用其出色的算力,运行基于OpenCV库优化的图像处理算法。系统通过高分辨率摄像头实时采集1080P&60FPS的棋盘图像,确保了输入数据的高质量与流畅性。在算法层面,首先利用OpenCV的强大功能进行棋盘格角点的精确检测与定位,为后续的坐标映射奠定基础。通过对原始图像进行透视变换,有效校正了因摄像头视角带来的几何畸变,从而建立起从图像像素坐标系到棋盘物理坐标系的精准映射模型。这一模型使得系统能够实时、准确地捕获每一枚棋子的落点坐标,并据此解析出完整的、当前的棋局状态——包括棋子位置、棋盘分区信息以及局势判断。</p> <p>整个系统的工作流程形成了一个高效的闭环:图像采集、视觉处理、数据通信与动作执行环环相扣,无缝衔接。树莓派5在完成复杂的图像识别与局势解析后,通过串口等通信方式,将关键的落子指令及坐标数据快速、可靠地传输至STM32F407主控单元。主控单元随即对这些指令进行解析与规划,并通过对步进电机或舵机等执行元件的精密控制,驱动机械臂或落子装置,在棋盘的指定位置完成精准的落子动作。</p> <p>该设计充分融合了嵌入式控制的实时性、可靠性与计算机视觉的智能识别能力,不仅实现了高达60FPS的流畅视觉处理体验,满足了人机交互对实时性的高标准要求,更展现出了在复杂场景下进行快速、精确分析与操作的强大潜力,为智能棋类机器人、自动化竞技系统等应用提供了一个功能完善、性能卓越的技术实现方案。</p> <p> </p> <p><br><br></p> <p style="line-height:1.8;"> </p> <p style="line-height:1.8;"> </p> <p style="line-height:1.8;"><span style="color:#95a5a6;font-size:14px;">注:主题不限,可以是解决生活/工作中的某个问题、为某个人群/场景设计的方案、毕业设计/课程设计/DIY项目/纯属炫酷项目等。主要讲一下自己通过什么手段解决了什么问题。</span></p> <p style="line-height:1.8;"> </p> <h3 style="line-height:1.8;">*2、项目属性</h3> <p style="line-height:1.8;">无获奖,原创作品</p> <p style="line-height:1.8;">未参加其他竞赛,未答辩</p> <p style="line-height:1.8;"><span style="color:#95a5a6;font-size:14px;">注:请说明项目是否首</span><span style="color:#95a5a6;font-size:14px;">次公开;项目是否为原创;项目是否曾经在其他比赛中获奖,若有获奖则叙述获奖详情;项目是否在学校参加过答辩。</span></p> <p style="line-height:1.8;"> </p> <h3 style="line-height:1.8;">* 3、开源协议</h3> <hr> <p style="line-height:1.8;"><span style="color:#95a5a6;font-size:14px;">GPL3.0</span></p> <p style="line-height:1.8;"> </p> <p style="line-height:1.8;"><span style="color:#95a5a6;font-size:14px;">注:利他即利己,请认真阅读下述内容。</span></p> <ol style="line-height:1.8;"> <li style="line-height:1.8;"><span style="color:#95a5a6;font-size:14px;">拥抱开源,赋予项目无限价值。建议项目核心功能开源80%以上;</span></li> <li style="line-height:1.8;"><span style="color:#95a5a6;font-size:14px;">2、若某一部分功能不可替代且删掉之后项目无法解决对应的问题,则这一部分实现的功能就是项目的核心功能;比如设计了一台电子负载且设计了一款上位机软件监控功率变化,则电子负载为核心功能,上位机软件为辅助功能;比如电子负载中使用了一款隔离485模块与上位机通信,则此485模块实现的通讯功能为辅助功能; </span></li> <li style="line-height:1.8;"><span style="color:#95a5a6;font-size:14px;">项目应选择适合自己的<span style="text-decoration:underline;"><a href="/posts/98fdb2accd754af7b51990790db3b47a" target="_blank">开源协议</a></span>,若项目引用其他开源项目,应注明来源并遵循原作者的开源协议规定;原创项目推荐使用GPL3.0开源协议;</span></li> <li style="line-height:1.8;"><span style="color:#95a5a6;font-size:14px;">直接引用开源项目的原电路或原代码实现的功能不可作为自己项目的核心功能、使用市场上通用模块直接实现的功能不可作为自己项目的核心功能。</span></li> </ol> <p style="line-height:1.8;"> </p> <p style="line-height:1.8;"><strong><span style="color:#0093e6;">请在竞赛阶段填写 ↓</span></strong></p> <p style="line-height:1.8;"> </p> <h3 style="line-height:1.8;">*4、硬件部分</h3> <hr> <p style="line-height:1.8;"><img src="//image.lceda.cn/pullimage/RPTuNivWmUxLUUc205bpKvH3yAFj09rNd0mcq2gS.png" alt="" width="1115" height="786"><img src="//image.lceda.cn/pullimage/H5MfQWZ2bvu3XU3RP2q3dgFF8GvbgThr5DsMTyEh.png" alt="" width="1107" height="776"></p> <p>本项目的主控PCB作为系统的“神经中枢”,其设计直接决定了整机的稳定性、抗干扰能力及信号完整性。我们遵循工业级设计标准,进行了如下精细化设计:</p> <p><strong>1. 层级架构与核心器件布局:</strong></p> <ul> <li> <p><strong>采用4层板结构</strong>:经典的“信号-地层-电源层-信号”叠层设计。该结构为高速数字电路和模拟电路提供了完整的地平面和电源平面,有效降低了电磁辐射(EMI)并提升了信号质量。</p> </li> <li> <p><strong>核心单元隔离布局</strong>:</p> <ul> <li> <p><strong>STM32F407最小系统</strong>:作为主控核心,其晶振、退耦电容等关键无源器件紧贴MCU引脚放置,缩短回流路径,确保时钟源稳定可靠。</p> </li> <li> <p><strong>电机驱动功率区</strong>:将步进/舵机的驱动芯片(如TMC2209等)集中放置在PCB边缘,并远离模拟和高速数字区域,通过物理隔离避免大电流开关噪声对敏感电路的干扰。</p> </li> <li> <p><strong>树莓派对接接口</strong>:使用高密度、防反插的板对板连接器或排针,将其固定在PCB一侧,与主控MCU保持合理距离,便于模块化装配与维护。</p> </li> </ul> </li> </ul> <ul> <li> <p> </p> </li> </ul> <p style="line-height:1.8;"><span style="color:#95a5a6;font-size:14px;"> 注:请前往<span style="text-decoration:underline;"><a href="https://lceda.cn/editor" target="_blank">嘉立创EDA</a> </span>生成/上传设计文件,文件完成后,相关文稿将自动生成至项目详情;这里可以详细说明您的项目实现原理和机制、注意事项、调试方法、测试方法等。推荐图文并茂的形式向别人介绍您的想法。 </span></p> <p style="line-height:1.8;"> </p> <h3 style="line-height:1.8;">*5、软件部分</h3> <hr> <div>/* USER CODE BEGIN Header */</div> <div>/**</div> <div>  ******************************************************************************</div> <div>  * @file           : main.c</div> <div>  * @brief          : Main program body</div> <div>  ******************************************************************************</div> <div>  * @attention</div> <div>  *</div> <div>  * Copyright (c) 2025 STMicroelectronics.</div> <div>  * All rights reserved.</div> <div>  *</div> <div>  * This software is licensed under terms that can be found in the LICENSE file</div> <div>  * in the root directory of this software component.</div> <div>  * If no LICENSE file comes with this software, it is provided AS-IS.</div> <div>  *</div> <div>  ******************************************************************************</div> <div>  */</div> <div>/* USER CODE END Header */</div> <div>/* Includes ------------------------------------------------------------------*/</div> <div>#include "main.h"</div> <div>#include "tim.h"</div> <div>#include "usart.h"</div> <div>#include "gpio.h"</div> <div> </div> <div>/* Private includes ----------------------------------------------------------*/</div> <div>/* USER CODE BEGIN Includes */</div> <div> </div> <div>#include "key.h"</div> <div>#include "StepMotor.h"</div> <div>#include "stdio.h"</div> <div>#include "OLED.h"</div> <div>#include "OLED_Data.h"</div> <div>#include "delay_us.h"</div> <div> </div> <div> </div> <div>/* USER CODE END Includes */</div> <div> </div> <div>/* Private typedef -----------------------------------------------------------*/</div> <div>/* USER CODE BEGIN PTD */</div> <div> </div> <div>/* USER CODE END PTD */</div> <div> </div> <div>/* Private define ------------------------------------------------------------*/</div> <div>/* USER CODE BEGIN PD */</div> <div> </div> <div>/* USER CODE END PD */</div> <div> </div> <div>/* Private macro -------------------------------------------------------------*/</div> <div>/* USER CODE BEGIN PM */</div> <div> </div> <div>/* USER CODE END PM */</div> <div> </div> <div>/* Private variables ---------------------------------------------------------*/</div> <div> </div> <div>/* USER CODE BEGIN PV */</div> <div>int a;</div> <div>extern int Uart_Receive;//串口接收完成标志,需声明</div> <div> </div> <div>uint8_t rx_buffer[9];       // 接收9字节数据</div> <div>uint8_t byte_index = 0;     // 当前接收到的字节索引</div> <div>uint8_t rx_byte;            // 单字节接收缓冲</div> <div>uint8_t data_ready_flag = 0;  // 表示接收完成</div> <div>volatile uint8_t txComplete = 1;  // 初始化为1表示可发送</div> <div> </div> <div>uint8_t display_buf[20];</div> <div>extern TIM_HandleTypeDef htim3;//OC通道 </div> <div>extern UART_HandleTypeDef huart2;</div> <div> </div> <div>uint8_t loge=0;</div> <div>uint8_t i;</div> <div>uint8_t A2=0;</div> <div>uint8_t cishu=0;</div> <div>uint8_t xunhuan8=0;</div> <div>unsigned int qi[4][2]={{0,0},</div> <div>   {0,0},</div> <div>   {0,0},</div> <div>   {0,0}};</div> <div>uint8_t n,f,h;</div> <div>   </div> <div>//extern UART_HandleTypeDef huart2;//串口接收中断</div> <div> </div> <div> </div> <div>/* USER CODE END PV */</div> <div> </div> <div>/* Private function prototypes -----------------------------------------------*/</div> <div>void SystemClock_Config(void);</div> <div>void san(void);</div> <div>/* USER CODE BEGIN PFP */</div> <div> </div> <div>/* USER CODE END PFP */</div> <div> </div> <div>/* Private user code ---------------------------------------------------------*/</div> <div>/* USER CODE BEGIN 0 */</div> <div> </div> <div>void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)</div> <div>{</div> <div>data_ready_flag=0;</div> <div>    if (huart->Instance == USART2)  // 串口2接收中断</div> <div>    {</div> <div>        rx_buffer[byte_index++] = rx_byte;</div> <div> </div> <div>        if (byte_index >= 9)</div> <div>        {</div> <div>            byte_index = 0;</div> <div>            data_ready_flag = 1;  // 标记接收完成</div> <div>        }</div> <div> </div> <div>        // 继续接收下一字节</div> <div>        HAL_UART_Receive_IT(&huart2, &rx_byte, 1);</div> <div>    }</div> <div>}</div> <div> </div> <div>//void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)</div> <div>//{</div> <div>// if (huart->Instance == USART2)  </div> <div>// {</div> <div>// txComplete = 1;  // 设置发送完成标志</div> <div>// }</div> <div>//</div> <div>//}</div> <div> </div> <div>//void send_byte(void)</div> <div>//{</div> <div>// HAL_UART_Transmit_IT(&huart2,&data,1);  // 发送一个字节</div> <div>//   </div> <div>//}</div> <div> </div> <div>#define PLAYER 1  // 白棋</div> <div>#define AI     2  // 黑棋</div> <div>#define EMPTY  0  // 空位</div> <div> </div> <div>uint8_t flag=0;</div> <div> </div> <div>int row,col,pos;</div> <div> </div> <div>int is_winning_move(int board[3][3], int row, int col, int symbol) {</div> <div>    board[row][col] = symbol;</div> <div>    int win =</div> <div>        (board[row][0] == symbol && board[row][1] == symbol && board[row][2] == symbol) ||</div> <div>        (board[0][col] == symbol && board[1][col] == symbol && board[2][col] == symbol) ||</div> <div>        (row == col && board[0][0] == symbol && board[1][1] == symbol && board[2][2] == symbol) ||</div> <div>        (row + col == 2 && board[0][2] == symbol && board[1][1] == symbol && board[2][0] == symbol);</div> <div>    board[row][col] = EMPTY;</div> <div>    return win;</div> <div>}</div> <div> </div> <div>int best_move(int board[3][3], int *best_row, int *best_col) {</div> <div>    // 1. AI可以赢就走</div> <div>    for (int i = 0; i <div>    for (int j = 0; j <div>        if (board[i][j] == EMPTY && is_winning_move(board, i, j, AI)) {</div> <div>            *best_row = i;</div> <div>            *best_col = j;</div> <div>            return 1;</div> <div>        }</div> <div> </div> <div>    // 2. 阻止玩家赢</div> <div>    for (int i = 0; i <div>    for (int j = 0; j <div>        if (board[i][j] == EMPTY && is_winning_move(board, i, j, PLAYER)) {</div> <div>            *best_row = i;</div> <div>            *best_col = j;</div> <div>            return 1;</div> <div>        }</div> <div> </div> <div>    // 3. 中间</div> <div>    if (board[1][1] == EMPTY) {</div> <div>        *best_row = 1;</div> <div>        *best_col = 1;</div> <div>        return 1;</div> <div>    }</div> <div> </div> <div>    // 4. 角落</div> <div>    int corners[4][2] = {{0,0}, {0,2}, {2,0}, {2,2}};</div> <div>    for (int i = 0; i <div>        int r = corners[i][0], c = corners[i][1];</div> <div>        if (board[r][c] == EMPTY) {</div> <div>            *best_row = r;</div> <div>            *best_col = c;</div> <div>            return 1;</div> <div>        }</div> <div>    }</div> <div> </div> <div>    // 5. 边</div> <div>    int edges[4][2] = {{0,1}, {1,0}, {1,2}, {2,1}};</div> <div>    for (int i = 0; i <div>        int r = edges[i][0], c = edges[i][1];</div> <div>        if (board[r][c] == EMPTY) {</div> <div>            *best_row = r;</div> <div>            *best_col = c;</div> <div>            return 1;</div> <div>        }</div> <div>    }</div> <div> </div> <div>    return 0; // 没有可走的位置</div> <div>}</div> <div> </div> <div>// 映射 (row, col) 为编号 1~9(从下到上,从右到左)</div> <div>int get_position_number(int row, int col) {</div> <div>    return (2 - row) * 3 + (2 - col) + 1;</div> <div>}</div> <div> </div> <div> </div> <div>void choice_chess(void);</div> <div> </div> <div> </div> <div> </div> <div>/* USER CODE END 0 */</div> <div> </div> <div>/**</div> <div>  * @brief  The application entry point.</div> <div>  * @retval int</div> <div>  */</div> <div>int main(void)</div> <div>{</div> <div> </div> <div>  /* USER CODE BEGIN 1 */</div> <div> </div> <div>  /* USER CODE END 1 */</div> <div> </div> <div>  /* MCU Configuration--------------------------------------------------------*/</div> <div> </div> <div>  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */</div> <div>  HAL_Init();</div> <div> </div> <div>  /* USER CODE BEGIN Init */</div> <div> </div> <div>  /* USER CODE END Init */</div> <div> </div> <div>  /* Configure the system clock */</div> <div>  SystemClock_Config();</div> <div> </div> <div>  /* USER CODE BEGIN SysInit */</div> <div> </div> <div>  /* USER CODE END SysInit */</div> <div> </div> <div>  /* Initialize all configured peripherals */</div> <div>  MX_GPIO_Init();</div> <div>  MX_TIM2_Init();</div> <div>  MX_TIM3_Init();</div> <div>  MX_USART2_UART_Init();</div> <div>  /* USER CODE BEGIN 2 */</div> <div>Enable_DWT();</div> <div>OLED_Init();</div> <div>OLED_Clear();</div> <div>HAL_TIM_Base_Start_IT(&htim2);</div> <div> </div> <div>// Reset();                             </div> <div>// HAL_TIM_OC_Start_IT(&htim3,TIM_CHANNEL_1);</div> <div>// HAL_TIM_OC_Start_IT(&htim3,TIM_CHANNEL_2);</div> <div>// HAL_TIM_OC_Start_IT(&htim3,TIM_CHANNEL_3);</div> <div> </div> <div>//串口收发初始化</div> <div>// HAL_UART_Transmit_IT(&huart2,&data,1);  // 发送一个字节</div> <div> </div> <div>HAL_UART_Receive_IT(&huart2,&rx_byte,1);//2</div> <div> </div> <div> </div> <div>//   HAL_Delay(100);</div> <div>// direction_x(1); //左</div> <div>// direction_x(0); //右</div> <div>//direction_y(1);//下</div> <div>// direction_y(0); //上</div> <div> </div> <div> </div> <div> </div> <div>// Move_x(44);Move_y(30); //选棋子 1 2</div> <div>//</div> <div>// decline();</div> <div>// HAL_Delay(200);</div> <div>// HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);//继电器吸合</div> <div>// HAL_Delay(500);</div> <div>//rise();</div> <div>//</div> <div>// // Move_x(164);Move_y(33); //选择棋盘 3</div> <div>// Move_x(100);Move_y(66); //4</div> <div> </div> <div>//</div> <div>//decline();</div> <div>// HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);//继电器断开   </div> <div>// HAL_Delay(500);</div> <div>//rise();</div> <div>//</div> <div>// Move_x(0);</div> <div>// Move_y(0);</div> <div> </div> <div>int board[3][3] = {</div> <div>        {0, 0, 0},</div> <div>        {0, 0, 0},</div> <div>        {0, 0, 0}</div> <div>    };</div> <div> </div> <div>   </div> <div>    if (best_move(board, &row, &col)) {</div> <div>        int pos = get_position_number(row, col);</div> <div>        sprintf((void *)display_buf,"AI:%d", pos);</div> <div>OLED_ShowString(0,20,(void *)display_buf,OLED_6X8);</div> <div>OLED_Update();</div> <div> </div> <div>    } else {</div> <div>        //printf("没有可走的位置。\n");</div> <div>    }</div> <div> </div> <div>  /* USER CODE END 2 */</div> <div> </div> <div>  /* Infinite loop */</div> <div>  /* USER CODE BEGIN WHILE */</div> <div> </div> <div>  while (1)</div> <div>{</div> <div> </div> <div>//  OLED_ShowNum (10,10,mode,3,16);</div> <div>//   OLED_ShowString(0,0,"InitOver",8);</div> <div>// sprintf((void *)display_buf,"mode:%d",mode);</div> <div>// OLED_ShowString(0,0,(void *)display_buf,OLED_6X8);</div> <div>//OLED_Update();</div> <div> </div> <div> </div> <div>sprintf((void *)display_buf,"mode:%d  ",mode);</div> <div>OLED_ShowString(0,0,(void *)display_buf,OLED_6X8);</div> <div> </div> <div>  sprintf((void *)display_buf,"ensure:%d  ",ensure);</div> <div>  OLED_ShowString(75,10,(void *)display_buf,OLED_6X8);</div> <div> </div> <div>sprintf((void *)display_buf,"rx_byte:%d  ", rx_byte);</div> <div>OLED_ShowString(0,20,(void *)display_buf,OLED_6X8);</div> <div> </div> <div>OLED_ShowHexNum(0,30,board[2][2],2,OLED_6X8);</div> <div>OLED_ShowHexNum(14,30,board[2][1],2,OLED_6X8);</div> <div>OLED_ShowHexNum(28,30,board[2][0],2,OLED_6X8);</div> <div>OLED_ShowHexNum(42,30,board[1][2],2,OLED_6X8);</div> <div>OLED_ShowHexNum(56,30,board[1][1],2,OLED_6X8);</div> <div>OLED_ShowHexNum(70,30,board[1][0],2,OLED_6X8);</div> <div>OLED_ShowHexNum(84,30,board[0][2],2,OLED_6X8);</div> <div>OLED_ShowHexNum(98,30,board[0][1],2,OLED_6X8);</div> <div>OLED_ShowHexNum(112,30,board[0][0],2,OLED_6X8);</div> <div> </div> <div>OLED_Update();</div> <div>board[0][0]=rx_buffer[8];board[0][1]=rx_buffer[7];board[0][2]=rx_buffer[6];</div> <div>board[1][0]=rx_buffer[5];board[1][1]=rx_buffer[4];board[1][2]=rx_buffer[3];</div> <div>board[2][0]=rx_buffer[2];board[2][1]=rx_buffer[1];board[2][2]=rx_buffer[0];</div> <div> </div> <div>// pos = get_position_number(row, col);</div> <div> </div> <div> </div> <div>// send_byte();//串口发送</div> <div>// HAL_Delay(1000);</div> <div> </div> <div> </div> <div>// if (data_ready_flag)</div> <div>//        {</div> <div>//            data_ready_flag = 0;</div> <div> </div> <div>//            // 在此处理完整接收到的 8 字节数据(rx_buffer[0] ~ rx_buffer[7])</div> <div>//            // 示例:打印或解析命令</div> <div>//        }</div> <div> </div> <div>switch(mode)</div> <div>{</div> <div>case 0:</div> <div>{</div> <div>if(flag!=0){flag=0;}</div> <div> </div> <div>};break ;</div> <div>case 1:</div> <div>{</div> <div>if(flag!=1){flag=1;}</div> <div>//choice_chess();</div> <div>}break ;</div> <div>case 2:</div> <div>{</div> <div>if(flag!=2){flag=2;f=0;}</div> <div>if(flag2==1)</div> <div>{</div> <div>if(best_move(board, &row, &col))</div> <div>pos = get_position_number(row, col);</div> <div>san();</div> <div>flag2=0;</div> <div>}</div> <div>}break ;</div> <div> </div> <div> </div> <div>}</div> <div> </div> <div> </div> <div> </div> <div>}</div> <div>    /* USER CODE END WHILE */</div> <div> </div> <div>    /* USER CODE BEGIN 3 */</div> <div>}</div> <div>  /* USER CODE END 3 */</div> <div> </div> <div> </div> <div>/**</div> <div>  * @brief System Clock Configuration</div> <div>  * @retval None</div> <div>  */</div> <div>void SystemClock_Config(void)</div> <div>{</div> <div>  RCC_OscInitTypeDef RCC_OscInitStruct = {0};</div> <div>  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};</div> <div> </div> <div>  /** Configure the main internal regulator output voltage</div> <div>  */</div> <div>  __HAL_RCC_PWR_CLK_ENABLE();</div> <div>  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);</div> <div> </div> <div>  /** Initializes the RCC Oscillators according to the specified parameters</div> <div>  * in the RCC_OscInitTypeDef structure.</div> <div>  */</div> <div>  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;</div> <div>  RCC_OscInitStruct.HSIState = RCC_HSI_ON;</div> <div>  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;</div> <div>  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;</div> <div>  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;</div> <div>  RCC_OscInitStruct.PLL.PLLM = 8;</div> <div>  RCC_OscInitStruct.PLL.PLLN = 168;</div> <div>  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;</div> <div>  RCC_OscInitStruct.PLL.PLLQ = 4;</div> <div>  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)</div> <div>  {</div> <div>    Error_Handler();</div> <div>  }</div> <div> </div> <div>  /** Initializes the CPU, AHB and APB buses clocks</div> <div>  */</div> <div>  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK</div> <div>                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;</div> <div>  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;</div> <div>  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;</div> <div>  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;</div> <div>  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;</div> <div> </div> <div>  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)</div> <div>  {</div> <div>    Error_Handler();</div> <div>  }</div> <div>}</div> <div> </div> <div>/* USER CODE BEGIN 4 */</div> <div> </div> <div>void choice_chess()</div> <div>{</div> <div>OLED_Update();</div> <div> </div> <div>sprintf((void*)display_buf,"Chess:%d  ",chess);</div> <div>    OLED_ShowString(0,20,(void *)display_buf,OLED_6X8);</div> <div> </div> <div>sprintf((void*)display_buf,"choose_ge:%d  ",choose_ge);</div> <div>    OLED_ShowString(0,10,(void *)display_buf,OLED_6X8);</div> <div> </div> <div>while(A2==0)</div> <div>{</div> <div>OLED_Update();</div> <div>key();</div> <div>sprintf((void*)display_buf,"Chess:%d  ",chess);</div> <div>    OLED_ShowString(0,20,(void *)display_buf,OLED_6X8);</div> <div> </div> <div>sprintf((void*)display_buf,"choose_ge:%d  ",choose_ge);</div> <div>    OLED_ShowString(0,10,(void *)display_buf,OLED_6X8);</div> <div> </div> <div>sprintf((void*)display_buf,"cishu:%d  ",cishu);</div> <div>    OLED_ShowString(0,30,(void *)display_buf,OLED_6X8);</div> <div> </div> <div>sprintf((void*)display_buf,"mode:%d  ",mode);</div> <div>    OLED_ShowString(0,0,(void *)display_buf,OLED_6X8);</div> <div> </div> <div>switch(cishu)</div> <div>{</div> <div>case 0:</div> <div>{</div> <div>if(queren==1){qi[0][0]=chess;cishu++;choose_ge=0;chess=0;queren=0;}</div> <div> </div> <div>}break;</div> <div>case 1:</div> <div>{</div> <div>if(queren==1){qi[0][1]=choose_ge;cishu++;choose_ge=0;chess=0;queren=0;}</div> <div> </div> <div>}break;</div> <div>case 2:</div> <div>{</div> <div>if(queren==1){qi[1][0]=chess;cishu++;choose_ge=0;chess=0;queren=0;}</div> <div>}break;</div> <div>case 3:</div> <div>{</div> <div>if(queren==1){qi[1][1]=choose_ge;cishu++;choose_ge=0;chess=0;queren=0;}</div> <div>}break;</div> <div>case 4:</div> <div>{</div> <div>if(queren==1){qi[2][0]=chess;cishu++;choose_ge=0;chess=0;queren=0;}</div> <div>}break;</div> <div>case 5:</div> <div>{</div> <div>if(queren==1){qi[2][1]=choose_ge;cishu++;choose_ge=0;chess=0;queren=0;}</div> <div>}break;</div> <div>case 6:</div> <div>{</div> <div>if(queren==1){qi[3][0]=chess;cishu++;choose_ge=0;chess=0;queren=0;}</div> <div>}break;</div> <div>case 7:</div> <div>{</div> <div>if(queren==1){qi[3][1]=choose_ge;ensure=1;cishu++;choose_ge=0;chess=0;queren=0;A2=1;}</div> <div>}break;</div> <div>}</div> <div> </div> <div>OLED_ShowNum(67,0,ensure,2,OLED_6X8);</div> <div> </div> <div>    OLED_ShowNum(0,45,qi[0][0],2,OLED_6X8);</div> <div>OLED_ShowNum(0,57,qi[0][1],2,OLED_6X8);</div> <div> </div> <div>OLED_ShowNum(28,45,qi[1][0],2,OLED_6X8);</div> <div>OLED_ShowNum(28,57,qi[1][1],2,OLED_6X8);</div> <div> </div> <div>OLED_ShowNum(56,45,qi[2][0],2,OLED_6X8);</div> <div>OLED_ShowNum(56,57,qi[2][1],2,OLED_6X8);</div> <div> </div> <div>OLED_ShowNum(84,45,qi[3][0],2,OLED_6X8);</div> <div>OLED_ShowNum(84,57,qi[3][1],2,OLED_6X8);</div> <div> </div> <div> </div> <div>// if(queren==1){cishu++;choose_ge=0;chess=0;queren=0;}</div> <div>if(cishu>7)cishu=0;</div> <div> </div> <div> </div> <div>}</div> <div>if(ensure==1&&pulse1==0&&pulse2==0&&xunhuan8=1&&qi[0][0]=1&&qi[0][0]=1&&qi[1][0]=1&&qi[1][0]=1&&qi[2][0]=1&&qi[2][0]=1&&qi[3][0]=1&&qi[3][0]=6)f=1;</div> <div>}</div> <div> </div> <div>/* USER CODE END 4 */</div> <div> </div> <div>/**</div> <div>  * @brief  This function is executed in case of error occurrence.</div> <div>  * @retval None</div> <div>  */</div> <div>void Error_Handler(void)</div> <div>{</div> <div>  /* USER CODE BEGIN Error_Handler_Debug */</div> <div>  /* User can add his own implementation to report the HAL error return state */</div> <div>  __disable_irq();</div> <div>  while (1)</div> <div>  {</div> <div>  }</div> <div>  /* USER CODE END Error_Handler_Debug */</div> <div>}</div> <div>利用 STM32F407ZET6 最小系统板通过 DMA+USART 串口空闲中断进行连续不定长接收树莓派 5</div> <div> <div> <div>视觉数据,经算法处理后生成运动控制指令,驱动步进电机,实现 ±0.5mm 精度的棋子定位与落子动作。</div> <div>1.实现从视觉识别、算法决策到机械执行的全流程闭环控制,完成三子棋人机对弈完整功能验证。</div> <div>2.掌握多平台异构通信(STM32 与树莓派)、机器视觉算法移植及机械结构调试技</div> <div>术。</div> </div> <div> </div> <div> </div> <div> </div> <div>  </div> <div> </div> <div> </div> <div> </div> <div> </div> <div> </div> <div> </div> </div> <div> </div> <div> </div> <div> </div> <div> </div> <div> </div> <div> </div> <div> </div> <div> </div> <div> </div> <p style="line-height:1.8;"><span style="color:#95a5a6;font-size:14px;">请输入内容…</span></p> <p style="line-height:1.8;"> </p> <p style="line-height:1.8;"><span style="color:#95a5a6;font-size:14px;">注:若您的项目涉及软件开发,请在附件上传对应的工程源码。这里可以详细说明您的软件流程图、功能模块框图、相关算法的解释或科普、源码结构、编译环境的搭建和配置、源码编译方法、程序烧录方法等。推荐图文并茂的形式向别人介绍您的想法。</span></p> <p style="line-height:1.8;"> </p> <h3 style="line-height:1.8;">*6、BOM清单</h3> <hr> <p style="line-height:1.8;"><span style="color:#95a5a6;font-size:14px;">请输入内容…</span></p> <p style="line-height:1.8;"><img src="//image.lceda.cn/pullimage/ppKgfIuVVfFv3Eav85WBa0r3FHLiUFcz4qnlBnLJ.png" alt="" width="1200" height="907"></p> <p style="line-height:1.8;"><span style="color:#95a5a6;font-size:14px;">注:项目涉及的BOM清单。在<span style="text-decoration:underline;"><a href="https://lceda.cn/editor" target="_blank">嘉立创EDA</a> </span>生成/上传设计文件后,BOM将自动生成至项目详情;建议包括型号、品牌、名称、封装、采购渠道、用途等内容。具体内容和形式应以表达清楚项目构成为准。 </span></p> <p style="line-height:1.8;"> </p> <h3 style="line-height:1.8;">*7、大赛LOGO验证</h3> <hr> <p style="line-height:1.8;"> </p> <p style="line-height:1.8;"><span style="color:#95a5a6;font-size:14px;">请上传<img src="//image.lceda.cn/pullimage/vaAS2wAKk19lJTnok730T5pbMV1NfbNS5rH58zwY.jpeg" alt="" width="1200" height="1200"><br>包含大赛logo的项目图片,logo以丝印形式印刷在PCB上面。</span></p> <p style="line-height:1.8;"><span style="color:#95a5a6;font-size:14px;">点击zip下载大赛logo标识! <span style="text-decoration:underline;"><a href="https://image.lceda.cn/easyedaResource/images/d1bbfd69f9404f56901a0e7b849b7245.rar" target="_blank">(大赛标识).zip</a></span></span></p> <p style="line-height:1.8;"> </p> <h3 style="line-height:1.8;">* 8、演示您的项目并录制成视频上传</h3> <hr> <p style="line-height:1.8;">如上图所示</p> <p style="line-height:1.8;"><span style="color:#95a5a6;font-size:14px;">视频要求:请横屏拍摄,分辨率不低于1280×720,格式Mp4/Mov,单个视频大小限100M内;</span></p> <p style="line-height:1.8;"><span style="color:#95a5a6;font-size:14px;">视频标题:立创电赛:{项目名称}-{视频模块名称};如立创电赛:《自动驾驶》-团队介绍。</span></p> <p style="line-height:1.8;"> </p> <p style="line-height:1.8;"><span style="font-size:14px;"><a href="/posts/42551e8f2f2548cabc1c36626a42da94" target="_blank">前往查看更多详情 ></a></span></p> <p style="line-height:1.8;"> </p> </div> </div> </div> </div> </div> </div> </div>

文档

BOM

暂无

附件

附件名 下载
2024_Sanziqi.7z

评论(2)

  • 表情
    emoji
    小嘉工作篇
    小嘉日常篇
  • 图片
成功
工程所有者当前已关闭评论
立创电赛 回复
<p>logo验证需要上传实物图哦</p>
立创电赛 回复
<p>工程未公开<img src="//image.lceda.cn/pullimage/w64qFRXczV7QudCD0051nb2c77LHRfTlEcdSDP3h.webp" alt="图片" /></p>
goToTop
svg-battery svg-battery-wifi svg-books svg-more svg-paste svg-pencil svg-plant svg-ruler svg-share svg-user svg-logo-cn svg-double-arrow