51单片机验证牛顿第二定律

51单片机验证牛顿第二定律

  1. 运用定时器
  2. 外部中断
  3. lcd1602的 显示
  4. 数据的处理
#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;
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部