使用51单片机实现的跳一跳物理外挂,包含了proteus仿真与元器件清单
代码不免有粗糙之处;关于跳一跳物理助手的实现方法有很多,从串口通信到舵机、步进电机,如果要以快速精准为目的,还可以使用摄像头或者配合采样电阻进行AD转换来实现来采集信息。
硬件搭设
原理图(见下图)
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
数据分析,首先通过给定的延时时间,测出小棋子跳的距离,记录十组左右升序排列,建表,画出折线图,如下图右侧:
得出的线性回归方程为:
T = 22.26 * L + 56.44 (T是延时时间,L是棋子跳的距离)
若要得到更准确的方程,可再多测量几次数据,再求方程。
(折线的原因是游戏本身是3D的,所以每次用尺子测量的距离误差很大)
总结
软件及数据调试:
1、软件(主要的源码如下:)
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
#define GPIO_SEG1 P0
sbit LsA=P2^2;
sbit LsB=P2^3;
sbit LsC=P2^4;
sbit K1=P2^0;
sbit Kt=P3^2;
sbit RELAY=P2^1;
float m=22.26,n=56.44,L;
uint T;
uchar num=0;
uchar code smgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07};
void delay_ms(uint n);
void DigDisplay();
uchar dig[4];
void DisplayData(uchar c);
void Rela();
void keyscan();
void Init0();
void main()
{
Init0();
while(1)
{
keyscan();
T=m*L+n;
DisplayData(L);
DigDisplay();
Rela();
}
}
void Rela()
{
if(K1==0)
{
delay_ms(10);
if(K1==0)
{
RELAY=0;
delay_ms(T);
RELAY=1;
while(!K1);
num=0;
L=0;
}
}
else
{
RELAY=1;
}
}
void delay_ms(unsigned int n)
{
unsigned int i=0,j=0;
for(i=0;i<n;i++)
for(j=0;j<123;j++);
}
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;
}
}
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];
}
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))
{
delay_ms(1);
a++;
}
num++;
if(num==1)
{
L=KeyValue*10.0;
}
if(num==2)
{
L=L+KeyValue*1.0;
num=0;
}
}
}
}
void Init0()
{
EA=1;
EX0=1;
IT0=0;
}
void Int0() interrupt 0
{
delay_ms(10);
if(Kt==0)
{
L=0;
num=0;
}
}