- #include <reg52.h>
- #include <intrins.h>
- #include <math.h>
- #include <stdio.h>
- #define uchar unsigned char
- #define uint unsigned int
-
- uint Time1ms=0;
- uint TimeCount=0;
- //LCD定义
- #define LCD_DB P0
- sbit LCD_RS=P2^0;
- sbit LCD_RW=P2^1;
- sbit LCD_E=P2^2;
- //按键定义
- sbit K1=P3^1;
- sbit K2=P1^0;
- sbit K3=P1^1;
- sbit K4=P1^2;
- //PWM变量
- uint PWMTime=0;
- uint PWMscale=100;
- //速度变量
- uchar Speed=0;
- //里程变量
- uint Meter=0;
- //时间变量
- uint Time01ms=0;
- uint Time10ms=0;
- //按键松开标志位
- bit flag_KEY=0;
- //刹车标志位
- bit bStop=0;
- //滑移率变量
- uint R=0;
- uchar CheSpeed=8;
- sbit LED1=P1^7;
- sbit LED2=P1^6;
- sbit LED3=P1^5;
- uint Count=0;
- /*-------------------------------------
- 函数申明
- ---------------------------------------*/
- void LCD_init(void); //初始化函数
- void LCD_write_command(uchar command); //写指令函数
- void LCD_write_data(uchar dat); //写数据函数
- void LCD_disp_char(uchar x,uchar y,uchar dat);//在某个屏幕位置上显示一个字符,X(0-15),y(1-2)
- void LCD_disp_str(uchar x,uchar y,uchar *str); //LCD1602显示字符串函数
- void delay_n10us(uint n); //延时函数
- /*------------------------------------------------
- 外部中断0程序
- ------------------------------------------------*/
- void INT() interrupt 0
- {
- Count++;
- }
- /*------------------------------------------
- 定时器0中断处理
- --------------------------------------------*/
- void tim0_isr(void) interrupt 1 using 1
- {
- TH0=0XFC;
- TL0=0X66;
- Time1ms++;
- TimeCount++;
- }
- /*-------------------------------------
- 定时器初始化
- ---------------------------------------*/
- void TIM0init(void)
- {
- TMOD=0x11;
- TH0=0xDC; //定时0.1ms
- TL0=0x00;
- ET0=1;
- TR0=1;
- EA=1;
- }
- /*-------------------------------------
- LCD1602子程序 (网上直接用)
- ---------------------------------------*/
- void LCD_init(void)
- {
- delay_n10us(10);
- LCD_write_command(0x38);//设置8位格式,2行,5x7
- delay_n10us(10); LCD_write_command(0x0c);//开显示,关光标,不闪烁
- delay_n10us(10); LCD_write_command(0x06);//设定输入方式,增量不移位
- delay_n10us(10); LCD_write_command(0x01);//清除屏幕显示
- delay_n10us(100); //延时清屏,延时函数,延时约n个10us
- }
- void LCD_write_command(uchar dat)
- {
- delay_n10us(10);
- LCD_RS=0; //指令
- LCD_RW=0; //写入
- LCD_E=1; //允许
- LCD_DB=dat; delay_n10us(10); //实践证明,我的LCD1602上,用for循环1次就能完成普通写指令。
- LCD_E=0; delay_n10us(10); //实践证明,我的LCD1602上,用for循环1次就能完成普通写指令。
- }
- void LCD_write_data(uchar dat)
- {
- delay_n10us(10);
- LCD_RS=1; //数据
- LCD_RW=0; //写入
- LCD_E=1; //允许
- LCD_DB=dat; delay_n10us(10);
- LCD_E=0; delay_n10us(10);
- }
- void LCD_disp_char(uchar x,uchar y,uchar dat)
- {
- uchar address;
- if(y==1)
- address=0x80+x;
- else
- address=0xc0+x;
- LCD_write_command(address);
- LCD_write_data(dat);
- }
- void LCD_disp_str(uchar x,uchar y,uchar *str)
- {
- uchar address;
- if(y==1)
- address=0x80+x;
- else
- address=0xc0+x;
- LCD_write_command(address);
- while(*str!='\0')
- {
- LCD_write_data(*str);
- str++;
- }
- }
- void delay_n10us(uint n) //延时
- {
- uint i;
- for(i=n;i>0;i--)
- {
- nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
- }
- }
- /*-------------------------------------
- 按键扫描
- ---------------------------------------*/
- void keyscan()
- {
- if(K1==0)//刹车
- {
- if(flag_KEY==1)
- {
- flag_KEY=0;
-
- bStop=1;
- }
- }
- else if(K2==0)//车速1
- {
- if(flag_KEY==1)
- {
- flag_KEY=0;
-
- CheSpeed=8;
- }
- }
- else if(K3==0)//车速2
- {
- if(flag_KEY==1)
- {
- flag_KEY=0;
-
- CheSpeed=10;
- }
- }
- else if(K4==0)//车速3
- {
- if(flag_KEY==1)
- {
- flag_KEY=0;
-
- CheSpeed=15;
- }
- }
- else//按键松开
- {
- flag_KEY=1;
- }
- }
- /*-------------------------------------
- 测速程序
- ---------------------------------------*/
- void Check()
- {
- //-----定时1秒--------
- if(Time1ms>=1000)
- {
- Time1ms=0;
- Speed=Count/2;
- Count=0;
- }
- }
- /*-------------------------------------
- LCD显示内容
- ---------------------------------------*/
- void DisPlay()
- {
- //显示轮速
- LCD_disp_char(0,1,Speed/10+'0'); //显示轮速变量
- LCD_disp_char(1,1,Speed%10+'0');
-
- //显示车速
- LCD_disp_char(0,2,CheSpeed/10+'0'); //显示车速变量
- LCD_disp_char(1,2,CheSpeed%10+'0');
-
-
- //显示里程
- LCD_disp_char(10,1,Meter/10000%10+'0'); //显示里程变量
- LCD_disp_char(11,1,Meter/1000%10+'0');
- LCD_disp_char(12,1,Meter/100%10+'0');
- LCD_disp_char(13,1,Meter/10%10+'0');
- LCD_disp_char(14,1,Meter%10+'0');
-
-
- //显示滑移率
- LCD_disp_char(12,2,R/10%10+'0');//显示滑移率
- LCD_disp_char(13,2,R%10+'0');
- }
- /*-------------------------------------
- 计算
- ---------------------------------------*/
- void Jisuan()
- {
-
- //路程累计
- Meter=Meter+Speed;
-
-
-
- if(bStop==1)
- {
- if(R>22)
- {
- LED1=0;
- LED2=1;
- LED3=1;
- }
- else if(R>18)
- {
- LED1=1;
- LED2=0;
- LED3=1;
- }
- else if(R>0)
- {
- LED1=1;
- LED2=1;
- LED3=0;
- }
- else
- {
- LED1=1;
- LED2=1;
- LED3=1;
- }
-
-
-
-
- if(Speed>0)
- {
- if(CheSpeed>Speed)
- {
- R=(CheSpeed-Speed)*100/CheSpeed;
- }
- else
- {
- R=0;
- }
- }
- else
- {
- R=0;
- }
- }
- else
- {
- R=0;
- LED1=1;
- LED2=1;
- LED3=1;
- }
-
-
-
- }
- /*-------------------------------------
- 主函数
- ---------------------------------------*/
- void main(void)
- {
- TIM0init();//定时器配置
- EX0=1;//打开外部中断0
- IT0=1;//下降沿触发
-
- LCD_init();//LCD初始化
- LCD_disp_str(0,1," m/s M"); //显示速度 里程
- LCD_disp_str(0,2," m/s S: % "); //显示滑移率
- while(1)
- {
- keyscan(); //按键扫描
- Check();//测速程序
- DisPlay();//LCD显示
-
- //-----1秒------
- if(TimeCount>=1000)
- {
- TimeCount=0;
- Jisuan();
- }
- }
- }
复制代码
|