使用51单片机实现的跳一跳物理外挂,包含了proteus仿真与元器件清单
代码不免有粗糙之处;关于跳一跳物理助手的实现方法有很多,从串口通信到舵机、步进电机,如果要以快速精准为目的,还可以使用摄像头或者配合采样电阻进行AD转换来实现来采集信息。
硬件搭设
原理图(见下图)
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
数据分析,首先通过给定的延时时间,测出小棋子跳的距离,记录十组左右升序排列,建表,画出折线图,如下图右侧:
得出的线性回归方程为:
T = 22.26 * L + 56.44 (T是延时时间,L是棋子跳的距离)
若要得到更准确的方程,可再多测量几次数据,再求方程。
(折线的原因是游戏本身是3D的,所以每次用尺子测量的距离误差很大)
总结
软件及数据调试:
1、软件(主要的源码如下:)
#include
#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 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; } }