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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

51單片機Uart與RGB兼容性問題

[復制鏈接]
跳轉到指定樓層
樓主
ID:1071654 發表于 2023-9-16 17:40 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
50黑幣
單片機STC89C52RC,晶振采用24MHZ,波特率9600,當前問題是:
1、把RGB()函數放在主函數while(1)里面后,雖然在串口助手看到有收到指令,指令所對應動作無法被執行
2、注釋主函數中的RGB()函數后,先發指令1-6能收到且執行,再發送指令9后,RGB燈正常,這時候發送1-6指令,概率性打斷RGB執行對應指令
為什么RGB()運行的同時Uart指令無法識別呢?就算去掉RGB()中的Delay()函數,看到的現象跟問題2一致。
感謝各位大神解答,感激不盡!!!

#include <REGX52.H>
#include "UART.H"
#include "MotorDrive.H"
#include "INTRINS.H"    //包含nop指令頭文件
#include "Delay.H"
#include "Timer0.H"

#define nop  _nop_();
sbit DIN=P2^6;     //定義信號輸出DIN
unsigned char Compare,Compare1,Compare2,Compare3;
unsigned char Counter,Counter1,Counter2,Counter3;
unsigned int IC=2;              //控制TM1804個數
unsigned int LED_PX;            //像素點數
unsigned char PWM=255;          //TM1804灰度數據
unsigned char Rda,Gda,Bda;      //R、G、B灰度數據
unsigned char bdata LED_data;   //可位操作的數據發送暫存變量聲明

sbit bit0=LED_data^0;           //被發送的數據各位定義
sbit bit1=LED_data^1;
sbit bit2=LED_data^2;
sbit bit3=LED_data^3;
sbit bit4=LED_data^4;
sbit bit5=LED_data^5;
sbit bit6=LED_data^6;
sbit bit7=LED_data^7;
bit flag=0;

sbit L298N_ENA=P1^4;
sbit L298N_ENB=P1^5;
sbit L298N_ENA1=P1^1;
sbit L298N_ENB1=P0^2;

bit gb_RGB=0;
bit gbRI=0;

unsigned char Data;

void send_data_0()        //發送0碼函數,規格書體現低速模式高電平700ns,周期2.5us
{
        //示波器實際測試高1uS,周期4.5uS
                DIN=1;
                _nop_();
                DIN=0;
}


void send_data_1()        //發送1碼函數,規格書體現低速模式高電平1800ns,周期2.5us   
{
        //示波器實際測試高1.5uS,周期6uS
                DIN=1;
                _nop_();_nop_();
                DIN=0;
}

void send_data(unsigned char DATA1)        //發送1個字節數據,高位先發               
{
LED_data=DATA1;                          
if(bit7)        send_data_1();        else send_data_0();
if(bit6)        send_data_1();        else send_data_0();
if(bit5)        send_data_1();        else send_data_0();
if(bit4)        send_data_1();        else send_data_0();
if(bit3)        send_data_1();        else send_data_0();
if(bit2)        send_data_1();        else send_data_0();
if(bit1)        send_data_1();        else send_data_0();
if(bit0)        send_data_1();        else send_data_0();
}

void send_px()        //發送1幀數據
{
unsigned int i;
for(i=0;i<LED_PX;i++)
  {
   send_data(Rda);             //發送R灰度數據
   send_data(Gda);             //發送G灰度數據
   send_data(Bda);             //發送B灰度數據
  }
}


void RGB()        //RGB函數
{
unsigned char i;
LED_PX=IC;                          //像素點數等于TM1804個數
Rda=Gda=Bda=0;                      //R、G、B灰度數據復位清零

   for(i=0;i<PWM;i++)          //紅色漸亮  
    {
     Rda=i;              //灰度計算
     send_px();          //發送灰度數據
     Delay(10);          //復位延時
    }
     for(i=0;i<PWM;i++)  //紅色漸滅,綠色漸亮
      {
       Gda=i;
       Rda=PWM-i;  //灰度計算
       send_px();  //發送灰度數據
       Delay(10);  //復位延時
      }
     for(i=0;i<PWM;i++)  //綠色漸滅,藍色漸亮
      {
       Bda=i;           
       Gda=PWM-i;  //灰度計算
       send_px();  //發送灰度數據       
       Delay(10);  //復位延時
      }
     for(i=0;i<PWM;i++)  //藍色漸滅,紅色漸亮
      {
       Rda=i;
       Bda=PWM-i;  //灰度計算
       send_px();  //發送灰度數據
       Delay(10);  //復位延時
      }
}

void main()
{
        UART_Init();
        L298N_ENA=1;
        L298N_ENB=1;
        L298N_ENA1=1;
        L298N_ENB1=1;
        while(1)
        {
//                RGB();
                if(Data==0)StopIt();        //停止
                if(Data==1)Forward();        //直行
                if(Data==2)BackOff();        //后退
                if(Data==3)TurnLeft();        //左轉
                if(Data==4)TurnRight();        //右轉
                if(Data==5)TurnLeftCircle();        //左轉彎
                if(Data==6)TurnRightCircle();        //右轉彎
                if(Data==9)RGB();                //RGB
                }
        }
void UART_Routine() interrupt 4    //串口中斷
{
gbRI=1;       
if(RI==1)   //允許單片機接收數據
{
        Data=SBUF;                   //讀取數據
        UART_SendByte(SBUF);  //將接收到的數據發回串口
        RI=0;  //接收標志位清0 軟件復位
}
}


最佳答案

查看完整內容

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

使用道具 舉報

沙發
ID:161164 發表于 2023-9-16 17:40 | 只看該作者
wen1989jun 發表于 2023-9-25 09:41
定時器10mS的設置不太行哦,電機會有卡頓。
現在還是卡在沒辦法同時用,我繼續找找問題

不要用delay
  1. void RGB()        //RGB函數
  2. {
  3.         static unsigned char i=0, j=0;
  4.         static unsigned int DelayCnt = 0;
  5.         LED_PX=IC;                          //像素點數等于TM1804個數
  6.         if(DelayCnt++>=1000)
  7.         {
  8.                 DelayCnt=0;
  9.                 switch(j)
  10.                 {
  11.                 case 0:
  12.                         Rda=Gda=Bda=0;                      //R、G、B灰度數據復位清零
  13.                         j++;
  14.                         break;
  15.                 case 1:
  16.                         Rda=i;              //灰度計算
  17.                         if(++i>=PWM)
  18.                         {
  19.                                 i=0;
  20.                                 j++;
  21.                         }
  22.                         break;
  23.                 case 2:
  24.                         Gda=i;
  25.                         Rda=PWM-i;  //灰度計算
  26.                         if(++i>=PWM)
  27.                         {
  28.                                 i=0;
  29.                                 j++;
  30.                         }
  31.                         break;
  32.                 case 3:
  33.                         Bda=i;
  34.                         Gda=PWM-i;  //灰度計算
  35.                         if(++i>=PWM)
  36.                         {
  37.                                 i=0;
  38.                                 j++;
  39.                         }
  40.                         break;
  41.                 case 4:
  42.                         Rda=i;
  43.                         Bda=PWM-i;  //灰度計算
  44.                         if(++i>=PWM)
  45.                         {
  46.                                 i=0;
  47.                                 j++;
  48.                         }
  49.                         break;
  50.                 }
  51.                 send_px();          //發送灰度數據
  52.         }
  53. }
復制代碼
回復

使用道具 舉報

板凳
ID:1071654 發表于 2023-9-18 13:59 | 只看該作者
自頂下,附件為51控制TM1804_RGB視頻

51控制TM1804_RGB.zip

16.9 MB, 下載次數: 5

回復

使用道具 舉報

地板
ID:1071654 發表于 2023-9-18 17:03 | 只看該作者
自頂下,感謝各位大神答疑!
回復

使用道具 舉報

5#
ID:1092816 發表于 2023-9-19 11:40 | 只看該作者
串口數據接收部分位于UART_Routine()函數中的串口中斷中。這意味著當該中斷被觸發時,會執行UART_Routine()函數來接收串口數據,并執行相應的動作。

問題1:
將RGB()函數放在主函數while(1)循環內部時,在執行RGB()函數期間,由于沒有執行完畢,此時可能無法及時觸發串口中斷來接收指令。因此,指令所對應的動作無法被執行。你可以嘗試在RGB()函數執行完畢后再進行串口指令的接收和執行。

問題2:
這可能是由于程序運行時使用了中斷,同時存在幾個中斷源時,可能導致中斷優先級出現問題。為了解決此問題,可以嘗試:
1. 在主函數中加入全局變量flag并初始化為0。
2. 將RGB()函數移到主函數的while循環之外。
3. 主函數中加入一個條件語句判斷,如果flag等于0,則執行RGB()函數;否則執行串口指令的接收和執行。

在RGB()函數執行期間,flag會被設置為非零值,避免概率性打斷RGB燈執行對應指令的問題。當RGB()函數執行完畢后,flag會重新置零,再次執行串口指令的接收和執行。
回復

使用道具 舉報

6#
ID:844772 發表于 2023-9-19 14:35 | 只看該作者
好細的電源線啊,是用來兩套電源嗎?程序沒啥問題,就看看電源功率夠不夠了。
回復

使用道具 舉報

7#
ID:404160 發表于 2023-9-19 14:55 | 只看該作者
        Data=SBUF;                   //讀取數據
        UART_SendByte(SBUF);  //將接收到的數據發回串口
改成
        Data=SBUF;                   //讀取數據
        UART_SendByte(Data);  //將接收到的數據發回串口
試試
回復

使用道具 舉報

8#
ID:161164 發表于 2023-9-19 17:47 | 只看該作者
因為用了for循環+阻塞式延時
先辦法不用for循環和阻塞式延時來達到同樣效果

回復

使用道具 舉報

9#
ID:1071654 發表于 2023-9-19 18:30 | 只看該作者
飛云居士 發表于 2023-9-19 14:55
Data=SBUF;                   //讀取數據
        UART_SendByte(SBUF);  //將接收到的數據發回 ...

按照您提供的方法驗證了,串口助手看到有收到指令,但在執行RGB()函數中,其他指令依然不識別;發指令9執行了RGB(),再發指令9,居然也不識別。
回復

使用道具 舉報

10#
ID:1071654 發表于 2023-9-19 18:34 | 只看該作者
glinfei 發表于 2023-9-19 14:35
好細的電源線啊,是用來兩套電源嗎?程序沒啥問題,就看看電源功率夠不夠了。

電源線由兩個18650電池自帶的線供電,雙電池,給電機升壓是SX1308_12V,當單電池供電,L298N使能時候確實有概率會導致供電不足,雙電池驗證多次均沒問題。
我在想單電池時候是不是由于升壓IC前端電容容量不夠導致電池進入了放電過流保護?
回復

使用道具 舉報

11#
ID:844772 發表于 2023-9-20 09:07 | 只看該作者
wen1989jun 發表于 2023-9-19 18:34
電源線由兩個18650電池自帶的線供電,雙電池,給電機升壓是SX1308_12V,當單電池供電,L298N使能時候確實 ...

我沒看到你的用電功率情況,用了什么高級電機要12V啊,還有能否先不用升壓模塊試試?這種小車好多問題就不在程序上。
回復

使用道具 舉報

12#
ID:1071654 發表于 2023-9-20 09:19 | 只看該作者
glinfei 發表于 2023-9-20 09:07
我沒看到你的用電功率情況,用了什么高級電機要12V啊,還有能否先不用升壓模塊試試?這種小車好多問題就 ...

單電池概率性被拉死情況目前沒有去排查,電機用的12V_600轉的N20。
回復

使用道具 舉報

13#
ID:1071654 發表于 2023-9-20 09:31 | 只看該作者
cjc1029 發表于 2023-9-19 11:40
串口數據接收部分位于UART_Routine()函數中的串口中斷中。這意味著當該中斷被觸發時,會執行UART_Routine() ...

問題1:確認在RGB()執行完成之后能收到其他指令,也能被執行。我只是懷疑難道是因為RGB_DIN這個IO口翻轉太快,Uart就收不到指令啦?
問題2:按照您提供的方法驗證了,還是不行;RGB()執行期間,Uart收到的指令無法被執行。
另外,您說的同時存在幾個中斷時候確認會導致RGB()無法正常運行,RGB燈異常閃爍。僅僅加了如下代碼并打開了ET0=1;就會導致這個情況發生,也沒太搞懂是個啥情況。
void Timer0_Init()        //100微秒@24MHz
{
        TMOD &= 0xF0;                //設置定時器模式
        TMOD |= 0x01;                //設置定時器模式
        TL0 = 0x38;                //設置定時初值
        TH0 = 0xFF;                //設置定時初值
        TF0 = 0;                //清除TF0標志
        TR0 = 1;                //定時器0開始計時
        ET0=0;        //1為允許T0中斷,0為禁止
        EA=1;        //開啟總中斷
        PT0=1;        //中斷優先級控制
}

void Timer0_Routine() interrupt 1
{
        TL0=0x38;  //設置定時初值
        TH0=0xFF;  //設置定時初值
        Counter++;
        Counter%=100;                //計數值變化范圍限制在0~99
        Counter1++;
        Counter1%=100;        //計數值變化范圍限制在0~99
        Counter2++;
        Counter2%=100;        //計數值變化范圍限制在0~99
        Counter3++;
        Counter3%=100;        //計數值變化范圍限制在0~99
        if(Counter<Compare)
        {
                L298N_ENA=1;
        }
        else
        {
                L298N_ENA=0;
        }
        if(Counter1<Compare1)
        {
                L298N_ENB=1;
        }
        else
        {
                L298N_ENB=0;
        }
        if(Counter2<Compare2)
        {
                L298N_ENA1=1;
        }
        else
        {
                L298N_ENA1=0;
        }
        if(Counter3<Compare3)
        {
                L298N_ENB1=1;
        }
        else
        {
                L298N_ENB1=0;
        }
}
回復

使用道具 舉報

14#
ID:1071654 發表于 2023-9-20 09:39 | 只看該作者
lkc8210 發表于 2023-9-19 17:47
因為用了for循環+阻塞式延時
先辦法不用for循環和阻塞式延時來達到同樣效果

謝謝您的指導,我加油!!!
回復

使用道具 舉報

15#
ID:844772 發表于 2023-9-20 16:08 | 只看該作者
wen1989jun 發表于 2023-9-20 09:31
問題1:確認在RGB()執行完成之后能收到其他指令,也能被執行。我只是懷疑難道是因為RGB_DIN這個IO口翻轉 ...

定時器0設的太短了,對于N20電機的PWM沒必要這么快,因為2812的控制對時刻要求特別高,老是中斷很影響效果,當然在RGB()運行期間只要中斷都會影響效果,2812控制時刻是1微秒級的;
RGB()執行期間當然 ,不能執行指令。這是你程序決定的,但執行完就應該可以啊。
還有我有點拿不準,4個N20啟動功率差不多6W,如果加10個2812總功率超過10W了,升壓模塊應付的了嗎?
回復

使用道具 舉報

16#
ID:526543 發表于 2023-9-20 17:24 | 只看該作者
可能與串口中斷和RGB函數之間的并發執行有關
回復

使用道具 舉報

17#
ID:1092816 發表于 2023-9-20 17:50 | 只看該作者
先排除硬件,如果單一模塊運行沒有問題,對于資源小的單片機,你要優化的是程序的架構,全部放while里不合適。你RGB里面的for也是耗CPU的,降低刷新頻率試一下。
回復

使用道具 舉報

18#
ID:1071654 發表于 2023-9-21 10:09 | 只看該作者
123456ZXC1 發表于 2023-9-20 17:24
可能與串口中斷和RGB函數之間的并發執行有關

兄弟,展開說說看
回復

使用道具 舉報

19#
ID:1071654 發表于 2023-9-21 14:35 | 只看該作者
glinfei 發表于 2023-9-20 16:08
定時器0設的太短了,對于N20電機的PWM沒必要這么快,因為2812的控制對時刻要求特別高,老是中斷很影響效 ...

定時器0當前設置的是100us,這個設置多少合適呢?
RGB控制用的是TM1804哦,用了2Pcs,各控制了7個RGB燈,這兩個IC由ETA的DCDC供電
4個N20電機由2個L298N控制,2個L298N由兩路SX1308供電,電源來自2個2550mAh的18650電池
回復

使用道具 舉報

20#
ID:1094164 發表于 2023-9-21 15:21 | 只看該作者
電源線太細是不是也有點關系啊
回復

使用道具 舉報

21#
ID:844772 發表于 2023-9-22 09:13 | 只看該作者
wen1989jun 發表于 2023-9-21 14:35
定時器0當前設置的是100us,這個設置多少合適呢?
RGB控制用的是TM1804哦,用了2Pcs,各控制了7個RGB燈 ...

1,電機有慣性的,幾十Hz,也就是10毫秒級就行了;
2. 給機械部分供電一般只降壓,沒看到電路按你說的理論上確實可以,但實際會出現各種莫名狀況;
3.我覺得程序可以達到目的,雖然優化空間較大,但不是主要問題。
4.另外,遙控影響燈效和燈效期間不執行命令這是程序問題,但也不大影響使用。
回復

使用道具 舉報

22#
ID:1071654 發表于 2023-9-22 16:13 | 只看該作者
cjc1029 發表于 2023-9-20 17:50
先排除硬件,如果單一模塊運行沒有問題,對于資源小的單片機,你要優化的是程序的架構,全部放while里不合 ...

單一模塊是可以正常工作的,現在就是放在一起沒辦法同時執行。
降低刷新率是否就是修改RGB()里面的Delay()的值?
回復

使用道具 舉報

23#
ID:1071654 發表于 2023-9-23 09:32 | 只看該作者
流利說你好 發表于 2023-9-21 15:21
電源線太細是不是也有點關系啊

這個應該沒太大關系了,電源只是影響是否工作,工作是否穩定的吧
回復

使用道具 舉報

24#
ID:1071654 發表于 2023-9-25 09:41 | 只看該作者
glinfei 發表于 2023-9-22 09:13
1,電機有慣性的,幾十Hz,也就是10毫秒級就行了;
2. 給機械部分供電一般只降壓,沒看到電路按你說的理 ...

定時器10mS的設置不太行哦,電機會有卡頓。
現在還是卡在沒辦法同時用,我繼續找找問題
回復

使用道具 舉報

25#
ID:1071654 發表于 2023-9-25 11:44 | 只看該作者

使用了您提供的代碼,驗證RGB()和其他指令不沖突均可運行,但也表現出一個問題:
不管把RGB()函數放進主函數while(1)里面,還是放在主函數if()里面,RGB()函數均執行一次就結束了
不管咋說,真的非常感謝您,我自己再研究學習下,再次感謝您!!!
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 九九免费| 一区二区久久 | 亚洲精品电影网在线观看 | 欧美性久久久 | 人成在线视频 | 成人网av| 日韩中文字幕一区 | 黄色91在线 | 亚洲一区二区三区免费在线观看 | 99久久99久久精品国产片果冰 | jlzzxxxx18hd护士| 亚洲国产成人av | 久久久久久亚洲精品 | 久久久亚洲 | 日韩午夜精品 | 正在播放国产精品 | 成人二区| 美日韩精品 | 不卡在线视频 | 日韩在线不卡 | 成人久久久 | 午夜免费网 | 成人影院在线视频 | 免费一二区 | 成人在线视频看看 | www.一区二区三区 | 五月天国产在线 | 自拍偷拍第一页 | 成人a视频片观看免费 | 国产精品五区 | 精品一区二区三区四区五区 | 亚洲精品专区 | 亚洲日韩中文字幕一区 | 九九伦理电影 | 别c我啊嗯国产av一毛片 | 久久精品国产一区二区电影 | 国产视频久久 | 久久国产精彩视频 | 日韩一区二区三区在线观看 | 国产精品国产馆在线真实露脸 | 国产自产21区|