找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1924|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

發(fā)表此貼,用以紀(jì)念首次實戰(zhàn),一切都在程序里,直接上干貨,

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:598994 發(fā)表于 2019-9-7 00:28 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
單詞量比較少,有時候需要變量名的時候真的是捉襟見肘!
程序是在邏輯分析儀輔助下反復(fù)修改完成的,節(jié)省了大量時間,再次感謝下這30塊不到的神器!
指針還不會用,目前就這個水平了,自己的目前主業(yè)不是程序員,但希望這可以成為主業(yè)!
以下程序還望大師多多指教!
/*        程序要求:
                 1:控制兩個兩相步進(jìn)電機(jī)A,B運(yùn)轉(zhuǎn);
                 2:轉(zhuǎn)的時候要做到可以不共同開始,停的時候以各自的停止信號為準(zhǔn)
                 3:有運(yùn)轉(zhuǎn)信號輸入的時候要立馬切斷,上一周期的運(yùn)轉(zhuǎn)完成信號
                 4:在啟動的時候馬達(dá)會先轉(zhuǎn)動一定的角度,避開檢測開關(guān)的范圍,之后才開始檢測是否到位。
*/
#include <STC89C5xRC.H>
sbit StartM = P1^0;                        //開始運(yùn)轉(zhuǎn)信號
sbit StopA = P1^4;                        //A停止信號
sbit StopB = P1^6;                        //B停止信號
sbit TurnB = P2^4;                        //B馬達(dá)脈沖輸出          板子線路都焊死了懶得再改板子,就改程序了
sbit TurnA = P2^6;                        //A馬達(dá)運(yùn)轉(zhuǎn)脈沖輸出
sbit OK = P2^0;                                //兩個電機(jī)都到位之后輸出信號
sbit LED = P2^2;                        //程序運(yùn)轉(zhuǎn)指示燈
bit EnTimerA = 0,EnTimerB = 0;                 //電機(jī)延時開始計數(shù)使能
bit EnStartMA = 1, EnStartMB = 1;         //電機(jī)延時結(jié)束輸出位
unsigned int ta = 0 ,tb = 0,i = 0,n = 0;//電機(jī)延時指令計數(shù)變量ta,tb;i是掃描消抖變量,n是指示燈變量
//unsigned char Index = 0;    //電機(jī)當(dāng)前脈沖相位,用于不使用驅(qū)動器
//unsigned char BateCode[]={0x08,0x0a,0x02,0x06,0x04,0x05,0x1,0x09};        //不使用驅(qū)動器,步進(jìn)電機(jī)電機(jī)運(yùn)轉(zhuǎn)參數(shù)
unsigned char StartMotor = 1, StopAMotor = 1,StopBMotor = 1,bate = 0,StartMotorbuf = 1;//啟動,A停止,B停止,節(jié)拍,啟動緩存
unsigned char StopAbuf = 0,StopBbuf = 0, KA = 1,KB = 1;//記錄電機(jī)是否到位緩存 和一些變量
void SignalInput();                        //信號消抖輸出函數(shù)(使用是位移消抖)
void TurnMotor();                        //馬達(dá)運(yùn)轉(zhuǎn)函數(shù),因為不需要倒轉(zhuǎn),所以么有添加倒轉(zhuǎn)功能
void InitTimer0();                        //啟動定時器0;開啟中斷2ms定時
void BeatMotor();           //電機(jī)脈沖節(jié)拍,可以在此處調(diào)節(jié)脈沖寬度
void DelayStartMotor();                //電機(jī)啟動延時函數(shù)
void main(void)
{
        P0 = 0xff;                                                          //初始化,各數(shù)位置1
        P1 = 0xff;
        P3 = 0xff;
        P2 = 0xff;
        InitTimer0();                                          //初始化定時器
        while(1)
        {
                if(n >= 250)                                          //運(yùn)轉(zhuǎn)指示燈變量
                {
                        n = 0;       
                        LED = !LED;
                }
       
        }       
}
void InitTimer0()        //啟動T0,初始化
{
    TMOD = 0x01;
    TH0 = 0xf8;
    TL0 = 0xd0;
    EA = 1;
    ET0 = 1;
    TR0 = 1;
}
void BeatMotor()                   //節(jié)拍器.到時間后輸出計時置位信號,此處可以調(diào)速,調(diào)脈沖占空比等參數(shù)
{
        static unsigned char cnt = 0; //節(jié)拍器計時
        cnt ++;

        if(cnt <= 2 )
        {                                                                                  
                bate = 0;
        }
        if(cnt > 2)
        {
                bate = 1;       
        }       
        if(cnt > 4)
        {       
                cnt = 0;
                //Index ++;       
        }
        /*if(Index >= 8)           //用于不用驅(qū)動器的時候
                {
                        Index = 0;
                } */
}
void SignalInput()                 //按鍵消抖檢測函數(shù),48ms秒消抖。
{
        static unsigned char StartBuf=0,StopABuf =0,StopBBuf=0  ;//(啟動緩存,A停止緩存,B停止緩存,A之前狀態(tài),B之前狀態(tài))
        StartBuf = (StartBuf<<1) | StartM;                          //通過位移消抖
        if(StartBuf == 0x00 )
        {
                StartMotor = 0;                                                          //確認(rèn)穩(wěn)定后,輸出啟動信號
        }
        else StartMotor = 1;                                                  //信號必須敏感,不是0就是1。而且要及時變動
        StopABuf = (StopABuf<<1) | StopA;
        if(StopABuf == 0)
        {
                StopAMotor = 0;                                                          //輸出A停止信號
        }
        else StopAMotor = 1;
        StopBBuf = (StopBBuf<<1) | StopB;
        if(StopBBuf == 0)
        {
                StopBMotor = 0;                                                          //輸出B停止信號,0代表停止
        }
        else StopBMotor = 1;
}
void DelayStartMotor()
{
        if(ta == 220)                   //200*2ms = 400ms = 0.4s;實測0.44s應(yīng)該是誤差,我是
        {       
                EnTimerA = 0;                //關(guān)閉計時使能
                EnStartMA = 0;            //延時結(jié)束,啟動馬達(dá)
        }
        if(tb == 220)
        {       
                EnTimerB = 0;           //關(guān)閉計數(shù)使能
                EnStartMB = 0;           //延時結(jié)束,輸出啟動馬達(dá)信號
        }
}
void TurnMotor()                   //電機(jī)運(yùn)轉(zhuǎn)函數(shù),
{       
        static unsigned int i = 0,e = 0;
        static unsigned char batebufa,batebufb;/*tmp,*/ //上半個脈沖高低電平的緩存,

        if(StartMotorbuf != StartMotor)                                        //對比電機(jī)運(yùn)轉(zhuǎn)使能信號是否發(fā)生變化
        {                                                                                                //有變化就說明本次周期結(jié)束,將電機(jī)電機(jī)轉(zhuǎn)到位的信號緩存清零
                StopAbuf = 0;
                StopBbuf = 0;
        }
        if(StopAbuf == 0)                                                                 //A電機(jī)無轉(zhuǎn)到位信號的時候才允許運(yùn)轉(zhuǎn)
        {
                 if(StartMotor == 0)                                                        //檢測運(yùn)轉(zhuǎn)使能,有運(yùn)轉(zhuǎn)使能的時候
                {                                                                                
                        EnTimerA = 1;                                                        //打開延時計數(shù)器使能,ta 開始計
                        if(EnStartMA == 0)                                                //當(dāng)延時器時間到后輸出信號。0
                        {
                                if(batebufa != bate)                                //當(dāng)電平值不等于上一個值的時候
                                {
                                        TurnA = bate;                                        //A電機(jī)運(yùn)轉(zhuǎn)
                                        i ++;                                                     //脈沖計數(shù)加1
                                        KA = 0;                                                        //再次清零 運(yùn)轉(zhuǎn)完時成輸出信號的 緩存數(shù)據(jù)
                                        batebufa = bate;                                //保存上一個電平值,用來做對比;
                                }
                                                                                        
                                if(i >= 250)                                                                 //先走一定的步數(shù),保證離開檢測開關(guān)的檢測范圍
                                {
                                   if((StopAMotor || StartMotor) == 0)                 //要求必須一直給運(yùn)轉(zhuǎn)使能,能允許輸出轉(zhuǎn)到位信號
                                   {
                                                   i = 0;                                                                   //脈沖計數(shù)清零
                                                StopAbuf = 1;                                                 //A轉(zhuǎn)到位的信號緩存;
                                                KA = 1;                                                                //輸出A到位
                                                EnStartMA = 1;                                                //關(guān)閉延時函數(shù)給的電機(jī)運(yùn)轉(zhuǎn)使能 ,等待下一周期
                                                StartMotorbuf = StartMotor;                    //將啟動使能信號另外保存,用以判斷該信號是否有變化
                                   }
                                }
                           }
                }
                else
                {
                        EnTimerA = 0;                                                                         //當(dāng)使能信號有低到高發(fā)生變化之后,并且沒有運(yùn)轉(zhuǎn)使能輸進(jìn)來
                        ta = 0;                                                                                         //的時候,將不開始運(yùn)轉(zhuǎn)延時的計時,并清零延時用的變量
                }

        }
         if(StopBbuf == 0)                                                                // B運(yùn)轉(zhuǎn)函數(shù)。驅(qū)動器用
        {                
                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;
                }
        }

        /*         這個函數(shù)是沒用步進(jìn)電機(jī)驅(qū)動器,直接用單片機(jī)發(fā)數(shù)據(jù);后來買了步進(jìn)電機(jī)驅(qū)動器之后,只需要發(fā)脈沖。
        這段就不需要了,這是個兩相四線的步進(jìn)電機(jī)驅(qū)動函數(shù)但是后面用驅(qū)動器之后就沒給這個函數(shù)再做修改了;
        if(StopBbuf == 0)                                                        // B運(yùn)轉(zhuǎn)函數(shù)。驅(qū)動板函數(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)到位的信號;
                                        StartMotorbuf = StartMotor;
                           }
                        }
                }
        } */
        if (KA && KB)                                   //兩個電機(jī)都到位的時候輸出到信號供機(jī)械手使用。
        {                                                        //延時使能清零
                OK = 0;                                                                        //輸出點(diǎn)P1.0
        }
        else OK = 1;
}
void Timer0Interrupt(void) interrupt 1
{       
        TH0 = 0xf9;                        //定時2ms初值
    TL0 = 0x29;
        BeatMotor();                 //節(jié)拍函數(shù)
        i ++;
        if(i == 3)
        {
                i = 0;
                SignalInput();        //信號輸入消抖函數(shù),消抖時間理論48ms,實測50ms,具體原因:沒查,但可能不是誤差
        }
        if(EnTimerA == 1)        //運(yùn)轉(zhuǎn)信號輸入后,電機(jī)延時運(yùn)轉(zhuǎn)計時使能
        {
                ta ++;                        //計時變量
                if(ta < 2)                //這個判斷的作用是:運(yùn)轉(zhuǎn)信號輸入后直接將電機(jī)到位信號切斷,而不是到延時結(jié)束時再切斷
                {                                //目的是為了避免重復(fù)將 K1 置 0 ;
                        KA = 0;                //
                }
        }
        if(EnTimerB == 1)        //同A電機(jī)
        {               
                tb ++;
                if(tb < 2)
                {
                        KB = 0;
                }       
        }
        DelayStartMotor(); //一個延時函數(shù),可以分別調(diào)節(jié)兩個電機(jī)的起始運(yùn)轉(zhuǎn)延時
        n ++;                           //程序運(yùn)轉(zhuǎn)指示燈變量
        TurnMotor();           //電機(jī)運(yùn)轉(zhuǎn)程序
}



評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏3 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表