#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位 } */
|