STM32CubeMX(STM32F103R6)+Proteus8.13实现汉诺塔(HAL库实现)

电路图如图

以下是代码实现部分

通过pan数组控制pan本身的各个特征,在通过函数显示在显示屏上,按钮都使用中断模式

int hannuolength[5]={36,30,24,18,10};//盘子的长度,不变
int hannuoheight[5]={60,50,40,30,20};//盘子显示出来的高度,随着移动而变化
int hannuoqishi[3]={0,43,85};//显示盘子的起始位置,对应A/B/C
int numhannuo[3]={5,0,0};//A/B/C上有几个盘子
int hannuo[3][5]={{1,1,1,1,1},{0,0,0,0,0},{0,0,0,0,0}};//A/B/C柱子的12345盘的情况,在A柱则盘子对应的下标就对应为1
int pan[][4]={{0,0,0,4},{0,1,1,3},{0,2,2,2},{0,3,3,1},{0,4,4,0}};//第几个盘,length数,高度,第*大盘子
int KeepMid[5]={0,3,6,9,13};//起始位置的偏移值,让盘子显示居中
/* USER CODE END PTD */
//盘的排名,第几个柱子
//如果此时柱子数组中盘子排名前没有其余盘子,则1,否则0
int HasBigger(int pannum,int zhunum)
{
	for(int i = 4; i >= 0; i--)
	{
		if(hannuo[zhunum-1][i] == 1 && i > pannum)
		{
			HAL_GPIO_WritePin(GPIOA,GPIO_PIN_9,1);
			return 0;
		}	
		
	}
	return 1;
}
//显示隔断

void ShowAnime()
{
	OLED_DrawLine(42,0,42,60,1);
	OLED_DrawLine(84,0,84,60,1);
	OLED_Refresh();
}
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
//显示五个盘子

void showPan()
{
	for(int i=0;i<5;i++)
		for(int j=0;j<10;j++)
	{
		OLED_DrawLine(hannuoqishi[pan[i][0]]+KeepMid[i],hannuoheight[pan[i][2]]-j,hannuoqishi[pan[i][0]]+hannuolength[i]+KeepMid[i],hannuoheight[pan[i][2]]-j,1);
	}

	OLED_Refresh();
}
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @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 */

  /* 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 */
	OLED_Init();
	 // 以上为初始化
  /* USER CODE END 2 */
	ShowAnime();//画线
	showPan();//显示盘子
	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,0);
	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,0);
	//三个灯初始化
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
		/*HAL_Delay(500);
		OLED_Clear();
		OLED_ShowString(10,0,"hello world",16,1);*/
		//OLED_DrawLine(
		//OLED_Qingchu(0,1);
		
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

int bushu=0;
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)//外部中断回调函数
	//PC0收到外部中断的时候,执行本函数
{
	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_9,0);
	if(GPIO_Pin==GPIO_PIN_1)//AC
	{
		int i=0,j=0;
		for(i =4;hannuo[0][i]!=1&&i>=0;i--)//寻找当前柱子上最小的盘子
		{
		}
		if(numhannuo[2]==0 || HasBigger(i,3))
		{
		hannuo[0][i]=0;
		hannuo[2][i]=1;//盘子被放在了第三根柱子上
		numhannuo[0]--;
		numhannuo[2]++;//每个柱子盘子统计
		pan[i][0]=2;
		pan[i][2]=numhannuo[2]-1;
		bushu++;
		}
	}
	if(GPIO_Pin==GPIO_PIN_2)//AB
	{
		int i =0,j=0;
		for(i =4;hannuo[0][i]!=1&&i>=0;i--)
		{
		}
		if(numhannuo[1]==0 || HasBigger(i,2))
		{
		hannuo[0][i]=0;
		hannuo[1][i]=1;
		numhannuo[0]--;
		numhannuo[1]++;
		pan[i][0]=1;
		pan[i][2]=numhannuo[1]-1;
		bushu++;
		}
	}
	if(GPIO_Pin==GPIO_PIN_3)//BC
	{
		int i =0,j=0;
		for(i =4;hannuo[1][i]!=1&&i>=0;i--)
		{
		}
		if(numhannuo[2]==0 || HasBigger(i,3))
		{
		hannuo[1][i]=0;
		hannuo[2][i]=1;
		numhannuo[1]--;
		numhannuo[2]++;
		pan[i][0]=2;
		pan[i][2]=numhannuo[2]-1;
		bushu++;
		}
	}
	if(GPIO_Pin==GPIO_PIN_4)//BA
	{
		int i =0,j=0;
		for(i =4;hannuo[1][i]!=1&&i>=0;i--)
		{
		}
		if(numhannuo[0]==0 || HasBigger(i,1))
		{
		hannuo[1][i]=0;
		hannuo[0][i]=1;
		numhannuo[1]--;
		numhannuo[0]++;
		pan[i][0]=0;
		pan[i][2]=numhannuo[0]-1;
		bushu++;
		}
	}
	if(GPIO_Pin==GPIO_PIN_5)//CA
	{
		int i =0,j=0;
		for(i =4;hannuo[2][i]!=1&&i>=0;i--)
		{
		}
		if(numhannuo[0]==0 || HasBigger(i,1))
		{
		hannuo[2][i]=0;
		hannuo[0][i]=1;
		numhannuo[2]--;
		numhannuo[0]++;
		pan[i][0]=0;
		pan[i][2]=numhannuo[0]-1;
		bushu++;
		}
	}
	if(GPIO_Pin==GPIO_PIN_6)//CB
	{
		int i =0,j=0;
		for(i =4;hannuo[2][i]!=1&&i>=0;i--)
		{
		}
		if(numhannuo[2]==0 || HasBigger(i,2))
		{
		hannuo[2][i]=0;
		hannuo[1][i]=1;
		numhannuo[2]--;
		numhannuo[1]++;
		pan[i][0]=1;
		pan[i][2]=numhannuo[1]-1;
		bushu++;
		}
	}
	OLED_Clear();
	ShowAnime();
	showPan();
	
	if(bushu%2==0)
	{
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,0);
	}
	else
	{
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,1);
	}
	if(numhannuo[2]==5)
	{
		OLED_Clear();
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,1);
		OLED_ShowString(64,32,(uint8_t *)"Game Over!",8,1);
	}
}

  • 11
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值