📄 main._c
字号:
#include <iom16v.h>
#include <MACROS.h>
#include "Define.h"
#include "5110.h"
//=======================================================================
//=======================================================================
//按键I/O口定义
#define key_ddr DDRA
#define key_port PORTA
#define key_pin PINA
//=======================================================================
//按键键值定义
#define all_key 0xF8
#define Up 0x78 //7
#define Right 0xB8 //6
#define Enter 0xD8 //5
#define Left 0xE8 //4
#define Down 0xF0 //3
extern const uint8 font6x8[][6]; //LCD字符显示码表声明
uint8 key_state; //按键状态
uint8 key_value; //按键返回值
uint8 key_last_value; //上次按键返回值
uint8 key_one; //处理按键后是否完成一次显示
uint8 X; //鼠标X轴
uint8 Y; //鼠标Y轴
uint16 NUM_BEST; //最好步数
uint16 NUM_YOUR; //走的步数
uint8 guanshu; //第几局
uint8 disp_buffer[5][4]; //显示缓存区
uint8 disp1_buffer[5][4]={ //第一局开局棋子布局
{0x11,0x41,0x41,0x13},
{0x12,0x41,0x41,0x14},
{0x21,0x31,0x31,0x24},
{0x21,0x22,0x23,0x24},
{0x00,0x22,0x23,0x00},
};
uint8 disp2_buffer[5][4]={ //第二局开局棋子布局
{0x11,0x41,0x41,0x13},
{0x12,0x41,0x41,0x14},
{0x31,0x31,0x32,0x32},
{0x33,0x33,0x34,0x34},
{0x00,0x35,0x35,0x00},
};
//=======================================================================
//延时函数
void Delay_us(uint16 time)
{while (time--)
_WDR();
}
void Delay_ms(uint16 time)
{while (time--)
Delay_us(1200);
}
//=======================================================================
//主函数
void main(void)
{
uint8 i,j;
guanshu=1;
NUM_BEST=100;
SETBIT(DDRC,BACKLED_EN); //配置背光控制端口
CLEARBIT(PORTC,BACKLED_EN); //使能背光
LCD_init(); //初始化LCD模块
while(1) //总循环
{
LCD_clear(); //清屏
//显示数据界面
LCD_write_String(34,0,8,"YOUR:000",0);
LCD_write_String(34,1,8,"BEST:000",0);
LCD_write_String(34,3,8,"GUAN:001",0);
NUMdisp_task(NUM_BEST,1); //显示最好成绩
NUMdisp_task(guanshu,3); //显示第几关
//一切变量都重新初始化
key_init();
key_state=0;
key_value=0;
key_last_value=0;
key_one=1;
X=0;
Y=0;
NUM_YOUR=0;
SEI(); //全局中断使能
while(1) //选关
{
if(key_value==Down)
{
key_value=0;
guanshu++;
if(guanshu==3)
guanshu=1;
NUMdisp_task(guanshu,3);
}
if(key_value==Enter) //按确定选关完成
{
key_value=0;
break;
}
}
//将选择的局载入显示缓存区
if(guanshu==1)
{
for(i=0;i<5;i++)
for(j=0;j<4;j++)
{
disp_buffer[i][j]=disp1_buffer[i][j];
}
}
else
{
for(i=0;i<5;i++)
for(j=0;j<4;j++)
{
disp_buffer[i][j]=disp2_buffer[i][j];
}
}
//开始闯关
for(;;)
{
//显示鼠标
LCD_set_XY(Y*8+3,X);//设置初始位置
LCD_write_byte(0x3c,1);
LCD_write_byte(0x3c,1);
KBOD_task(); //按键操作处理
if(key_value!=0)
{
key_last_value=key_value; //将上次的键值存起来
key_value=0; //将当前键值清零
key_one=1; //将显示打开
}
if(key_one==1)
{
DISP_task(); //显示图形界面
key_one=0; //将显示关闭
}
//判断通关与否
if((disp_buffer[4][1]==0x41)&(disp_buffer[4][2]==0x41)) //通过
{
LCD_clear(); //清屏
LCD_write_String(0,5,15,"Congratulation!",0); //祝贺
LCD_write_String(0,4,5,"Wait!",0); //等待
Delay_ms(10000); //延时
guanshu++; //关数加1
if(guanshu==3) //达到最高关数就返回第一关
guanshu=1;
if(NUM_BEST>NUM_YOUR) //存储最好成绩
NUM_BEST=NUM_YOUR;
break; //跳出此关,进行下一关
}
}
}
}
//=======================================================================
//键盘初始化(采用定时扫描)
void key_init(void)
{
key_ddr&=~all_key;
key_port|=all_key;
//t/c0初始化
TCCR0=0X0D;
TCNT0=0X00;
OCR0=0XF0; //定时30ms
TIMSK|=0X02;
}
//=======================================================================
//扫描程序(带去抖功能)
void read_keyboard(void)
{
switch(key_state)
{
case 0:
if((key_pin&all_key)!=all_key)
key_state++;
break;
case 1:
if((key_pin&all_key)!=all_key)
{
key_state++;
key_value=key_pin&all_key;
}
else key_state--;
break;
case 2:
if((key_pin&all_key)==all_key)
{key_state=0;
}
break;
}
}
//=======================================================================
//定时中断,进行键盘扫描
#pragma interrupt_handler timer0comp:20
void timer0comp (void)
{
read_keyboard();
}
//=======================================================================
//键盘键值处理(有键被按下以后进行的处理)
void KBOD_task(void)
{
if(key_value!=0)
{
switch(key_value)
{
case Up: //向上键被按下
if(key_last_value!=Enter) //判断是走局还是移动鼠标
{
if(X>0)X--; //鼠标向上移动
}
else //走局操作
{
if((disp_buffer[X][Y]&0xF0)==0x00)return;//如果移动的是空白,则跳出
else if((disp_buffer[X][Y]&0xF0)==0x10) //如果移动的是兵
{
if(X>0)
if(disp_buffer[X-1][Y]==0x00)
{
X--;
disp_buffer[X][Y]=disp_buffer[X+1][Y];
disp_buffer[X+1][Y]=0x00;
NUM_YOUR++;
}
}
else if((disp_buffer[X][Y]&0xF0)==0x20) //如果移动的是竖将
{
if(X>0)
if(disp_buffer[X][Y]==disp_buffer[X-1][Y])
X--;
if(X>0)
if(disp_buffer[X-1][Y]==0x00)
{
X--;
disp_buffer[X][Y]=disp_buffer[X+2][Y];
disp_buffer[X+2][Y]=0x00;
NUM_YOUR++;
}
}
else if((disp_buffer[X][Y]&0xF0)==0x30) //如果移动的是横将
{
if(Y>0)
if(disp_buffer[X][Y]==disp_buffer[X][Y-1])
Y--;
if(X>0)
if((disp_buffer[X-1][Y]==0x00)&(disp_buffer[X-1][Y+1]==0x00))
{
X--;
disp_buffer[X][Y]=disp_buffer[X+1][Y];
disp_buffer[X][Y+1]=disp_buffer[X+1][Y+1];
disp_buffer[X+1][Y]=0x00;
disp_buffer[X+1][Y+1]=0x00;
NUM_YOUR++;
}
}
else if((disp_buffer[X][Y]&0xF0)==0x40)//如果移动的是曹操
{
if(X>0)
if(disp_buffer[X][Y]==disp_buffer[X-1][Y])
X--;
if(Y>0)
if(disp_buffer[X][Y]==disp_buffer[X][Y-1])
Y--;
if(X>0)
if((disp_buffer[X-1][Y]==0x00)&(disp_buffer[X-1][Y+1]==0x00))
{
X--;
disp_buffer[X][Y]=disp_buffer[X+2][Y];
disp_buffer[X][Y+1]=disp_buffer[X+2][Y+1];
disp_buffer[X+2][Y]=0x00;
disp_buffer[X+2][Y+1]=0x00;
NUM_YOUR++;
}
}
}
break;
case Right: //向右键被按下
if(key_last_value!=Enter) //判断是走局还是移动鼠标
{
if(Y<3)Y++;
}
else //走局操作
{
if((disp_buffer[X][Y]&0xF0)==0x00)return;
else if((disp_buffer[X][Y]&0xF0)==0x10)//如果移动的是兵
{
if(Y<3)
if(disp_buffer[X][Y+1]==0x00)
{
Y++;
disp_buffer[X][Y]=disp_buffer[X][Y-1];
disp_buffer[X][Y-1]=0x00;
NUM_YOUR++;
}
}
else if((disp_buffer[X][Y]&0xF0)==0x20)//如果移动的是竖将
{
if(X>0)
if(disp_buffer[X][Y]==disp_buffer[X-1][Y])
X--;
if(Y<3)
if((disp_buffer[X][Y+1]==0x00)&(disp_buffer[X+1][Y+1]==0x00))
{
Y++;
disp_buffer[X][Y]=disp_buffer[X][Y-1];
disp_buffer[X+1][Y]=disp_buffer[X+1][Y-1];
disp_buffer[X][Y-1]=0x00;
disp_buffer[X+1][Y-1]=0x00;
NUM_YOUR++;
}
}
else if((disp_buffer[X][Y]&0xF0)==0x30)//如果移动的是横将
{
if(Y>0)
if(disp_buffer[X][Y]==disp_buffer[X][Y-1])
Y--;
if(Y<2)
if(disp_buffer[X][Y+2]==0x00)
{
Y++;
disp_buffer[X][Y+1]=disp_buffer[X][Y-1];
disp_buffer[X][Y-1]=0x00;
NUM_YOUR++;
}
}
else if((disp_buffer[X][Y]&0xF0)==0x40)//如果移动的是曹操
{
if(X>0)
if(disp_buffer[X][Y]==disp_buffer[X-1][Y])
X--;
if(Y>0)
if(disp_buffer[X][Y]==disp_buffer[X][Y-1])
Y--;
if(Y<2)
if((disp_buffer[X][Y+2]==0x00)&(disp_buffer[X+1][Y+2]==0x00))
{
Y++;
disp_buffer[X][Y+1]=disp_buffer[X][Y-1];
disp_buffer[X+1][Y+1]=disp_buffer[X+1][Y-1];
disp_buffer[X][Y-1]=0x00;
disp_buffer[X+1][Y-1]=0x00;
NUM_YOUR++;
}
}
}
break;
case Enter: //确定键被按下
break;
case Left: //向左键被按下
if(key_last_value!=Enter) //判断是走局还是移动鼠标
{
if(Y>0)Y--;
}
else //走局操作
{
if((disp_buffer[X][Y]&0xF0)==0x00)return;
else if((disp_buffer[X][Y]&0xF0)==0x10)//如果移动的是兵
{
if(Y>0)
if(disp_buffer[X][Y-1]==0x00)
{
Y--;
disp_buffer[X][Y]=disp_buffer[X][Y+1];
disp_buffer[X][Y+1]=0x00;
NUM_YOUR++;
}
}
else if((disp_buffer[X][Y]&0xF0)==0x20)//如果移动的是竖将
{
if(X>0)
if(disp_buffer[X][Y]==disp_buffer[X-1][Y])
X--;
if(Y>0)
if((disp_buffer[X][Y-1]==0x00)&(disp_buffer[X+1][Y-1]==0x00))
{
Y--;
disp_buffer[X][Y]=disp_buffer[X][Y+1];
disp_buffer[X+1][Y]=disp_buffer[X+1][Y+1];
disp_buffer[X][Y+1]=0x00;
disp_buffer[X+1][Y+1]=0x00;
NUM_YOUR++;
}
}
else if((disp_buffer[X][Y]&0xF0)==0x30)//如果移动的是横将
{
if(Y>0)
if(disp_buffer[X][Y]==disp_buffer[X][Y-1])
Y--;
if(Y>0)
if(disp_buffer[X][Y-1]==0x00)
{
Y--;
disp_buffer[X][Y]=disp_buffer[X][Y+2];
disp_buffer[X][Y+2]=0x00;
NUM_YOUR++;
}
}
else if((disp_buffer[X][Y]&0xF0)==0x40)//如果移动的是曹操
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -