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