单片机原理及应用课程设计报告

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

《单片机原理及应用》课程设计报告基于单片机的俄罗斯方块游戏设计
学号
姓名杨欣
同组成员黄涛
专业电气工程及其自动化
班级班
指导教师黄劲
院(系、所)电气与电子工程学院
华中科技大学教务处制
目录
一、课程设计的目的 ..................................................................................
二、题目要求...............................................................................................
三、原理概述...............................................................................................
四、调试过程...............................................................................................
五、验收结果...............................................................................................
六、个人体会...............................................................................................
七、参考文献...............................................................................................
八、致谢....................................................................................................... 附录一:外电路原理图 .............................................................................. 附录二:程序清单 ......................................................................................
一、课程设计的目的
1.加深对单片机的理解,熟悉单片机的原理,掌握单片机的编程方法与技巧
2.灵活运用单片机的基础知识,增强利用理论知识解决实际问题的能力
二、题目要求
.验收时,先在仿真机的上显示自己学号的后位,再进行相应内容验收。

.能在单片机实验箱通用板上的液晶显示屏()上玩俄罗斯方块游戏,使用*键盘输入,能够完美实现俄罗斯方块的基本游戏内容,界面优美,最后可以显示分数和级别,如果游戏失败显示“”,最后显示本人姓名“”和学号“”。

三、原理概述
. 程序整体思路
单片机上的程序设计一般是一个大循环结构,对于俄罗斯方块的程序设计,首先产生一个伪随机数,其范围是,分别对应俄罗斯方块中随机产生的七种方块,然后程序根据此数值所对应的图形模块装入的固定区域内,紧接着将此图像写入所对应的显示缓冲区中,显示程序将缓冲区内的内容显示在显示屏上,如果没有控制键按下,图形将自动向下移动。

如果有键按下,程序将根据按下的键来改变图形存储区的值,同时程序将判断图形是否已到达边界,当图形最上层到达显示区顶部,则游戏结束,此时将清除显示缓冲的内容,游戏重新开始。

.图形显示
液晶显示器一共有*个像素点,本程序中每个像素点用一个坐标表示,左上角为(),右下角为()。

对于显示类的基本操作是任意点亮一个点,熄灭一个点,任意点亮个点,灭掉个点,如此一来游戏的第一个关键点就完成了。

我们将中选取一段为显示缓冲区,这里面的每一位对应上的的一个点,将实时显示缓冲区的内容,也就是当此缓冲区内容一改变,上看到的也会做出相应的改变。

同时游戏中的那些方块被存放在一个类似于一维的数组之中,每一个方块对应四个小方块,根据伪随机数将这四个小方块对应的值装入固定的区域内。

如果要显示方块只需将这些方块所对应的点写入缓冲区就可以了。

.消层算法
设置循环变量数,即总共要扫描次,每一次循环过程中检测此行是否已满,也就是检测这一行所对应的存储单元是否全为,如果全为则将此行消去,即将此行对应的清零。

同时将此行上面的内容按每列依次下移,下移完之后重新令,又从第一行开始检测。

此行不全为零
时只需令,直到消层过程结束。

.旋转算法
首先要确定一个旋转中心,假如旋转中心的编号是,将除以,商是存入余数是存入,及时用商和余数建立坐标系。

此时若以此为旋转中心的图形需要旋转,则将每一个小方块对应编号除以,商减去,余数减去,而每一个方块一次将旋转度,所以有公式,,其中,为旋转之前的坐标,为旋转之后的坐标。

旋转完之后将加上将加上,然后将乘以再加上。

执行四次,此过程旋转结束。

四、调试过程
、学号显示部分单独调试
这个在之前的很多实验中都有涉及,程序较为简单,语句也不复杂,本实验中才用的是并行动态显示,调试一次成功。

2、游戏程序调试相关
五、验收结果
下图为当时的整个实验装置:
实验中,游戏随机产生方块
按下控制键,方块旋转:
按下控制键,方块加速下落
方块下落到底部,最底层被填满:
最底层填满后,自动消去这一层:
随机产生下一个方块,每次产生方块完全随机:
最后一幅图为游戏结束后,显示所得分数,每消去一行得到一分,显示“”和游戏者姓名学号。

本次实验默认游戏者为本人(杨欣),学号()
六、个人体会
在这次实验过程中,特别是调试的时候,如果能够顺利排除实现程序预定功能是最让人开心的,这个过程也会让我很享受。

但是如果由于一些搞不清楚的原因迟迟达不到目标,也是最让人烦躁的。

而其中的问题,只能漫无目的地去尝试,无法在逻辑中得到答案,我个人遇到了这种状况,确实很无奈。

不知道是否是因为我的分析不到位,而实际上有一个合乎逻辑的答案在那里呢?
这次课程设计,第一周主要是在修改程序的驱动部分,从第二周开始上机调试,用了差不多半个月的时间,最终也没有成功调试出结果,实在很受打击,让我很沮丧。

从单片机课程到单片机实验到如今的单片机课程设计,我感触最深的一点就是:必须有耐心、足够细心。

单片机程序前前后后有不少联系,可能前面用的的某个变量跟后面重复、字与字节搞乱等等细小的问题,如果不能耐心、细心地去寻找,很难发现。

最后,我还体会到了,硬件学习是编写程序前最重要的部分,只有对所使用的硬件设备完全了解才能编写出适合使用的程序,否则会做很多无用功,浪费很多时间和精力。

以后一定要谨记这个道理!
七、主要参考文献
【】《单片机原理及应用》姜志海主编
【】《系列单片机原理及应用实验指导书》
八、致谢
感谢黄劲老师的耐心指导!
感谢管理实验室的老师多日来为我们开放实验室!
附录一:电路原理图
按键与单片机连接:
按照*键盘上的布置,游戏控制键分别为:,,,,,液晶显示器与单片机的连接:
附录二:程序清单:
(因程序繁多,此处只列出文件程序,如果老师要看完成程序,请看电子档报告)1.
$
;
; () , .
;
;
; *** <<< >>> ***
; : .
;
; :
;
;
;
;
; :
;
; ,
;
;
; <>
;
;
; :
;
; <> : <>
; <> :
; <> .
;
; <> : <>
; <>
;
; <> : <>
; <> .
;
; <> : <>
; <>
;
; <> : <>
; <> .
;
;<>
;
;<>
;
;
; :
;
; <> .
; <> :
; <> .
; . ; <> : <>
; <> .
;
; <>
;
; <> .
; <> :
; <> .
; . ; <> : <>
; <> .
;
; <>
;
; <> .
; <> :
; <> .
; . ;
; <> : <>
; <> .
;
; <>
;<>
;
;
; <>
;
; <> .
; <> .
;
;
; . ;
; <> <>
; <> .
;
; <> <>
; <>
;
; <>
;
()
:
:
<>
:
<>
() ( ()) <>
( ())
() :
<>
<>
()
() :
<>
()
<>
()
<>
()
;
;<>
; <>
; <> . ()
; ;<>
2.
""
""
""
全局数据
[]{};
[]{};
; 方块的位置
;
[][]; 游戏平台数据
; 当前形状
;
; 等级速度,正常情况,方块下降的速度;
;
方块形状的定义
{
;
;
};
{
[];
; 下一个形状
}
[]{
{ },
{ },
{ },
{ },
{ },
{ },
{ },
{ },
{ },
{ },
{ },
{ },
{ },
{ },
{ },
{ },
{ },
{ },
{ },
};
************************************************************************** 函数原型()
功能: 初始化游戏平台
参数: 无
返回值: 无
函数性质:公有函数
注意:
*************************************************************************** ();
()
{
;
;
;
( ); 初始化游戏平台边界画游戏区域
( ); 画上横线
();
(); 画左竖线
();
(); 画下横线
();
(); 画右竖线
(<) 游戏平台数据清零
{
(<)
{
[][];
}
}
(<)
{
[][]; 游戏平台最下面一行的每一个方块位置为1,作为下边界
}
(<) 游戏平台左右方块位置置1,作为左右边界
{
[][];
[][];
}
(); 输入“分”汉字
(); 输入“级”汉字
(); 显示初始分数
(); 显示初始等级水平
(); 根据水平确定速度
;
;
;
}
()
{
;
();
(); 输入“按”汉字
(); 显示
(); 输入“开”汉字
(); 输入“始”汉字
}
************************************************************************** 函数原型( )
功能: 显示一个小方块
参数: 小方块的横,坚坐标:显示小方块:删除小方块
返回值:
函数性质:私有函数
注意:
*************************************************************************** ( )
{
*; 将方块在平台的位置转化成LCD的点坐标(地址转换)*;
;
()
{
(<)
{
(); 画一条横线
}
;
(<)
{
(); 画第二条横线
}
(<)
{
(); 画第条坚线
}
;
(<)
{
(); 画第条坚线
}
;
(<)
{
(); 画斜线
}
}
{
(<)
{
(); 画一条横线
}
;
(<)
{
(); 画第二条横线
}
(<)
{
(); 画第条坚线
}
;
(<)
{
(); 画第条坚线
}
;
(<)
{
(); 画斜线
}
}
}
左冲突检测
()
{
;
(<)
{
([[][]][[][]])
;
}
;
}
右冲突检测
()
{
;
(<)
([[][]][[][]])
;
}
;
}
下冲突检测
()
{
;
(<)
{
([[][]][[][]])
;
}
;
}
改变形状时产生的冲突检测
()
{
;
(<)
{
([[[]][]][[[]][]])
; 检测一个形状的冲突情况}
;
}
产生一个随机数,返回一个随机数
()
{
;
;
();
}
计分函数,参数为消行行数
( )
{
*;
{
(); 显示个位
}
(<)
{
();
(); 显示个位,十位
}
(<)
{
();
();
(); 显示个位,十位,百位
}
{
();
();
(); 显示个位,十位,百位,千位
();
}
()
{
(>)
{
;
()
{
;
(); 输出“太棒了"
();
();
}
(); 显示水平
}
}
}
************************************************************************** 函数原型()
功能: 消除行
参数: 无
返回值: 无
函数性质:私有函数
注意:
*************************************************************************** ()
{
; 标识要删除的行
; 标识删除的行数
;
; 标识一行中是否有空白点
(<)
{
(<)
{
([][])
; 如果这一行中有一个为空,则退出这一行的循环
()
{
; 确定要删除的行
(<)
{
; 计算共删除的行数
(<)
{
(); 删除行
[][]; 平台数据清零
}
() 下移
{
;
(<)
{
([][])
{
; 标识这一行有要下移的点
(); 删除小方块
[][]; 平台数据清零
() ; 将小方块下移
[][]; 平台数据置,表明此位置已被占用
}
}
() ; 没有要下移的行,退出本循环
; 下移上一行
}
}
}
}
}
()
{
(); 刷新分数显示
}
}
************************************************************************** 函数原型( )
功能: 显示一个方块形状或删除一个方块形状
参数: ()为显示位置为显示的形状为显示不显示
返回值:
函数性质:私有函数
注意:
*************************************************************************** ( )
{
()
{
([][][][]); 显示形状
([][][][]);
([][][][]);
([][][][]);
}
{
([][][][]); 删除形状
([][][][]);
([][][][]);
([][][][]);
}
}
************************************************************************** 函数原型()
功能: 方块下降处理
参数:
返回值:
函数性质:公有函数
注意:
*************************************************************************** ; 标识下降速度
; 当前速度
()
{
;
; 标识是否要产生新形状
() ;
()
{
;
;
;
; 当前方块等于预方块
(); 产生一下个方块前,将预方块删除
(); 产生下一个方块
(); 显示当前方块
(); 预显示下一个方块
(())
{
;
(); 清屏
(); 显示
(); 显示
;
}
}
{
()
{
; 确定方块下落的速度
(())
{
产生新的形状
(<)
{
[[][]][[][]]写入平台
}
()消行计分
;
}
{
(); 删除当前形状
;
(); 显示形状(形状下移一个位置)
;
}
}
{
;
}
}
}
************************************************************************** 函数原型()
功能: 方块游戏控制
参数:
返回值:
函数性质:公有函数
注意:
***************************************************************************
()
{
() 消息处理
{
:
{
; 信息已被处理,抛弃它
(())
{
(); 删除当前形状
;
(); 显示移动后的形状
}
};
:
{
; 信息已被处理,抛弃它
(())
{
(); 删除当前形状
;
(); 显示移动后的形状
}
};
:
{
; 信息已被处理,抛弃它
()
{
()
{
;
(); 显示等级水平
(); 根据水平确定速度
}
{
;
(); 显示等级水平
(); 根据水平确定速度
}
}
{
; 调整位置后,加速下降
;
}
};
:
{
; 信息已被处理,抛弃它
()
{
()
{
;
(); 显示等级水平
(); 根据水平确定速度
}
{
;
(); 显示等级水平
(); 根据水平确定速度
}
}
{
(())
{
(); 删除当前形状
[];
(); 显示变化后的形状
}
}
};
:
{
; 信息已被处理,抛弃它
();
();
();
;
};
:
{
; 信息已被处理,抛弃它
;
}
;
}
}
3.
""
""
端口定义
^;
^;
^;
^;
^;
^;
^;
^;
; 键盘缓冲寄存器(公有数据)
; 功能键
********************************************************************* 函数原型: (* , * )
功能: 扫描键盘
参数: 普通键,功能键,缓存器的指针
返回值:
函数性质:私有函数
**********************************************************************
(* , * )
{
;
( ) * ''; 键
( ) * ;
( ) * '';
( ) * '';
;
;
( ) * ;
( ) * ;
( ) * ;
( ) * '';
;
;
( ) * ;
( ) * ;
( ) * ;
( ) * '*';
;
;
( ) * ;
( ) * ;
( ) * ;
( ) * '';
;
}
********************************************************************* 函数原型: ()
功能: 键盘缓冲寄存器更新程序. 普通键, 功能键
参数:
返回值:
函数性质:公有函数
********************************************************************** ()
{
; 去抖动延时
; 标识是否正在延时
()
{
() 如果缓存器中的数据未被读取,则不扫描键盘
{
(); 扫描键盘
()
{
;
;
}
}
}
{
() 延时结束
{
(); 读取键盘
;
}
; 延时减一}
}
4.
""
""
""
""
()
{
();
();
();
(, , );
(, , );
(, , );
();
()
{
();
}
}
5.
""
""
定义任务结构
{
( * )();
;
;
;
};
[]; 定义任务数据结构
任务开始---------------------()
{
;
}
系统进入空闲模式,等待下一次刷新---------()
{
;
}
任务添加---------------------
( ( * )() )
{
;
(([] ) ( < ))
{
; 查找空的任务指针
}
( )
{
;
}
[] ;
[] ;
[] ;
[] ;
;
}
任务删除-----------------------
( )
{
([] )
{
;
}
[] ;
[] ;
[] ;
[] ;
;
}
任务调度---------------------
()
{
;
( ; < ; )
{
([] > )
{
(*[])();
[] ;
([] ) 删除只运行一次的任务
{
();
}
}
}
(); 单片机进入空闲模式
}
-----------------任务中断刷新------------------
()
{
;
;
( ; < ; )
{
([])
{
([] )
{
[] ;
([])
{
[] [];
}
}
{
[] ;
}
}
}
}
----------------系统初始化-------------------
()
{
;
( ; < ; )
{
();
}
;
;
;
;
;
;
;
;
}
6.
""
""
""
""
;
;
接口定义
;
^ ; ???原理图错了?
^ ;
^ ;
常量数据
[] {
*得* ,
,
*分* ,
,
*等* ,
,
*级* ,
,
*按* ,
,
*开* ,
,
*始* ,
,
*太* ,
,
*棒* ,
,
*了* ,
,
*!* ,
};
底层调用小函数待修改???
延时几微秒
()
{
;
;
;
}
读状态位和,:指令读写状态准备好;:数据读写状态准备好()
{
;
(){
;
;
;
((^)(^)) ; 判断指令、数据读写状态是否准备好
}
}
读状态位, 检测数据自动读状态是否准备好
()
{
;
(){
;
;
;
(^) ;
}
}
读状态位, :数据自动写状态准备好
(){
;
()
{
;
;
;
(^) ;
}
}
读状态位, 检测屏读或屏拷贝出错状态::出错;:正确()
{
;
()
{
;
;
;
(^) ;
}
}
对进行读写数据
写数据
( )
{
();
;
;
;
;
}
读数据
()
{
();
;
;
;
写命令
( )
{
();
;
;
;
;
}
单参数指令
( )
{
(); 写数据
(); 写命令
}
双参数指令
( )
{
(); 写数据
(); 写数据
(); 写命令
}
常用处理程序
初始化显示
()
{
设置文本显示首地址
();
设置文本显示区宽度字节
();
设置图形显示区首地址
(); 首地址
设置图形显示区宽度
(); 字节
设置的首地址
();
设置显示方式
(); 启用内部字符发生器,显示方式是文本与图形逻辑或
设置显示状态
(); 启用光标闪烁、光标显示、文本显示、图形显示
}
清显示
(){
;
设置显示地址
();
进入自动写方式
();

(<){
();
}
退出自动写方式
();
}
***********************************************************************
函数原型: ( , )
功能: 根据字符的行列设置地址
参数: 行坐标,列坐标
返回值:
函数性质:私有函数
***********************************************************************
( , )
{
;
;
* ;
;
>>;
;
();
}
************************************************************************ 函数原型: ( , )
功能: 根据的行列设置图形字节的地址
参数:
返回值:
函数性质:私有函数
************************************************************************ ( , )
{
;
;
* ;
;
>>;
;
();
}
************************************************************************** 函数原型: ( , )
功能: 在指定坐标位置显示一个点
参数: 坐标,显示点或清除点
返回值:
函数性质:私有函数
:显示:清除该点
**************************************************************************
( , )
{
;
;
;
()* (>>) ; 地址转化
; 产生位操作命令画点的数据
() ;
;
>>;
;
(); 设置该点所在单元地址
(); 利用位操作命令画点
}
***************************************************************************** 函数原型: ( , * )
功能: 连续写入一个或多个字符
参数: 坐标,要显示的字符数组,显示的单个字符,要显示的字符个数
返回值:
函数性质:私有函数
当一次性写入一个字符,否则一次性写入多个字符
*****************************************************************************
( , * )
{
;
(); 写入地址
()
(); 一次写入数据
{
()进入自动写
(<)
([]);
(); 退出自动写
}
}
****************************************************************************** 函数原型: ( , )
功能: 连续写入一个或多个汉字
参数: 坐标,要显示的第一个汉字的位置,连续显示汉字的个数。

返回值:
函数性质:私有函数
当一次性写入一个字符,否则一次性写入多个字符
*****************************************************************************
( , )
{
;
;
*; 第个字符
(<)
{
(); 汉字左上角写入
(); 一次写入数据;
;
;
(); 汉字左下角写入
();
;
;
;
(); 汉字右上角写入
();
;
;
(); 汉字右下角写入
();
;
;
;
()
{
; 写满一行,从第二行开始
;
;
}
}
}
****************************************************************************** 函数原型: ( * )
功能: 填充数据
参数: 字符数组,写入第个汉字,循环写入的汉字个数
返回值:
函数性质:私有函数
***************************************************************************
( * )
{
;
;
;
;
;
*; 确定地址
;
>>;
;
();
*;
();
(<)
([]);
(); 退出自动写
}
******************************************************************************* 函数原型: ( , )
功能: 画一条横线或一条竖线
参数: 为横线,否则为竖线,()为起始点,为长度,为显示
返回值:
函数性质:公有函数
*******************************************************************************
( , ){
;
()
{
(<) 画横线
{
()
();
();
}
;
}
{
(<) 画竖线
{
()
();
();
}
;
}
}
***************************************************************************** 函数原型: ( )
功能: 填充区域() ()
参数: ()为起始点,()为终点显示
返回值:
函数性质:私有函数
注意:以点为单位
*****************************************************************************
( )
{
;
()
{
(<)
(<)
();
}
{
(<)
(<)
();
}
}
******************************************************************************* ***
函数原型: ( * )
功能: 在设定的区域连续写入多个字节,作图形显示用
参数: ()为起始点,()为终点*为图形数组,显示清除
返回值:
函数性质:私有函数
操作方法:当时,连续输入,作反显用,当时,连续输入,作
消除反显用,当时,作输入图像用,此时无效
注意:参数的数据范围
******************************************************************************* ***
( * )
{
;
;
(<)
{
;
(); 写入地址
(); 进入自动写
(<)
{
()
{
();
}
()
{
();
}
{
([]);
; 下一个字节
}
}
(); 退出自动写
}
}
****************************************************************************** 函数原型: ( )
功能: 反显区域() ()
参数: ()为起始点,()为终点反显
返回值:
函数性质:私有函数
注意:以字节为单位
******************************************************************************
( )
{
()
{
(); 启用内部字符发生器,显示方式是文本与图形逻辑异或
();
}
{
(); 启用内部字符发生器,显示方式是文本与图形逻辑或
();
}
}
****************************************************************************** 函数原型: ( )
功能: 在设定的位置显示一个数字
参数: ()为位置,为数字
返回值:
函数性质:公有函数
注意:以字节为单位
***************************************************************************** ( )
{
[]{};
();
([]); 一次写入数据
}
初始化
()
{
();
();
(); 将汉字写入
}。

相关文档
最新文档