欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

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

請(qǐng)教AT89S52單片機(jī)的數(shù)碼管顯示問(wèn)題 定時(shí)器中斷程序分析

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:709154 發(fā)表于 2020-3-15 23:51 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
新手剛起步,有點(diǎn)搞不懂定時(shí)器中斷函數(shù)的運(yùn)行時(shí)刻,我想把超聲波測(cè)量的距離放在數(shù)碼管中顯示,于是在中斷函數(shù)中加入了掃描數(shù)碼管函數(shù),但是在實(shí)際運(yùn)行中出現(xiàn)了數(shù)值跳動(dòng)緩慢,大概15s才跳動(dòng)一下,而且我的小車輪子轉(zhuǎn)速也會(huì)出現(xiàn)大概15s會(huì)停一下(測(cè)試過(guò)如果不把掃描數(shù)碼管放在定時(shí)器中斷函數(shù)就不會(huì)有這種情況)于是我又想我寫在主函數(shù)中,但是多次嘗試,發(fā)現(xiàn)寫在主函數(shù)中雖然數(shù)字跳動(dòng)很快,但是無(wú)論我怎么寫都只顯示最后數(shù)碼管第三位,我想要的是顯示三位數(shù)。以下是我正在改寫的代碼

單片機(jī)源程序如下:
#include <reg52.h>//51頭文件
#include <intrins.h>   //包含nop等系統(tǒng)函數(shù)
#include <config.h>//配置文件


sbit RX = P2^0;//ECHO超聲波模塊回響端
sbit TX = P2^1;//TRIG超聲波模塊觸發(fā)端
sbit DU =P2^6;
sbit WE =P2^7;
unsigned int  timer=0;
unsigned char posit=0;
unsigned char const discode[] ={ 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,0x6F,0x40,0x00};   //數(shù)碼管段選碼
unsigned char const positon[3]={ 0xfe,0xfd,0xfb};        //數(shù)碼管位選碼
unsigned char disbuff[4 ]           ={ 0,0,0,0,};

unsigned char pwm_left_val = 210;//左電機(jī)占空比值 取值范圍0-170,0最快
unsigned char pwm_right_val = 210;//右電機(jī)占空比值取值范圍0-170 ,0最快
unsigned char pwm_t;//周期
unsigned int  time = 0;//傳輸時(shí)間
unsigned long S = 0;//距離
bit      flag = 0;//超出測(cè)量范圍標(biāo)志位


/*掃描數(shù)碼管*/
void Display1(void)                                 //掃描數(shù)碼管
{
        DU = 0;                                                        //關(guān)閉段 選
         P0=(discode[disbuff[0]])|0x80; //或上0x80是為了添加小數(shù)點(diǎn)
         DU = 1;                                                //開啟段選,段選值送過(guò)去了
         DU = 0;                                                //關(guān)閉段選
         WE = 0;                                                //關(guān)閉位選
          P0=positon[0];
          WE=1;
          WE=0;
}

void Display2(void)                                 //掃描數(shù)碼管
{
         DU = 0;                                                        //關(guān)閉段 選
         P0=discode[disbuff[1]];
         DU = 1;                                                //開啟段選,段選值送過(guò)去了
         DU = 0;                                                //關(guān)閉段選
         WE = 0;                                                //關(guān)閉位選
          P0=positon[1];
          WE=1;
          WE=0;        
}

void Display3(void)                                 //掃描數(shù)碼管
{
         DU = 0;                                                        //關(guān)閉段 選
         P0=discode[disbuff[2]];
         DU = 1;                                                //開啟段選,段選值送過(guò)去了
         DU = 0;                                                //關(guān)閉段選
         WE = 0;                                                //關(guān)閉位選
          P0=positon[2];
          WE=1;
          WE=0;        
}

void delay(unsigned int z)//毫秒級(jí)延時(shí)
{
        unsigned int x,y;
        for(x = z; x > 0; x--)
                for(y = 114; y > 0 ; y--);
}

void Delay10us(unsigned char i)            //10us延時(shí)函數(shù) 啟動(dòng)超聲波模塊時(shí)使用
{
   unsigned char j;
        do{
                j = 10;
                do{
                        _nop_();
                }while(--j);
        }while(--i);
}
/*小車前進(jìn)*/
void forward()
{
        left_motor_go; //左電機(jī)前進(jìn)
        right_motor_go; //右電機(jī)前進(jìn)
}
/*小車左轉(zhuǎn)*/
void left_run()
{
        left_motor_stops; //左電機(jī)停止
        right_motor_go; //右電機(jī)前進(jìn)        
}
/*小車右轉(zhuǎn)*/
void right_run()
{
        right_motor_stops;//右電機(jī)停止
        left_motor_go;    //左電機(jī)前進(jìn)
}


/*PWM控制使能 小車原地左轉(zhuǎn)*/
void left_rapidly()
{
        left_motor_back;
        right_motor_go;        
}

/*小車后退*/
void backward()
{
        left_motor_back; //左電機(jī)后退
        right_motor_back; //右電機(jī)后退        
}
/*小車停止*/
void stop()
{
        right_motor_stops;//右電機(jī)停止
        left_motor_stops; //左電機(jī)停止        
}

void  StartModule()                          //啟動(dòng)超聲波模塊
{
          TX=1;                                             //啟動(dòng)一次模塊
      Delay10us(2);
          TX=0;
}



/*定時(shí)器1中斷輸出PWM信號(hào)*/
void timer1() interrupt 3
{
    //Display();                                      //如果把掃描數(shù)碼管函數(shù)加在這里,就會(huì)導(dǎo)致數(shù)碼管數(shù)字15s以上才跳動(dòng)一次,另外小車輪子也同時(shí)停止轉(zhuǎn)動(dòng)
        pwm_t++;//周期計(jì)時(shí)加
        if(pwm_t == 255)
        {
        //        StartModule();        //啟動(dòng)模塊測(cè)距
                pwm_t = EN1 = EN2 = 0;
        }
        if(pwm_left_val == pwm_t)//左電機(jī)占空比        
                EN1 = 1;               
        if(pwm_right_val == pwm_t)//右電機(jī)占空比
                EN2 = 1;                        
}

/*啟動(dòng)函數(shù)*/
void start()
{

                                beep = 0;        //使能有源蜂鳴器
                                delay(200);//200毫秒延時(shí)
                                beep = 1;        //關(guān)閉有源蜂鳴器

}
/*電機(jī)加速函數(shù)*/
void keying_s2()
{
        
                if(key_s2 == 0)// 實(shí)時(shí)檢測(cè)S2按鍵是否被按下
                {
                        delay(5); //軟件消抖
                        if(key_s2 == 0)//再檢測(cè)S2是否被按下
                        {
                                while(!key_s2);//松手檢測(cè)
                                if(pwm_right_val >= 0 && pwm_left_val >= 0 )
                                {
                                        pwm_left_val--;
                                        pwm_right_val--;
                                }
                        }
                }        
}         
/*電機(jī)減速函數(shù)*/
void keying_s3()
{
        
                if(key_s3 == 0)// 實(shí)時(shí)檢測(cè)S2按鍵是否被按下
                {
                        delay(5); //軟件消抖
                        if(key_s3 == 0)//再檢測(cè)S2是否被按下
                        {
                                while(!key_s2);//松手檢測(cè)
                                if(pwm_right_val < 255 && pwm_left_val < 255 )
                                {
                                        pwm_left_val++;
                                        pwm_right_val++;
                                }
                        }
                }        
}

/*定時(shí)器0中斷*/
void timer0() interrupt 1        //T0中斷用來(lái)計(jì)數(shù)器溢出,超過(guò)測(cè)距范圍
{
        flag=1;                                                         //中斷溢出標(biāo)志                        
}


/*計(jì)算超聲波所測(cè)距離并顯示*/
void Conut()
{
        time=TH0*256+TL0;
        TH0=0;
        TL0=0;
        
        S=(float)(time*1.085)*0.017;     
        if((S>=700)||flag==1) //超出測(cè)量范圍
        {         
          flag=0;
          disbuff[0]=10;
          disbuff[1]=10;           //“-”
          disbuff[2]=10;           //“-”
         }
         else
         {
          disbuff[0]=S/100;
          disbuff[1]=S%100/10;
          disbuff[2]=S%10;
         }
}

//尋跡
void tracking()
{
                //為0 沒有識(shí)別到黑線 為1識(shí)別到黑線
        if(left_led1 == 1 && right_led1 == 1)//左右尋跡探頭識(shí)別到黑線
        {
                forward();//前進(jìn)
        }
        else
        {
                if(left_led1 == 1 && right_led1 == 0)//小車右邊出線,左轉(zhuǎn)修正
                {
                        left_run();//左轉(zhuǎn)
                }
                if(left_led1 == 0 && right_led1 == 1)//小車左邊出線,右轉(zhuǎn)修正
                {
                        right_run();//右轉(zhuǎn)
                }
                if(left_led1 == 0 && right_led1 == 0)//左右尋跡探頭都沒識(shí)別到黑線
                {
                        backward();//后退
                }               
        }        
}

/*超聲波避障*/
void        Avoid()
{
        if(S < 400)//設(shè)置避障距離(單位毫米),掉頭距離
        {
        //        beep = 0;//使能蜂鳴器
                stop();//停車
                delay(100);//停車時(shí)間
                left_rapidly();//原地左轉(zhuǎn)
                delay(180);//左右角度,數(shù)值越大轉(zhuǎn)向角度越大
                do{
                        left_rapidly();//原地左轉(zhuǎn)
                        delay(10);//轉(zhuǎn)向角度
                        stop();         //停車
                        delay(1);//停車時(shí)間
                        }while(left_led1 == 0 || right_led1 == 0); //回到黑線上則退出,否則繼續(xù)原地轉(zhuǎn)向?qū)ふ液诰
        //        beep = 1;//關(guān)閉蜂鳴器                    //測(cè)試太吵了,暫時(shí)關(guān)掉
        }
}
        
void main()
{
        unsigned int i;
        keying_s2();
        keying_s3();
        start();//等待按鍵按下啟動(dòng)
        delay(1000);//延時(shí)1秒
        TMOD |= 0x20;//定時(shí)器1工作模式2,8位自動(dòng)重裝。用于產(chǎn)生PWM
        TMOD |= 0x01;//定時(shí)器0工作模塊1,16位定時(shí)模式。T0用測(cè)ECH0脈沖長(zhǎng)度
        TH1 = 220; //
        TL1 = 220; //100HZ T1   小車機(jī)械周期為1.85微秒
        TH0        = 0;
        TL0        = 0;//T0,16位定時(shí)計(jì)數(shù)用于記錄ECHO高電平時(shí)間         
        ET1        = 1;//允許T1中斷
        ET0 = 1;//允許T0中斷
        TR1 = 1;//啟動(dòng)定時(shí)器1
        EA  = 1;//啟動(dòng)總中斷
        StartModule();        //啟動(dòng)模塊測(cè)距
        while(1)
        {        
                 StartModule();                //啟動(dòng)模塊測(cè)距
                 while(!RX);                //當(dāng)RX(ECHO信號(hào)回響)為零時(shí)等待
                 TR0=1;                            //開啟計(jì)數(shù) ,此時(shí)ECHO信號(hào)回響為1
                 while(RX);                        //當(dāng)RX為1計(jì)數(shù)并等待
                 TR0=0;                                //關(guān)閉計(jì)數(shù) ,此時(shí)ECHO信號(hào)恢復(fù)為0
                 Conut();                        //計(jì)算距離
                 Avoid();                        //避障
                //之前我也考慮過(guò)在這里添加三個(gè)Display()函數(shù),就不用循環(huán)掃描了,寫成三個(gè)函數(shù),分別對(duì)應(yīng)數(shù)碼管的三個(gè)位,但是基本前兩位看不清,只能看清楚第三位,我知道這是因?yàn)檠訒r(shí)的原因,但是這里的延時(shí)確實(shí)不好調(diào)整。
                 for(i=0; i<1800; i++)  //超聲波每次測(cè)距間隔不低于65ms
                 tracking();        //尋跡        
        }
}

我個(gè)人的思想是那個(gè)T1中斷函數(shù)很慢才啟動(dòng)一次,測(cè)試我發(fā)現(xiàn)其實(shí)超聲波模塊的測(cè)距是很頻繁的,所以我覺得disbuffer數(shù)組中的數(shù)是經(jīng)常在調(diào)整的,知識(shí)因?yàn)閽呙钄?shù)碼管函數(shù)啟動(dòng)一次很慢,所以才導(dǎo)致要花費(fèi)15s才能有變換。但是我又想不通T1那個(gè)函數(shù)不可能15s才進(jìn)入一次啊,因?yàn)閜wm在每個(gè)周期都要靠那里使能占空比,所以請(qǐng)教一下大佬,這是什么原因?如果順帶能告訴我如何優(yōu)化,更是感激不盡!
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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