標(biāo)題: 51單片機(jī)的計數(shù)器問題,電機(jī)圈數(shù)怎么達(dá)不到停止條件? [打印本頁]

作者: niejiangong    時間: 2022-5-23 18:51
標(biāo)題: 51單片機(jī)的計數(shù)器問題,電機(jī)圈數(shù)怎么達(dá)不到停止條件?
通過T0計數(shù)器對減速直流電機(jī)軸的轉(zhuǎn)動圈數(shù)進(jìn)行累計(直流電機(jī)帶有編碼器),轉(zhuǎn)到一定圈數(shù)后讓電機(jī)停止,但不知道為什么,程序運行后,電機(jī)一直轉(zhuǎn),不會停,不知道為什么?求大俠們幫忙指點指點:

單片機(jī)源程序如下:
#include "reg52.h"

typedef unsigned int u16;        //對系統(tǒng)默認(rèn)數(shù)據(jù)類型進(jìn)行重定義
typedef unsigned char u8;

sbit MOTOR1_A=P0^0;          //直流電機(jī)的正極
sbit MOTOR1_B=P0^1;          //直流電機(jī)的負(fù)極

u16 s1=10;                //設(shè)定電機(jī)旋轉(zhuǎn)圈數(shù)
u16 count=0;               //電機(jī)圈數(shù)

/*******************************************************************************
* 函 數(shù) 名       : delay_ms
* 函數(shù)功能                 : ms延時函數(shù),ms=1時,大約延時1ms
* 輸    入       : ten_us
* 輸    出             : 無
*******************************************************************************/
void delay_ms(u16 ms)
{
        u16 i,j;
        for(i=ms;i>0;i--)
                for(j=110;j>0;j--);
}

/*******************************************************************************
* 函 數(shù) 名       : time0_init
* 函數(shù)功能       : 定時器0中斷配置函數(shù),通過設(shè)置TH和TL即可確定計數(shù)值
* 輸    入       : 無
* 輸    出       : 無
*******************************************************************************/

void counter0_init(void)
{
        TMOD|=0X05;                //選擇為計數(shù)器0模式,工作方式1
        TH0=0xFC;                  //電機(jī)編碼器867個脈沖,減速器軸轉(zhuǎn)一圈,初值設(shè)置為FC9D
        TL0=0x9D;      
        TF0=0;
        TR0=1;        //打開計數(shù)器
        ET0=1;        //打開計數(shù)器0中斷允許
        EA=1;        //打開總中斷
}

/*******************************************************************************
* 函 數(shù) 名       : contor0
* 函數(shù)功能       : 定時器0中斷函數(shù),通過設(shè)置TH和TL即可確定計數(shù)值,并對減速器軸圈數(shù)進(jìn)行累加
* 輸    入       : 無
* 輸    出       : 無
*******************************************************************************/

void conter0() interrupt 1 //定時器0中斷函數(shù)
{
        TH0=0xfC;        //給計數(shù)器賦初值
        TL0=0x9D;
        count++;                 //對電機(jī)轉(zhuǎn)動圈數(shù)進(jìn)行累加
}


/*******************************************************************************
* 函 數(shù) 名       : main
* 函數(shù)功能       : 主函數(shù)
* 輸    入       : 無
* 輸    出       : 無
*******************************************************************************/
void main()
{      
        u16 k;                                //緩沖變量
        k=count;      

        counter0_init();        //計數(shù)器0中斷配置

        MOTOR1_A=1;                   //直流電機(jī)開始正轉(zhuǎn)
        MOTOR1_B=0;
        do
        {
                ;
        }
        while(k<s1);                  //檢測編碼器計數(shù)是否達(dá)到設(shè)定值s1
        TR0=0;                                //計數(shù)器停止計數(shù)
        MOTOR1_A=1;                            //電機(jī)停止
        MOTOR1_B=1;
        delay_ms(5000);         
}

作者: glinfei    時間: 2022-5-24 09:13
1、把while(k<s1);    改成while(count<s1); 2、把 delay_ms(5000);  改成while(1);3、  另外電機(jī)停止應(yīng)該都置低位吧。
作者: 興安xa    時間: 2022-5-24 10:51
信號線接好,這樣改一下,如果還不行就用最下面的方法先試一下
    MOTOR1_A=1;                   //直流電機(jī)開始正轉(zhuǎn)
    MOTOR1_B=0;
        while(1)
        {
                if(k>s1)  
                {                //檢測編碼器計數(shù)是否達(dá)到設(shè)定值s1
                        TR0=0;                                //計數(shù)器停止計數(shù)
                        MOTOR1_A=0;                            //電機(jī)停止
                        MOTOR1_B=0;
                        delay_ms(5000);
                }
        }

另一種試驗
#include "reg52.h"

typedef unsigned int u16;        //對系統(tǒng)默認(rèn)數(shù)據(jù)類型進(jìn)行重定義
typedef unsigned char u8;

sbit MOTOR1_A=P0^0;          //直流電機(jī)的正極
sbit MOTOR1_B=P0^1;          //直流電機(jī)的負(fù)極

u16 s1=10;                //設(shè)定電機(jī)旋轉(zhuǎn)圈數(shù)
//u16 count=0;               //電機(jī)圈數(shù)



void counter0_init(void)
{
    TMOD|=0X05;                //選擇為計數(shù)器0模式,工作方式1
    TH0=0xFF;                  //電機(jī)編碼器867個脈沖,減速器軸轉(zhuǎn)一圈,初值設(shè)置為FC9D
    TL0=0xF5;      
    TF0=0;
    TR0=1;        //打開計數(shù)器
    ET0=1;        //打開計數(shù)器0中斷允許
    EA=1;        //打開總中斷
}
main()
{
        counter0_init();
    MOTOR1_A=1;                   //直流電機(jī)開始正轉(zhuǎn)
    MOTOR1_B=0;
        while(1);
}


void conter0() interrupt 1 //定時器0中斷函數(shù)
{
    TH0=0xFF;        //給計數(shù)器賦初值
    TL0=0xF5;
    MOTOR1_A=0;                            //電機(jī)停止
        MOTOR1_B=0;               //對電機(jī)轉(zhuǎn)動圈數(shù)進(jìn)行累加
}

作者: 興安xa    時間: 2022-5-24 11:21
下面的方法  
TH0=0xFC;        //計數(shù)器賦初值,和初值設(shè)置,用這個初值只能轉(zhuǎn)一轉(zhuǎn)
TL0=0x9D;
TH0=0xDE;        //計數(shù)器賦初值,和初值設(shè)置,用這個初值轉(zhuǎn)十轉(zhuǎn)
TL0=0x22;
作者: hzhehe    時間: 2022-5-24 11:39
我覺得樓主的主要問題在于k=count沒有附上導(dǎo)致do while沒有辦法跳出,count已為全局變量,所以無需緩沖也可以用于判斷,另外主函數(shù)不帶while的話應(yīng)該不會重復(fù)跑把,可以的話還是加一個大循環(huán),通過大循環(huán)來保持mcu的持續(xù)運行
作者: niejiangong    時間: 2022-5-24 11:52
glinfei 發(fā)表于 2022-5-24 09:13
1、把while(k

1,改成cuont<s1解決問題,k只在開始時等于了count,后面就失去作用了
2,改成while(1)可以一直停止下去,用delay_ms(5000)停止5秒又繼續(xù)轉(zhuǎn)了,在此我不明白,main主程序執(zhí)行完了還會從頭開始再來嗎?
3,主要我用了個直流電機(jī)驅(qū)動模塊,真值表上說都置高位是剎車,也可以停止
作者: niejiangong    時間: 2022-5-24 11:54
興安xa 發(fā)表于 2022-5-24 11:21
下面的方法  
TH0=0xFC;        //計數(shù)器賦初值,和初值設(shè)置,用這個初值只能轉(zhuǎn)一轉(zhuǎn)
TL0=0x9D;

一轉(zhuǎn)的控制精度高些,10轉(zhuǎn)走的太遠(yuǎn)了
作者: glinfei    時間: 2022-5-24 14:51
niejiangong 發(fā)表于 2022-5-24 11:52
1,改成cuont

嵌入系統(tǒng)主程序是不能返回的,結(jié)果不可測,我覺得沒必要研究究竟會跑飛還是軟啟動,因為這要看編譯器和芯片設(shè)計情況。
兩個高位沒有剎車作用,短路兩極才剎車。我不大習(xí)慣程序結(jié)束了還置高位。




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1