毕业设计| STM32+UART HMI,玩扫雷游戏
-
每年毕设,STM32出现的频率最高,很多都是“老实本分”的设计,但也有不走寻常路,比如今天分享的这个毕设——扫雷游戏。不知道这位同学在毕业答辩时,有没有被老师为难,当着这么多评委老师,来几盘扫雷,是不是很刺激
先上2张游戏中照片:
系统的硬件:指南者开发板和4.2英寸的UATRT HMI串口屏组成,其实可以用最小的核心板,单片机外设也就用到了串口而已,但是要求使用开发板,只好有点浪费了。
软件部分:软件部分是这个项目的核心。
刚开始参考了网上一些扫雷代码。在单片机上很多地方不一样,但大体思路还是一样的,主要解决的就是与串口屏之间的通信协议,贴一段简单的通信代码。
具体完成功能:
1.扫雷基本功能
2.当周围的雷都标记完时,打开剩余未标记的格子
//串口接收中断
void USART1_IRQHandler(void)
{
if(huart1.Instance->SR&(1<<5))//如果接收到了数据
{
buf=huart1.Instance->DR;
/接收选择的格子串口通信协议
if(id_flag==1)
{
if(buf==0xff)
{
id_flag=0;
count=0;
select_id=buff[0];
select_flag=1;
}
else
{
buff[count++]=buf;
}
}
if(buf==0xaa)
{
id_flag=1;
}
}
/接收选择的格子串口通信协议
/打开一个安全格子串口通信协议
if(buf==0xbb)
{
safe_flag=1;
}
/打开一个安全格子串口通信协议
/重新开始串口通信协议
if(buf==0xcc)
{
refreshall_flag=1;
}
/重新开始安全格子串口通信协议
/标记炸弹串口通信协议
if(buf==0xdd)
{
zhadan_flag=~zhadan_flag; //屏幕点击一次标记炸弹就取反一次,如点击一次表示开始标记炸弹,点击第二次表示取消标记炸弹
}
/标记炸弹安全格子串口通信协议
}与串口屏的通信协议,使用的hal库,用cubemx辅助开发。串口屏的开发有专门的软件就叫UART HMI。再贴一个自己写的的串口屏通信代码(适用于hal库)。
/*
UART HMI 串口屏通信函数 HMISendnum1,2,3分别是不同的字符串与数字的拼接后面的参数是串口号,适用于hal库
*/
void HMISendnum1(char *str1,int nums,UART_HandleTypeDef uart)
{
HAL_StatusTypeDef Flag;
uint8_t b=0xff,i;
char buf1[10];
sprintf(buf1, "%s%d", str1, nums);
Flag=HAL_UART_Transmit(&uart,(uint8_t*)buf1,strlen(buf1),0xffffffff);
while(Flag!=HAL_OK);
for(i=0;i<3;i++)
{
if(b!=0)
{
HAL_UART_Transmit(&uart,&b,1,0xff);
while(Flag!=HAL_OK);
}
else
return ;
}
}
void HMISendnum2(char *str1,int nums,char *str2,UART_HandleTypeDef uart)
{
HAL_StatusTypeDef Flag;
uint8_t b=0xff,i;
char buf1[10];
sprintf(buf1, "%s%d%s", str1, nums,str2);
Flag=HAL_UART_Transmit(&uart,(uint8_t*)buf1,strlen(buf1),0xffffffff);
while(Flag!=HAL_OK);
for(i=0;i<3;i++)
{
if(b!=0)
{
HAL_UART_Transmit(&uart,&b,1,0xff);
while(Flag!=HAL_OK);
}
else
return ;
}
}
void HMISendnum3(char *str1,int nums1,char *str2,int nums2,UART_HandleTypeDef uart)
{
HAL_StatusTypeDef Flag;
uint8_t b=0xff,i;
char buf1[10];
sprintf(buf1, "%s%d%s%d", str1, nums1,str2,nums2);
Flag=HAL_UART_Transmit(&uart,(uint8_t*)buf1,strlen(buf1),0xffffffff);
while(Flag!=HAL_OK);
for(i=0;i<3;i++)
{
if(b!=0)
{
HAL_UART_Transmit(&uart,&b,1,0xff);
while(Flag!=HAL_OK);
}
else
return ;
}
}
//控制串口屏的文本控件,輸入字符串命令,后面是通信的串口号
void HMISendtxt(char *str,UART_HandleTypeDef uart)
{
HAL_StatusTypeDef Flag;
uint8_t b=0xff,i;
Flag=HAL_UART_Transmit(&uart,(uint8_t*)str,strlen(str),0xff);
while(Flag!=HAL_OK);
for(i=0;i<3;i++)
{
if(b!=0)
{
HAL_UART_Transmit(&uart,&b,1,0xffffffff);
while(Flag!=HAL_OK);
}
else
return ;
}
}其他的具体代码就暂时不贴了,如果你对这个项目感兴趣,可以加QQ:943874487,一起交流。也可以看young0219同学的博客:
https://blog.csdn.net/weixin_43793057/article/details/106158063
分享一个有关keil不能使用time函数的点:
keil不支持time()函数,让我苦恼了很久。因为地雷的产生需要使用的随机函数,就需要随机种子,必须要使用到time()函数,很久的尝试之后还是无法使用这个函数,所以去问了一位很厉害的学长,才告诉我keil不支持time函数(如果可以使用各位可以告诉我,感谢),同时提出了另一种解决方案,用定时器的数值作为随机种子,刚开始还是不行,因为初始化地雷每次到达程序段的时间都是一样的,所以随机种子的值也是一样的,但是最后加了界面之后,进入到游戏的时间就随机了,算是成功解决了这个问题。
-