跳一跳物理助手的实现,代码更加规范,视频请参https://v.youku.com/v_show/id_XN ... 42.soresults.dtitle
全部资料51hei下载地址:
微信跳一跳物理助手(不含视频).zip
(664.37 KB, 下载次数: 11)
算法:
1.数据分析:首先通过给定的延时时间,测出小棋子跳的距离,记录十组左右升序排列,建表,画出折线图,如下图右侧:
得出的线性回归方程为:
T = 22.26 * L + 56.44 (T是延时时间,L是棋子跳的距离)
若要得到更准确的方程,可再多测量几次数据,再求方程。
(折线的原因是游戏本身是3D的,所以每次用尺子测量的距离误差较大)
2.算法实现:
paramsInit()中初始化结构体:
Jump_Params.L=0;
Jump_Params.m=22.26;
Jump_Params.n=56.44;
main.c中计算延时时间:
Jump_Params.T=Jump_Params.m*Jump_Params.L+Jump_Params.n; //计算延时时间
Rela()中实现触屏延时:
RELAY=0;
delay_ms(Jump_Params.T); //延时时间T,已由距离——时间函数算出
RELAY=1;
while(!K1); //等待按键释放
九、运行设计:
1、硬件运行设计
可选择普中科技HC6800-EM3开发板或使用以下材料参照电路原理图自行搭建。
单片机STC89C52RC、74HC138、74HC573、5V继电器模块、四脚轻触开关、四位数码管、晶振、电容、电阻、LED灯、铜箔胶带等,
2、软件运行设计:
使用KEIL C51 (8051内核的微控制器开发工具)进行程序设计,使用STC-isp 下载器进行程序烧录。
软件结构图
二、逻辑框图
三、功能流程图:
四、软件总体设计:
五、软件接口:
1.毫秒延时函数
//--------------------------------------------------------------------------------------------
// @brief 毫秒延时
// @param 延时毫秒数值 类型unsigned int
// @return void
// @since v2.0
// Sample usage: delay_ms(10);//延时10ms
//--------------------------------------------------------------------------------------------
void delay_ms(unsigned int n)
{
unsigned int i=0,j=0;
for(i=0;i<n;i++)
for(j=0;j<123;j++);
}
2、数值拆分函数
//-------------------------------------------------------------------------------------------------------------------
// @brief 数值拆分
// @param 待显示的十进制数 类型uchar
// @return void
// @since v2.0
// Sample usage: DisplayData(90);
//-------------------------------------------------------------------------------------------------------------------
void DisplayData(uchar c) //数值拆分函数
{
dig[0]=smgduan[c/1000];
dig[1]=smgduan[(c-(c/1000)*1000)/100];
dig[2]=smgduan[(c%100)/10];
dig[3]=smgduan[c%10];
}
六、模块名称功能:
以下为模块化编程中各模块名称及功能的介绍
1、按键模块
key.c
key.h
功能:按键输入
2、外部中断模块
EXIT.c
EXIT.h
功能:中断按键触发,清零距离与数码管数值
3、显示模块:
Display.c
Display.h
功能:数码管显示
4、继电器控制模块:
RelayControl.c
RelayControl.h
功能:实现触屏功能
5、延时模块:
Delay_ms.c
Delay_ms.h
功能:延时
6、结构体参数头文件
Params.h
功能:参数设定
7、工程整合头文件
common.h
功能:包含工程中的所有头文件
七、函数名称功能介绍:
1、
//--------------------------------------------------------------------------------------------
// @brief 按键扫描
// @param void
// @return void
// @since v2.0
// Sample usage: keyscan();
//--------------------------------------------------------------------------------------------
void keyscan() //按键扫描函数
{
uint a=0;
uchar KeyValue;
GPIO_SEG1=0x0f;
if(GPIO_SEG1!=0x0f)
{
delay_ms(10);
if(GPIO_SEG1!=0x0f)
{
GPIO_SEG1=0x0f;
switch(GPIO_SEG1)
{
case(0x07):
KeyValue=0;break;
case(0x0b):
KeyValue=1;break;
case(0x0d):
KeyValue=2;break;
case(0x0e):
KeyValue=3;break;
}
GPIO_SEG1=0xf0;
switch(GPIO_SEG1)
{
case(0x70):
KeyValue=KeyValue;break;
case(0xb0):
KeyValue=KeyValue+4;break;
case(0xd0):
KeyValue=KeyValue+8;break;
case(0xe0):
KeyValue=KeyValue+12;break;
}
while(a<500&&(GPIO_SEG1!=0xf0)) //0.5秒后自动释放按键
{
delay_ms(1);
a++;
}
Jump_Params.num++;
if(Jump_Params.num==1)
{
Jump_Params.L=KeyValue*10.0; //第一次按下取得的值作十位
}
if(Jump_Params.num==2)
{
Jump_Params.L=Jump_Params.L+KeyValue*1.0; //第二次按下取得的值作为个位
Jump_Params.num=0; //清零计数标志
}
}
}
}
2、
//--------------------------------------------------------------------------------------------
// @brief 外部中断初始化
// @param void
// @return void
// @since v2.0
// Sample usage: Init0();
//--------------------------------------------------------------------------------------------
void Init0() //外部中断配置函数
{
EA=1;
EX0=1;
IT0=0;
}
3、
//--------------------------------------------------------------------------------------------
// @brief 外部中断服务函数
// @param void
// @return void
// @since v2.0
// Sample usage: 内部调用,用户无需调用
//--------------------------------------------------------------------------------------------
void Int0() interrupt 0 //中断按键触发,清零距离L与数码管数值num
{
delay_ms(10);
if(Kt==0)
{
Jump_Params.L=0;
Jump_Params.num=0;
}
}
4、
//-------------------------------------------------------------------------------------------------------------------
// @brief 数码管显示
// @param void
// @return void
// @since v2.0
// Sample usage: DigDisplay();
//-------------------------------------------------------------------------------------------------------------------
void DigDisplay() //数码管显示函数
{
uchar i;
for(i=0;i<4;i++)
{
switch(i)
{
case 0:
LsC=0;LsB=0;LsA=0;break;
case 1:
LsC=0;LsB=0;LsA=1;break;
case 2:
LsC=0;LsB=1;LsA=0;break;
case 3:
LsC=0;LsB=1;LsA=1;break;
}
P1=dig[ i];
delay_ms(1);
P1=0x00; //数码管消隐
}
}
5、
//-------------------------------------------------------------------------------------------------------------------
// @brief 数值拆分
// @param 待显示的十进制数 类型uchar
// @return void
// @since v2.0
// Sample usage: DisplayData(90);
//-------------------------------------------------------------------------------------------------------------------
void DisplayData(uchar c) //数值拆分函数
{
dig[0]=smgduan[c/1000];
dig[1]=smgduan[(c-(c/1000)*1000)/100];
dig[2]=smgduan[(c%100)/10];
dig[3]=smgduan[c%10];
}
6、
//-------------------------------------------------------------------------------------------------------------------
// @brief 继电器模拟触屏控制
// @param void
// @return void
// @since v2.0
// Sample usage: Rela();
//-------------------------------------------------------------------------------------------------------------------
void Rela() //继电器控制函数
{
if(K1==0)
{
delay_ms(10);
if(K1==0)
{
RELAY=0;
delay_ms(Jump_Params.T);
RELAY=1;
while(!K1);
Jump_Params.num=0;
Jump_Params.L=0;
}
}
else
{
RELAY=1;
}
}
7、
//-------------------------------------------------------------------------------------------------------------------
// @brief 毫秒延时
// @param 延时毫秒数值 类型unsigned int
// @return void
// @since v2.0
// Sample usage: delay_ms(10);//延时10ms
//-------------------------------------------------------------------------------------------------------------------
void delay_ms(unsigned int n)
{
unsigned int i=0,j=0;
for(i=0;i<n;i++)
for(j=0;j<123;j++);
}
|