|
單詞量比較少,有時(shí)候需要變量名的時(shí)候真的是捉襟見(jiàn)肘 !
程序是在邏輯分析儀輔助下反復(fù)修改完成的,節(jié)省了大量時(shí)間,再次感謝下這30塊不到的神器!
指針還不會(huì)用,目前就這個(gè)水平了,自己的目前主業(yè)不是程序員,但希望這可以成為主業(yè)!
以下程序還望大師多多指教!
/* 程序要求:
1:控制兩個(gè)兩相步進(jìn)電機(jī)A,B運(yùn)轉(zhuǎn);
2:轉(zhuǎn)的時(shí)候要做到可以不共同開(kāi)始,停的時(shí)候以各自的停止信號(hào)為準(zhǔn)
3:有運(yùn)轉(zhuǎn)信號(hào)輸入的時(shí)候要立馬切斷,上一周期的運(yùn)轉(zhuǎn)完成信號(hào)
4:在啟動(dòng)的時(shí)候馬達(dá)會(huì)先轉(zhuǎn)動(dòng)一定的角度,避開(kāi)檢測(cè)開(kāi)關(guān)的范圍,之后才開(kāi)始檢測(cè)是否到位。
*/
#include <STC89C5xRC.H>
sbit StartM = P1^0; //開(kāi)始運(yùn)轉(zhuǎn)信號(hào)
sbit StopA = P1^4; //A停止信號(hào)
sbit StopB = P1^6; //B停止信號(hào)
sbit TurnB = P2^4; //B馬達(dá)脈沖輸出 板子線路都焊死了懶得再改板子,就改程序了
sbit TurnA = P2^6; //A馬達(dá)運(yùn)轉(zhuǎn)脈沖輸出
sbit OK = P2^0; //兩個(gè)電機(jī)都到位之后輸出信號(hào)
sbit LED = P2^2; //程序運(yùn)轉(zhuǎn)指示燈
bit EnTimerA = 0,EnTimerB = 0; //電機(jī)延時(shí)開(kāi)始計(jì)數(shù)使能
bit EnStartMA = 1, EnStartMB = 1; //電機(jī)延時(shí)結(jié)束輸出位
unsigned int ta = 0 ,tb = 0,i = 0,n = 0;//電機(jī)延時(shí)指令計(jì)數(shù)變量ta,tb;i是掃描消抖變量,n是指示燈變量
//unsigned char Index = 0; //電機(jī)當(dāng)前脈沖相位,用于不使用驅(qū)動(dòng)器
//unsigned char BateCode[]={0x08,0x0a,0x02,0x06,0x04,0x05,0x1,0x09}; //不使用驅(qū)動(dòng)器,步進(jìn)電機(jī)電機(jī)運(yùn)轉(zhuǎn)參數(shù)
unsigned char StartMotor = 1, StopAMotor = 1,StopBMotor = 1,bate = 0,StartMotorbuf = 1;//啟動(dòng),A停止,B停止,節(jié)拍,啟動(dòng)緩存
unsigned char StopAbuf = 0,StopBbuf = 0, KA = 1,KB = 1;//記錄電機(jī)是否到位緩存 和一些變量
void SignalInput(); //信號(hào)消抖輸出函數(shù)(使用是位移消抖)
void TurnMotor(); //馬達(dá)運(yùn)轉(zhuǎn)函數(shù),因?yàn)椴恍枰罐D(zhuǎn),所以么有添加倒轉(zhuǎn)功能
void InitTimer0(); //啟動(dòng)定時(shí)器0;開(kāi)啟中斷2ms定時(shí)
void BeatMotor(); //電機(jī)脈沖節(jié)拍,可以在此處調(diào)節(jié)脈沖寬度
void DelayStartMotor(); //電機(jī)啟動(dòng)延時(shí)函數(shù)
void main(void)
{
P0 = 0xff; //初始化,各數(shù)位置1
P1 = 0xff;
P3 = 0xff;
P2 = 0xff;
InitTimer0(); //初始化定時(shí)器
while(1)
{
if(n >= 250) //運(yùn)轉(zhuǎn)指示燈變量
{
n = 0;
LED = !LED;
}
}
}
void InitTimer0() //啟動(dòng)T0,初始化
{
TMOD = 0x01;
TH0 = 0xf8;
TL0 = 0xd0;
EA = 1;
ET0 = 1;
TR0 = 1;
}
void BeatMotor() //節(jié)拍器.到時(shí)間后輸出計(jì)時(shí)置位信號(hào),此處可以調(diào)速,調(diào)脈沖占空比等參數(shù)
{
static unsigned char cnt = 0; //節(jié)拍器計(jì)時(shí)
cnt ++;
if(cnt <= 2 )
{
bate = 0;
}
if(cnt > 2)
{
bate = 1;
}
if(cnt > 4)
{
cnt = 0;
//Index ++;
}
/*if(Index >= 8) //用于不用驅(qū)動(dòng)器的時(shí)候
{
Index = 0;
} */
}
void SignalInput() //按鍵消抖檢測(cè)函數(shù),48ms秒消抖。
{
static unsigned char StartBuf=0,StopABuf =0,StopBBuf=0 ;//(啟動(dòng)緩存,A停止緩存,B停止緩存,A之前狀態(tài),B之前狀態(tài))
StartBuf = (StartBuf<<1) | StartM; //通過(guò)位移消抖
if(StartBuf == 0x00 )
{
StartMotor = 0; //確認(rèn)穩(wěn)定后,輸出啟動(dòng)信號(hào)
}
else StartMotor = 1; //信號(hào)必須敏感,不是0就是1。而且要及時(shí)變動(dòng)
StopABuf = (StopABuf<<1) | StopA;
if(StopABuf == 0)
{
StopAMotor = 0; //輸出A停止信號(hào)
}
else StopAMotor = 1;
StopBBuf = (StopBBuf<<1) | StopB;
if(StopBBuf == 0)
{
StopBMotor = 0; //輸出B停止信號(hào),0代表停止
}
else StopBMotor = 1;
}
void DelayStartMotor()
{
if(ta == 220) //200*2ms = 400ms = 0.4s;實(shí)測(cè)0.44s應(yīng)該是誤差,我是
{
EnTimerA = 0; //關(guān)閉計(jì)時(shí)使能
EnStartMA = 0; //延時(shí)結(jié)束,啟動(dòng)馬達(dá)
}
if(tb == 220)
{
EnTimerB = 0; //關(guān)閉計(jì)數(shù)使能
EnStartMB = 0; //延時(shí)結(jié)束,輸出啟動(dòng)馬達(dá)信號(hào)
}
}
void TurnMotor() //電機(jī)運(yùn)轉(zhuǎn)函數(shù),
{
static unsigned int i = 0,e = 0;
static unsigned char batebufa,batebufb;/*tmp,*/ //上半個(gè)脈沖高低電平的緩存,
if(StartMotorbuf != StartMotor) //對(duì)比電機(jī)運(yùn)轉(zhuǎn)使能信號(hào)是否發(fā)生變化
{ //有變化就說(shuō)明本次周期結(jié)束,將電機(jī)電機(jī)轉(zhuǎn)到位的信號(hào)緩存清零
StopAbuf = 0;
StopBbuf = 0;
}
if(StopAbuf == 0) //A電機(jī)無(wú)轉(zhuǎn)到位信號(hào)的時(shí)候才允許運(yùn)轉(zhuǎn)
{
if(StartMotor == 0) //檢測(cè)運(yùn)轉(zhuǎn)使能,有運(yùn)轉(zhuǎn)使能的時(shí)候
{
EnTimerA = 1; //打開(kāi)延時(shí)計(jì)數(shù)器使能,ta 開(kāi)始計(jì)
if(EnStartMA == 0) //當(dāng)延時(shí)器時(shí)間到后輸出信號(hào)。0
{
if(batebufa != bate) //當(dāng)電平值不等于上一個(gè)值的時(shí)候
{
TurnA = bate; //A電機(jī)運(yùn)轉(zhuǎn)
i ++; //脈沖計(jì)數(shù)加1
KA = 0; //再次清零 運(yùn)轉(zhuǎn)完時(shí)成輸出信號(hào)的 緩存數(shù)據(jù)
batebufa = bate; //保存上一個(gè)電平值,用來(lái)做對(duì)比;
}
if(i >= 250) //先走一定的步數(shù),保證離開(kāi)檢測(cè)開(kāi)關(guān)的檢測(cè)范圍
{
if((StopAMotor || StartMotor) == 0) //要求必須一直給運(yùn)轉(zhuǎn)使能,能允許輸出轉(zhuǎn)到位信號(hào)
{
i = 0; //脈沖計(jì)數(shù)清零
StopAbuf = 1; //A轉(zhuǎn)到位的信號(hào)緩存;
KA = 1; //輸出A到位
EnStartMA = 1; //關(guān)閉延時(shí)函數(shù)給的電機(jī)運(yùn)轉(zhuǎn)使能 ,等待下一周期
StartMotorbuf = StartMotor; //將啟動(dòng)使能信號(hào)另外保存,用以判斷該信號(hào)是否有變化
}
}
}
}
else
{
EnTimerA = 0; //當(dāng)使能信號(hào)有低到高發(fā)生變化之后,并且沒(méi)有運(yùn)轉(zhuǎn)使能輸進(jìn)來(lái)
ta = 0; //的時(shí)候,將不開(kāi)始運(yùn)轉(zhuǎn)延時(shí)的計(jì)時(shí),并清零延時(shí)用的變量
}
}
if(StopBbuf == 0) // B運(yùn)轉(zhuǎn)函數(shù)。驅(qū)動(dòng)器用
{
if(StartMotor == 0)
{
EnTimerB = 1;
if(EnStartMB == 0)
{
if(batebufb != bate)
{
TurnB = bate;
KB = 0;
e ++;
}
batebufb = bate;
if(e >= 250)
{
if((StopBMotor || StartMotor) == 0)
{
e = 0;
StopBbuf = 1;
KB = 1;
EnStartMB = 1;
StartMotorbuf = StartMotor;
}
}
}
}
else
{
EnTimerB = 0;
tb = 0;
}
}
/* 這個(gè)函數(shù)是沒(méi)用步進(jìn)電機(jī)驅(qū)動(dòng)器,直接用單片機(jī)發(fā)數(shù)據(jù);后來(lái)買(mǎi)了步進(jìn)電機(jī)驅(qū)動(dòng)器之后,只需要發(fā)脈沖。
這段就不需要了,這是個(gè)兩相四線的步進(jìn)電機(jī)驅(qū)動(dòng)函數(shù)但是后面用驅(qū)動(dòng)器之后就沒(méi)給這個(gè)函數(shù)再做修改了;
if(StopBbuf == 0) // B運(yùn)轉(zhuǎn)函數(shù)。驅(qū)動(dòng)板函數(shù)。
{
if(StartMotor == 0)
{
if(BateCode[Index] != tmp)
{
n ++;
} ;
tmp = BateCode[Index];
P2 = tmp;
if(n >= 25)
{
if((StopBMotor || StartMotor) == 0)
{
n = 0;
StopBbuf = 1; //B轉(zhuǎn)到位的信號(hào);
StartMotorbuf = StartMotor;
}
}
}
} */
if (KA && KB) //兩個(gè)電機(jī)都到位的時(shí)候輸出到信號(hào)供機(jī)械手使用。
{ //延時(shí)使能清零
OK = 0; //輸出點(diǎn)P1.0
}
else OK = 1;
}
void Timer0Interrupt(void) interrupt 1
{
TH0 = 0xf9; //定時(shí)2ms初值
TL0 = 0x29;
BeatMotor(); //節(jié)拍函數(shù)
i ++;
if(i == 3)
{
i = 0;
SignalInput(); //信號(hào)輸入消抖函數(shù),消抖時(shí)間理論48ms,實(shí)測(cè)50ms,具體原因:沒(méi)查,但可能不是誤差
}
if(EnTimerA == 1) //運(yùn)轉(zhuǎn)信號(hào)輸入后,電機(jī)延時(shí)運(yùn)轉(zhuǎn)計(jì)時(shí)使能
{
ta ++; //計(jì)時(shí)變量
if(ta < 2) //這個(gè)判斷的作用是:運(yùn)轉(zhuǎn)信號(hào)輸入后直接將電機(jī)到位信號(hào)切斷,而不是到延時(shí)結(jié)束時(shí)再切斷
{ //目的是為了避免重復(fù)將 K1 置 0 ;
KA = 0; //
}
}
if(EnTimerB == 1) //同A電機(jī)
{
tb ++;
if(tb < 2)
{
KB = 0;
}
}
DelayStartMotor(); //一個(gè)延時(shí)函數(shù),可以分別調(diào)節(jié)兩個(gè)電機(jī)的起始運(yùn)轉(zhuǎn)延時(shí)
n ++; //程序運(yùn)轉(zhuǎn)指示燈變量
TurnMotor(); //電機(jī)運(yùn)轉(zhuǎn)程序
}
51hei圖片_20190907002637.jpg (807.79 KB, 下載次數(shù): 74)
下載附件
該程序最終的運(yùn)行的波形圖
2019-9-7 00:26 上傳
|
評(píng)分
-
查看全部評(píng)分
|