51单片机验证牛顿第二定律
51单片机验证牛顿第二定律
- 运用定时器
- 外部中断
- lcd1602的 显示
- 数据的处理
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
#define s 30
sbit led = P2^4;
sbit key1 = P1^7;
sbit key2 = P3^2;
sbit key3 = P3^0;int count =0;
int str[3];
int m = 0;
int m1 = 0;
int flag = 0;
int flag1 = 0;
int temp = 0;
int temp1 = 0;int t0;
int t2;
int t1;
int a ;
int v0;
int v1;
int v2;int pp =0;
int pp1 = 0;void data_deal();
/* 初始化定义引脚 */
sbit rs=P2^0;
sbit rw=P2^1;
sbit lcden=P2^2;void Delay(uint num) //延时函数
{while( --num );
}void delay1(int ms)
{
unsigned char n;while(ms--){for(n = 0; n<250; n++){_nop_();_nop_();_nop_();_nop_();}}
}/******** 1602的设置 ********/
void write_com(uchar com) //写指令
{// while(lcd_busy());rs = 0;
// LCD_RW = 0;lcden = 0;_nop_();_nop_(); P0 = com;delayNOP();lcden = 1;delayNOP();lcden= 0; Delay(10);
}void write_date(uchar date) //写数据
{// while(lcd_busy());rs = 1;
// LCD_RW = 0;lcden= 0;P0 = date;delayNOP();lcden = 1;delayNOP();lcden= 0; Delay(10);}void init1()
{TMOD=0x10; //模式设置,00000001,可见采用的是定时器0,工作与模式1(M1=0,M0=1)。TH1=(65536-46080)/256; //由于晶振为11.0592,故所记次数应为46080,计时器每隔50000微秒发起一次中断。
TL1=(65536-46080)%256; //46080的来历,为50000*11.0592/12ET1=1; //开定时器0中断EA=1; //开总中断EX1 = 1;IT1 = 1;
}/**** 相关的初始化 ******/
void init()
{TMOD=0x01; //模式设置,00000001,可见采用的是定时器0,工作与模式1(M1=0,M0=1)。TH0=(65536-46080)/256; //由于晶振为11.0592,故所记次数应为46080,计时器每隔50000微秒发起一次中断。TL0=(65536-46080)%256; //46080的来历,为50000*11.0592/12ET0=1; //开定时器0中断EA=1; //开总中断EX0 = 1;IT0 = 1;
}void init_1602() //1602的初始化
{rw = 0;delay1(15); write_com(0x01); //清除LCD的显示内容 write_com(0x38); //16*2显示,5*7点阵,8位数据delay1(5);write_com(0x38);delay1(5);write_com(0x38);delay1(5);write_com(0x0c); //开显示,不显示光标 delay1(5);write_com(0x01); //清除LCD的显示内容delay1(5);
}
/*** 显示处理 ****/
void display_xy(uchar x,uchar y)
{ if(y==0x01){x = x + 0x40 + 0x80; }else{x = x+0x80; //数据指针设置 80H+地址码 (0-27H,40H-67H)}write_com(x);
}void Disp1Char(uchar x,uchar y,uchar f_data)
{display_xy(x,y);write_date(f_data); 输出数据
}void Disp_float(uint f_data)
{ unsigned char lcd_table[3];lcd_table[0]= f_data/100; //第一位lcd_table[1]= f_data%100/10; //第二位lcd_table[2]=f_data%100%10;Disp1Char(3,0,(lcd_table[0]+0x30)); //显示整数部分的十位数 0x30的原因CGROM和CGRAM与字符的对应关系Disp1Char(4,0,(0x2e)); //显示小数点"." 小数点对应00101110Disp1Char(5,0,(lcd_table[1]+0x30));Disp1Char(6,0,(lcd_table[2]+0x30)); //显示小数部分的个位// Disp1Char(7,0,(lcd_table[3]+0x30));//Disp1Char(8,0,(lcd_table[2]+0x30)); //显示小数部分的十分位 //加上0x30以便直接得到相应的ASCII码去显示
}void Disp_float1(uint f_data)
{ unsigned char lcd_table[3];lcd_table[0]= f_data/100; //第一位lcd_table[1]= f_data%100/10; //第二位lcd_table[2]=f_data%100%10;Disp1Char(11,0,(lcd_table[0]+0x30)); //显示整数部分的十位数 0x30的原因CGROM和CGRAM与字符的对应关系Disp1Char(12,0,(0x2e)); //显示小数点"." 小数点对应00101110Disp1Char(13,0,(lcd_table[1]+0x30));Disp1Char(14,0,(lcd_table[2]+0x30)); //显示小数部分的个位}
void Disp_float2(uint f_data)
{ unsigned char lcd_table[3];lcd_table[0]= f_data/100; //第一位lcd_table[1]= f_data%100/10; //第二位lcd_table[2]=f_data%100%10;Disp1Char(3,1,(lcd_table[0]+0x30)); //显示整数部分的十位数 0x30的原因CGROM和CGRAM与字符的对应关系Disp1Char(4,1,(0x2e)); //显示小数点"." 小数点对应00101110Disp1Char(5,1,(lcd_table[1]+0x30));Disp1Char(6,1,(lcd_table[2]+0x30)); //显示小数部分的个位}void Disp_float3(uint f_data)
{ unsigned char lcd_table[3];lcd_table[0]= f_data/100; //第一位lcd_table[1]= f_data%100/10; //第二位lcd_table[2]=f_data%100%10;Disp1Char(11,1,(lcd_table[0]+0x30)); //显示整数部分的十位数 0x30的原因CGROM和CGRAM与字符的对应关系Disp1Char(12,1,(0x2e)); //显示小数点"." 小数点对应00101110Disp1Char(13,1,(lcd_table[1]+0x30));Disp1Char(14,1,(lcd_table[2]+0x30)); //显示小数部分的个位}
void start_inter()
{ uint temp;while(1 ){if(pp==20){ pp=0;m++;if(m==600){m=0; //若到了600s,则归零}}temp = m *100;// Disp_float(temp);if(flag == 1 && count == 1)
{TR0 = 0; //关闭定时器flag = 0;t0 = temp;break;
}if(flag == 1 && count == 2){TR0 = 0;flag = 0;t2 = temp;data_deal();break;}
}}void data_deal()
{ //Disp_float1(t0);// Disp_float2(t2);//Disp_float(t0);
t1 = t2 -t0;a = (2 * s*(2*t0 – t2)) /(t0*t2*(t2- t0));v0 = (s -(a/2)*t0*t0)/t0;v1 = v0 + a *t0;v2 = v0 + a* t2;Disp_float(v0);Disp_float1(v1);Disp_float2(v2);Disp_float3(a);
}void time0() interrupt 1
{TH0=(65536-46080)/256;TL0=(65536-46080)%256;pp++;}void interrupt0() interrupt 0
{//开外部中断0if ( key2 == 0) //触发门外光控回路之前,没有触发门内的
{
count++; flag = 1; //启动显示标志}}int main()
{// int t1;
// int t2;init_1602();// init();Disp1Char(0,0,'v');Disp1Char(1,0,'0'); //将第一个字符a(加速度)写在向右偏移1个字符处,为后面的由右向左划入做准备。Disp1Char(2,0,'=');
// Delay(20);Disp1Char(8,0,'v');Disp1Char(9,0,'1'); //将第二个字符v(瞬时速度)写在向右偏移1个字符处,为后面的由右向左划入做准备。Disp1Char(10,0,'=');
// Delay(20); Disp1Char(0,1,'v');Disp1Char(1,1,'2'); //将第三个字符t(时间)写在向右偏移1个字符处,为后面的由右向左划入做准备。Disp1Char(2,1,'=');Disp1Char(8,1,'a');Disp1Char(9,1,'=');
// Delay(20);//EA = 1; //开启串行口中断允许,开启外部中断0、外部中断1//设置外部中断0、1为下降沿触发
while(1)
{ if(key1== 0 ){EA = 1;TR0 = 1;init();start_inter();if(flag == 1)
{EX0 = 0; EA=0; }}// Disp_float3(str[0]);//Disp_float2(str[1]);;}return 0;
}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
