找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2676|回复: 0
收起左侧

人机界面初稿

[复制链接]
ID:190116 发表于 2017-6-16 02:50 | 显示全部楼层 |阅读模式
#include <reg52.h> // 引用标准库的头文件  
#include <intrins.h>   
#include <eeprom.h>

#define uchar unsigned char
#define uint  unsigned int
#define det_Dist 0.45454545         //20MM/44

//=============HALL按键接口======================
sbit    HALL_r  =    P3^2;// 右边HALL模块检测口 INT0
sbit    HALL_l  =    P3^3;// 左边HALL模块检测口 INT1     

sbit        up=P2^0;           //up
sbit        down=P2^1;           //down
sbit        m1234=P2^2;   // m1234

//=================电机驱动接口=====================
sbit    dianji_r = P1^0;  //右边电机U10P7控制口,低电平正转,高电平反转
sbit    pwm_r = P1^1;
sbit    brake_r = P1^2;          //刹车
sbit    dianji_l = P1^3;  //左边电机U9P6控制口,低电平正转,高电平反转
sbit    pwm_l = P1^4;
sbit    brake_l = P1^5;          //刹车

sbit    r12 = P0^0;            //RCK  or #define r12 P0_0?
sbit    s11 = P0^1;                   //SCK
sbit    d14 = P0^2;                  //模拟SPI总线

uchar r_count;//右边HALL检测到的次数计数单元xj
uchar l_count;         //xj                       
uint time;                //xj
uchar i,j;                            //定义循环控制变量lc
uchar code duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x7F};        //0x7F点亮小数点
                    //0    1    2    3    4    5    6    7    8    9    .  BLOG
uchar code duandp[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};        //段码含小数点
                    //0.    1.    2.   3.   4.   5.  6.   7.    8.  9.    zb
uchar code wei[]={0x01,0x02,0x04,0xf7,0xef,0xdf,0xbf,0x7f};                //后5位键扫用,按M1234键序送出低电平
                                   //1    2    3    m    1    2    3    4           BLOG        ,11110111,11101111,11011111,10111111,01111111
uint keyvalue;         //BGSY TinyHMI
    //uchar KeyValue;        //用来存放读取到的键值 PZ矩阵
    //uchar M,O,T,TRE,F;
void    check_right();//右边时候检测到停止测试程序
void    check_left();//左边时候检测到停止测试程序   

void delay_50us(uint t); //xj
void delayms(uint Ms);         //xj
void delay2ms(void);         //595BLOG
   //void delay(uint i);                 //PZ
void h595_in(uchar Data); //595BLOG
void h595_out(void);           //595BLOG
void Hc595SendData(uchar SendVal); //595BLOG+YL视

void TinyHMI_STR(void);
void TinyHMI_CP(void);
char delay100us(unsigned int uiDly);
void TinyHMI_Display(unsigned char Data); //8位串入并出带锁存送数子程序
void TinyHMI_Show(unsigned i,unsigned j);
void TinyHMI_Scan(void);
   //void KeyDown(void);                  //PZ矩阵
//void Keypros();                           //PZ后要用

   //=============计数器初始化子程序BK ======================
void Init_Timer0(void)         
{  
    TMOD = 0x0D;        // TMOD=00001101B不影响定时计数器T1  
                        // 使用定时计数器T0(GATE 1, C/T 1计数, M1 0, M0 1)  
                        // 使用模式1, 16位定时器.  
    TH0 = (65536 - 50000) / 256;     // 计数器计数初值, 这里使用定时器最大值从0开始计数一直到65535溢出  
    TL0 = (65536 - 50000) % 256;  
                  
    EA = 1;            // 总中断打开  
    ET0 = 0;           // 不使用定时器T0管脚的中断  
    TR0 = 1;           // 定时器计数器开关打开  
}                                           // 计数器器初始化子程序


//***********************主程序******************************
main()   
{
    uchar cnt=0;
    uint temp=0;
    uint tab=0,wap=0,a;            //定义无符号整形变量
    double way = 0,sudu = 0;//定义浮点型数据,way表示高度,sudu表示速度

          uint Hc595SendVal;

   {
  while(1)
   {
   TinyHMI_Scan();
   }
   }
  time=50;
    dianji_r=1;//上电时右侧电机stop
    dianji_l=1;//上电时左侧电机stop
        brake_r =0;
        brake_l =0;
        pwm_r =1;
        pwm_l =1;      
        EA=1;           //CPU总中断允许控制IE
    EX1=1;           //INT1外部中断1允许控制IE
    EX0=1;           //INT1外部中断1允许控制IE
    IT1=1;           //INT1设下降沿触发方式 外部中断1请求标志TCON
    IT0=1;            //INT0设下降沿触发方式 外部中断0请求标志TCON

   HALL_r=1;//置IO为1,准备读取数据
   HALL_l=1;
   _nop_();
   r_count=0;
   l_count=0;

    while(1)
     {
       _nop_();//
           check_right();//调用右边HALL检测传感器
           check_left(); //调用左边HALL检测传感器
                {
                 
         TH1=0x00;
         TL1=0x00;
         sudu=0;            //速度清零

             temp=TH1;
         temp=temp<<8;             //将TH1中数字左移8位再赋给temp
         temp=temp|TL1;      //将TH1和TL1中数据合到一个整形变量temp中            

         way=temp*det_Dist;           //高程存入浮点型变量way中
      while(HALL_r==1);                  //等待0INT变低
             TR0=1;
      while(HALL_r==0);                  //等待0INT变高
      while(HALL_r==1);                  //等待0INT变低
         TR0=0;
         a=TH0;
         a=a<<8;
         a=a||TL1;         a=a*0.001;
         sudu=2/a;
         wap=sudu*10;
        }
      wap=sudu*10; //将速度数据转化为整形,最低位表示十分位,其次为个位,十位   
      tab=way*10;  //将高程数据转化为整形,最低位表示厘米,其次表示分米,米
         
          Hc595SendVal=tab;
          Hc595SendData(Hc595SendVal);

                if(up==0)
                   {
                        dianji_r=0;          //        正转
                        dianji_l=0;          //        正转
               
                            if(sudu==0)
                                   {
                                   brake_r =1;        //刹车
                           brake_l =1;        //刹车
                }                 //堵转保护
                    }                //        正转
            if(down==0);  
                    {
                        dianji_r=1;        //反转
                        dianji_l=1;        //反转
       
                                  if(sudu==0)
                                   {
                                  dianji_r=0; //        正转
                          dianji_l=0; //        正转
                                          if(way==2)          
                                {
                                           brake_r =1;        //刹车
                                   brake_l =1;        //刹车
                                                 
                                           Init_Timer0();
                                    }  //反转堵转变正转2个脉冲,计数器初始化
                         }                 //        反转
             }
        }
}

  void init0int() interrupt 2
  {
       l_count=2;
       dianji_l=1;
       dianji_r=0;
       if(r_count>0)
       {   
               EX0=0;
           delayms(20);
           if(time>=20)time-=19;
           EX0=0;
       }
      return;
   }

  void init1int() interrupt 0
  {
      r_count=2;
     dianji_r=1;          dianji_l=0;
     if(l_count>0)
     { EX1=0;
      delayms(20);
      if(time>=20)time-=19;
      EX1=1;}
     return;  
  }


  //函数名称:
  //功能:左边边时候检测到停止测试程序
void    check_left()
{
    if(HALL_l==0)//检测右边的传感器是否感应到停止
    {
     delay_50us(1);//延时,去除机械振动
     _nop_();
     if(HALL_l==0)//再次检测
       {  
            delay_50us(1);//延时,去除机械振动
           if(HALL_l==0)
                  {
            l_count++;
            HALL_l=1;      
              }
       }
    }
}   
//函数名称:
        //功能:右边时候检测到停止测试程序
void    check_right()
{
if(HALL_r==0)//检测右边的传感器是否感应到停止                          
{
  delay_50us(1);//延时,去除机械振动
  if(HALL_r==0)//再次检测
  {
   delay_50us(1);//延时,去除机械振动                                          
   if(HALL_r==0)
   {
    r_count++;
    HALL_r=1;
   }
  }
}
}

//函数名称:void delay_50US(unsigned int t)
//功能:延时50*t(us)
void delay_50us(uint t)
{
    uchar j;
    for(;t>0;t--)
    {
       for(j=19;j>0;j--);
    }
}

/*==========设定延时时间:x*1ms  =============*/
void delayms(uint Ms)
{
   uint i,TempCyc;
   for(i=0;i<Ms;i++)
   {
     TempCyc =70;
     while(TempCyc--);
   }
}  



void delay2ms(void)
{
   unsigned char i,j;
   for(i=133;i>0;i--)
   for(j=6;j>0;j--);
}

/*void delay(uint i)
{
        while(i--);       
}*/

void h595_in(uchar SendVal)
{
uchar i;
for(i = 0; i < 8; i++)   //循环8次,刚好移完8位
    {
      s11 = 0;        //先将移位寄存器控制引脚SCK(s11)置为低   
      _nop_();
      if((SendVal & 0x80)== 0x80)          //SendVal是没有经过位分离的d14数据。因595先处理最高位,所以用0x80
           d14 =1;  //当0赋i(第1轮for循环),SendVal最高位(第8位)若高电平,则&运算后,d14也为高电平,                                                                  
      else                    //否则,
           d14 =0;  //d14为低电平,1赋i(第2轮for循环)、2赋i(第3轮for循环).....以此类推       
       SendVal <<= 1;      //将数据的次高位移到最高位
       s11 = 1;            //再置为高,产生移位时钟上升沿,上升沿时数据寄存器的数据移位
      _nop_();
    }
}          //串行入

void h595_out(void)
{
      r12 = 0; //先将存储寄存器引脚置为低
      _nop_();
      r12 = 1; //再置为高,产生移位时钟上升沿,上升沿时移位寄存器的数据进入数据存储寄存器,更新显示数据。
}    //并行出

void Hc595SendData(uchar SendVal)
{
uchar i;
  for(i = 0;i < 8;i++)  //有3位数码管,3位依次扫描        余5位按键
   {
     h595_in(duan[i]);  //先传段码?(BLOG图段9-位14脚送序与己同)
     h595_in(wei[i]);   //再传位码,3<=i<8传M1234按键,595轮流输出一个低电平,P2^2已上拉,当检测P2^2脚为低电平时,看595是哪脚输出低电平,得键值
     h595_out();
     delay2ms();        //延迟时间2ms以内
   }
}
/********=====================================================*********/
void TinyHMI_STR(void)
{
r12 =1; //STR开解锁控制字
_nop_();
r12 =0;
}
void TinyHMI_CP(void)
{
s11 =1; //CP方波移位控制字
_nop_();
s11 =0;
}
char delay100us(unsigned int uiDly)
{
unsigned char k;
do{
   k=46;
   do{
     }while (--k!=0);
  }while (--uiDly!=0);
return 0;
}
void TinyHMI_Display(unsigned char Data) //8位串入并出带锁存送数子程序
{
unsigned char i;
for (i=0;i<8;i++)
{
  d14=Data&0x80;
  Data<<=1;
  TinyHMI_CP();
  }
}
void TinyHMI_Show(unsigned i,unsigned j)                // unsigned?
{
TinyHMI_Display(duandp[i+1]);
TinyHMI_Display(~wei[j+1]);
TinyHMI_STR();
delay100us(22);
}
void TinyHMI_Scan(void)
{
  unsigned i;
  for (i=3;i<8;i++)
  {
   TinyHMI_Display(duandp[i]);
   TinyHMI_Display(~wei[i]);
   TinyHMI_STR();
   if(m1234==0)keyvalue=i;
   if(keyvalue==1)TinyHMI_Show(1,0);
   if(keyvalue==2)TinyHMI_Show(2,1);
   if(keyvalue==3)TinyHMI_Show(3,2);
   if(keyvalue==4)TinyHMI_Show(4,3);
   if(keyvalue==5)TinyHMI_Show(5,4);
   if(keyvalue==6)TinyHMI_Show(6,5);
   if(keyvalue==7)TinyHMI_Show(7,6);
   if(keyvalue==8)TinyHMI_Show(8,7);
   delay100us(22);
   }
}



/*for(n=3;n<8;n++) //BG,CF
{
  s11 out;
  Qn = 1;//Qn595某脚
  s11 in;
  if(s11==1) KEYn=1;//KEYn某键
  else       KEYn=0;
  Qn = 0;
}
/*void KeyDown(void)          //M1234按下 PZJZ
{
        char a=0;
        m1234=0;
        if(m1234!=0)//读取按键是否按下(m1234中任一按下,通过d14、CPUP2^2口传595后5位选拉低)
        {
                delay(500);//延时5ms进行消抖
                if(m1234!=0)//再次检测键盘是否按下
                {       
                        m1234=0;
                        switch(P2^2)//不需要如何将P2^2口送出8位串行数据
                        {
                                case(0xf7):        KeyValue=M;break;                 //11110111
                                case(0xef):        KeyValue=O;break;                 //11101111
                                case(0xdf): KeyValue=T;break;                 //11011111
                                case(0xbf):        KeyValue=TRE;break;                 //10111111
                                case(0x7f):        KeyValue=F;break;                 //01111111
                        }
                        while((a<50)&&(m1234!=0))         //检测按键松手检测
                        {
                                delay(1000);
                                a++;
                        }
                }
        }
} */
/*M1234键函*/
/*void Keypros()
{
        if(M==0)
        {
                delay(1000);  //消抖处理
                if(k1==0)
                {
                        At24c02Write(1,num);   //在地址1内写入数据num
                }
                while(!k1);
        }
        if(k2==0)
        {
                delay(1000);  //消抖处理
                if(k2==0)
                {
                        num=At24c02Read(1);          //读取EEPROM地址1内的数据保存在num中
                }
                while(!k2);
        }
        if(k3==0)
        {
                delay(100);  //消抖处理
                if(k3==0)
                {
                        num++;           //数据加1
                        if(num>255)num=0;
                }
                while(!k3);
        }
        if(k4==0)
        {
                delay(1000);  //消抖处理
                if(k4==0)
                {
                        num=0;                 //数据清零
                }
                while(!k4);
        }               
}

/*
if(M==0)//擦除数据(准备写)SMG 闪
                        {        if(O==0)   //写0x2000SMG !闪(&位选)
                                if(T==0)   //写0x2200SMG !闪(&位选)
                                if(TRE==0) //写0x2400SMG !闪(&位选)
                                if(F==0)   //写0x2600SMG !闪(&位选)        }

if(O==0)   //读0x2000SMG 电机转到1位
if(T==0)   //读0x2200SMG 电机转到2位
if(TRE==0) //读0x2400SMG 电机转到3位
if(F==0)   //读0x2600SMG 电机转到4位        } */

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表