找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4549|回復: 13
打印 上一主題 下一主題
收起左側(cè)

做一個藍牙小車程序,pwm中斷和串口中斷沖突,有大哥幫幫忙嗎,看看那里有問題

  [復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:344179 發(fā)表于 2019-2-25 15:04 | 只看該作者 回帖獎勵 |正序瀏覽 |閱讀模式
有大哥幫幫忙嗎,看看那里有問題,51單片機做一個藍牙小車程序,pwm中斷和串口中斷沖突,幫忙看看那里有問題, 感謝感謝。


#include <reg52.h>

sbit EN1 = P2^0; //為1 右電機使能
sbit EN2 = P2^1; //為1 左電機使能
sbit IN1 = P2^2; //為1 右電機反轉(zhuǎn)
sbit IN2 = P2^3; //為1 右電機正轉(zhuǎn)
sbit IN3 = P2^4; //為1 左電機正轉(zhuǎn)
sbit IN4 = P2^5; //為1 左電機反轉(zhuǎn)

#define left_motor_en           EN1 = 1           //左電機使能
#define left_motor_stops        EN1 = 0           //左電機停止
#define right_motor_en          EN2 = 1           //右電機使能
#define right_motor_stops       EN2 = 0           //右電機停止
#define left_motor_go           IN1 = 0, IN2 = 1  //左電機正傳
#define left_motor_back         IN1 = 1, IN2 = 0  //左電機反轉(zhuǎn)
#define right_motor_go          IN3 = 1, IN4 = 0  //右電機正傳
#define right_motor_back        IN3 = 0, IN4 = 1  //右電機反轉(zhuǎn)

double count = 0;//定義占空比,并初始占空比為26%
unsigned char time;
unsigned char pwm_left_val = 0;//左電機占空比值 取值范圍0-170,0最快
unsigned char pwm_right_val = 0;//右電機占空比值取值范圍0-170 ,0最快
unsigned char pwm_t; //周期

void UART_INIT();  //藍牙接收初始化
void Che_init();   //小車輸出端口定時器初始化
void forward();    //小車前進
void back();       //小車后退
void right();      //小車左轉(zhuǎn)
void left();       //小車右轉(zhuǎn)
void stop();           //小車停止
void delay(unsigned int z);        //延時函數(shù)
               
void main()
{
        UART_INIT();  //藍牙接收初始化
    Che_init();          //小車輸出端口定時器初始化
    while(1);
        

}

void UART_INIT()  //藍牙接收初始化
{
        SCON = 0X50;
    TMOD = 0x20; //8位自動重裝模式
    TH1 = 0xfd;
    TL1 = 0xfd;  //9600波特率
    TR1 = 1;     //啟動定時器1
    ES = 1;      //開串口中斷
        EA = 1;      //開總中斷
}
                        
void Che_init()         //小車使能輸出端口定時器初始化
{
        TMOD|= 0x02; //8位自動重裝模塊
        TH0=(65536-10)/256;
        TL0=(65536-10)%256;
        TR0=1;
        ET0=1;
        EA=1;
/*
        TMOD|= 0x02; //8位自動重裝模塊
    TH0 = 220;
    TL0 = 220;    //11.0592M晶振下占空比最大比值是256,輸出100HZ
    TR0 = 1;      //啟動定時器0
    ET0 = 1;      //允許定時器0中斷
    EA = 1;       //總中斷允許
        */
}

void forward()        //小車前進
{
        ET0 = 1;
        TR0 = 1;
    left_motor_go;  //左電機前進
    right_motor_go; //右電機前進
        while(1)
        {
                count += 0.1;
        }
}

void back()        //小車后退
{
        ET0 = 1;
        TR0 = 1;
        left_motor_back;  //左電機反轉(zhuǎn)
        right_motor_back; //右電機反轉(zhuǎn)      
}

void right()  //小車左轉(zhuǎn)
{
        ET0 = 1;
        TR0 = 1;
        left_motor_go;    //左電機正傳
        right_motor_back; //右電機反轉(zhuǎn)
}

void left()          //小車右轉(zhuǎn)
{
        ET0 = 1;
        TR0 = 1;
        right_motor_go;         //右電機正傳
        left_motor_back; //左電機反轉(zhuǎn)
}

void stop()          //小車停止
{
        ET0 = 0;
        TR0 = 0;
        count = 0;
        left_motor_stops;   //左電機停止
        right_motor_stops;        //右電機停止
}

void timer0() interrupt 1  //定時器0中斷
{  
        TR0 = 0; //設置定時器初值期間,關(guān)閉定時器
        TH0=(65536-10)/256;
        TL0=(65536-10)%256;
        //TR0=1;
        time++;
        //count += 0.1;
        if(time<count)
        {        
                EN1 = 1;  //輸出高電平
                EN2 = 1;  //輸出高電平
        }
        else
        {
                EN1 = 0;  //輸出低電平
                EN2 = 0;  //輸出低電平
        }
        if(time>=1000)
                time=0;
                /*
        pwm_t++;
        if(pwm_t == 255)
        {
           EN1 = 0;
           EN2 = 0;
           pwm_t = 0;
        }
        if(pwm_left_val == pwm_t)
            EN1 = 1;
        if(pwm_right_val == pwm_t)
                EN2 = 1;*/                        
}


void UART_SER() interrupt 4  //串口中斷
{
        if(RI)
    {
            RI = 0;//清除接收標志
        switch(SBUF)
        {
                case 'a':          //前進
                                forward();
                                break;
            case 'b':          //后退
                                back();
                                break;
            case 'l':          //左轉(zhuǎn)
                                right();
                                break;
                        case 'r':          //右轉(zhuǎn)
                                left();
                                break;
            case 's':          //停止
                                stop();
                                break;
                        default:     //否則全部停止
                                stop();
                                break;
        }
     }
}

void delay(unsigned int z)
{
        unsigned int x,y;
        for(x = z; x > 0; x--)
                for(y = 114; y > 0 ; y--);
}


評分

參與人數(shù) 1黑幣 +2 收起 理由
kljie1000 + 2

查看全部評分

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

使用道具 舉報

14#
ID:467843 發(fā)表于 2019-4-2 13:33 | 只看該作者
while(1)
         {
                 count += 0.1;
         }
}
前進程序干嘛要加while ,可以刪掉的。
還有你那定時至少100us啊,10us太短暫。
另外你你這個程序框架設計給我的感覺有點不簡潔。
count += 0.1;這個你想表達什么意思呢
定義變量可以像我這么定義,用數(shù)組比較簡潔。
#define Left_moto_Stop    {P1_0=0;P1_1=0,P1_2=0;}    //左電機停轉(zhuǎn)
#define Left_moto_go      {P1_0=1;P1_1=1,P1_2=0;}    //左電機正轉(zhuǎn)
#define Left_moto_back    {P1_0=1;P1_1=0,P1_2=1;}          //左電機反轉(zhuǎn)
#define Right_moto_Stop   {P1_3=0;P1_4=0,P1_5=0;}           //右電機停轉(zhuǎn)                     
#define Right_moto_go     {P1_3=1;P1_4=1,P1_5=0;}           //右電機正轉(zhuǎn)
#define Right_moto_back   {P1_3=1;P1_4=0,P1_5=1;}           //右電機反轉(zhuǎn)

引腳定義自己改


回復

使用道具 舉報

13#
ID:213173 發(fā)表于 2019-3-10 08:58 | 只看該作者
你定時器中斷設定10us,完成一次定時中斷內(nèi)容需要300us,怎么可能正常工作。何況在前進程序中使用死循環(huán),結(jié)果是同歸于盡,大家一起死。
回復

使用道具 舉報

12#
ID:478236 發(fā)表于 2019-3-10 08:11 | 只看該作者
上次我做過這個小車,后來發(fā)現(xiàn)串口接受一點問題都沒有,就是定時器中斷只進入一次,第二次就進不去,不懂你現(xiàn)在是不是這個問題?
回復

使用道具 舉報

11#
ID:137676 發(fā)表于 2019-3-10 00:55 | 只看該作者
感覺你定時器時間太短了
回復

使用道具 舉報

10#
ID:466164 發(fā)表于 2019-3-9 23:05 | 只看該作者
贊同HC6800-ES-V2.0
while(1)
        {
                count += 0.1;
        }
這里死循環(huán),只要小車前進,程序沒有跳出死循環(huán)語句,程序就一直跳不出,別的程序別想工作。
回復

使用道具 舉報

9#
ID:469417 發(fā)表于 2019-3-9 22:13 | 只看該作者
你是怎么確認的PWM中斷和串口中斷有沖突,建議分開調(diào)試檢查

評分

參與人數(shù) 2黑幣 +22 收起 理由
春風十里吹 + 12 回帖助人的獎勵!
zhengchong60 + 10 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

8#
ID:480013 發(fā)表于 2019-3-9 16:55 | 只看該作者
張事坤 發(fā)表于 2019-2-26 15:04
大哥 ,能改成pwm從0到最大嗎

這是可以的,如果不正常你再把周期改小一點
回復

使用道具 舉報

7#
ID:344179 發(fā)表于 2019-2-26 15:04 | 只看該作者
yaoji123 發(fā)表于 2019-2-26 08:01
中斷嵌套,優(yōu)級高占先,定時器0高于定時器1,定時器0定時值太小,很快就中斷,造成始終定時器中斷,PWM有動 ...

大哥 ,能改成pwm從0到最大嗎
回復

使用道具 舉報

6#
ID:158375 發(fā)表于 2019-2-26 08:36 | 只看該作者
你在串口中斷里直接處理SBUF,那么定時器0中斷怎么進去呢?
我認為是你的程序結(jié)構(gòu)或框架問題,改變思路試一試吧;
串口中斷里把SBUF保存起來,在while()處理那個數(shù)據(jù),可能會好些吧。
一般情況下,中斷里面,做最少的事情,只做必要的。需要處理,把標志位保存即可,剩下的事情讓主程序去干!
回復

使用道具 舉報

5#
ID:164602 發(fā)表于 2019-2-26 08:20 | 只看該作者
卡這里了:
        while(1)
        {
                count += 0.1;
        }
這里死循環(huán),當然卡住了嘛。
回復

使用道具 舉報

地板
ID:432823 發(fā)表于 2019-2-26 08:01 | 只看該作者
中斷嵌套,優(yōu)級高占先,定時器0高于定時器1,定時器0定時值太小,很快就中斷,造成始終定時器中斷,PWM有動作,串口無法中斷接收。
回復

使用道具 舉報

板凳
ID:344179 發(fā)表于 2019-2-25 21:27 | 只看該作者
笨笨兔 發(fā)表于 2019-2-25 16:44
程序沒看,只是想問一下:
你是怎么確認的PWM中斷和串口中斷有沖突呢?

只有pwm在動作 藍牙串口不工作,卡在前進的while()中了,要的效果是,小車前進pwm從0到最大
回復

使用道具 舉報

沙發(fā)
ID:158375 發(fā)表于 2019-2-25 16:44 | 只看該作者
程序沒看,只是想問一下:
你是怎么確認的PWM中斷和串口中斷有沖突呢?
回復

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復 返回頂部 返回列表