久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1892|回復: 0
打印 上一主題 下一主題
收起左側

發表此貼,用以紀念首次實戰,一切都在程序里,直接上干貨,

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

        if(cnt <= 2 )
        {                                                                                  
                bate = 0;
        }
        if(cnt > 2)
        {
                bate = 1;       
        }       
        if(cnt > 4)
        {       
                cnt = 0;
                //Index ++;       
        }
        /*if(Index >= 8)           //用于不用驅動器的時候
                {
                        Index = 0;
                } */
}
void SignalInput()                 //按鍵消抖檢測函數,48ms秒消抖。
{
        static unsigned char StartBuf=0,StopABuf =0,StopBBuf=0  ;//(啟動緩存,A停止緩存,B停止緩存,A之前狀態,B之前狀態)
        StartBuf = (StartBuf<<1) | StartM;                          //通過位移消抖
        if(StartBuf == 0x00 )
        {
                StartMotor = 0;                                                          //確認穩定后,輸出啟動信號
        }
        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應該是誤差,我是
        {       
                EnTimerA = 0;                //關閉計時使能
                EnStartMA = 0;            //延時結束,啟動馬達
        }
        if(tb == 220)
        {       
                EnTimerB = 0;           //關閉計數使能
                EnStartMB = 0;           //延時結束,輸出啟動馬達信號
        }
}
void TurnMotor()                   //電機運轉函數,
{       
        static unsigned int i = 0,e = 0;
        static unsigned char batebufa,batebufb;/*tmp,*/ //上半個脈沖高低電平的緩存,

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

        }
         if(StopBbuf == 0)                                                                // B運轉函數。驅動器用
        {                
                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;
                }
        }

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



評分

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

查看全部評分

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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产免费一级片 | 欧美一区二区三区在线视频 | 一区二区三区四区不卡视频 | 久久精品中文字幕 | 蜜桃视频成人 | 99热精品6 | 国产人成精品一区二区三 | 欧美亚洲国产一区 | 成人综合在线视频 | 久久久91 | 午夜电影福利 | 成人免费小视频 | 亚洲国产一区二区三区, | 蜜臀av日日欢夜夜爽一区 | 在线观看av网站 | 久精品久久 | 性生生活大片免费看视频 | 亚洲黄色一级毛片 | 91色在线视频 | 精品国产乱码久久久久久影片 | 日韩一区二区三区四区五区 | 亚洲第一在线视频 | 午夜免费观看网站 | 成人欧美日韩一区二区三区 | 成人午夜毛片 | 精品亚洲一区二区 | av天天干 | 成人毛片在线视频 | 亚洲97 | 亚洲精品视频观看 | 国产精品99久久久久久久久久久久 | 黄色福利 | 色网站视频 | 女女百合av大片一区二区三区九县 | 99久久精品免费看国产高清 | 欧美一级欧美三级在线观看 | 网站国产 | 国产在线精品一区 | 看av网址 | 欧美国产日韩在线 | www国产亚洲精品久久网站 |