电路图如图
以下是代码实现部分
通过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);
}
}