找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3842|回復(fù): 26
收起左側(cè)

為什么單片機(jī)流水燈由1到8就停止了。編譯沒有問題,求解怎么修改代碼可以運(yùn)行

[復(fù)制鏈接]
ID:858009 發(fā)表于 2021-4-27 15:48 | 顯示全部樓層 |閱讀模式
本帖最后由 qwettyuio 于 2021-4-28 10:28 編輯

#include<reg51.h>    //包含51單片機(jī)寄存器定義的頭文件
unsigned char keyval;  //儲存按鍵值
#define uchar unsigned char
#define uint unsigned int
code tabup[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
code tabdown[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
uint x,y;
/*************************************************
函數(shù)功能:流水燈延時(shí)
**************************************************/
void led_delay(void)
{
   unsigned char i,j;
        for(i=0;i<250;i++)
          for(j=0;j<250;j++);           
}
/*************************************************
函數(shù)功能:軟件消抖延時(shí)
**************************************************/
void delay20ms(void)
{
   unsigned char i,j;
       for(i=0;i<100;i++)
          for(j=0;j<60;j++);           
}
/*************************************************
函數(shù)功能:正向流水點(diǎn)亮LED
**************************************************/
void forward(void)
{                              
        for(x=0;x<8;x++)        
        {
                P1=tabup[x];
                led_delay();
        }               
}
/*************************************************
函數(shù)功能:反向流水點(diǎn)亮LED
**************************************************/
void backward(void)
{                          
        for(y=0;y<8;y++)
        {
                P1=tabdown[y];
                led_delay();
        }
}
/*************************************************
函數(shù)功能:關(guān)閉所有LED
**************************************************/
void stop(void)
{
        P1=0xff;    //關(guān)閉8個(gè)LED
}
/*************************************************
函數(shù)功能:閃爍點(diǎn)亮LED
**************************************************/
void flash(void)
{
  P1=0x00;               //點(diǎn)亮8個(gè)LED
  led_delay();
}
void main(void)          //主函數(shù)
{
        SCON = 0x50;           //設(shè)定串口工作方式
  PCON = 0x00;           //波特率不倍增        
  TMOD = 0x20;           //定時(shí)器1工作于8位自動重載模式, 用于產(chǎn)生波特率
  EA   = 1;
  ES   = 1;              //允許串口中斷
  TL1  = 0xfd;
  TH1  = 0xfd;           //波特率9600
  TR1  = 1;
  while(1);
}
/*************************************************
函數(shù)功能:定時(shí)器T0的中斷服務(wù)子程序
**************************************************/
void  serial() interrupt 4
{
   ES = 0;                //關(guān)閉串行中斷
   RI = 0;                //清除串行接受標(biāo)志位
   keyval = SBUF;            //從串口緩沖區(qū)取得數(shù)據(jù)                        
   switch(keyval)
   {
      case 1:forward();break;
      case 2:backward();break;
      case 3:stop();break;
      case 4:flash();break;
   }                  
  ES = 1;    //允許串口中斷
}


效果圖 (2).jpg
回復(fù)

使用道具 舉報(bào)

ID:332214 發(fā)表于 2021-4-27 16:36 | 顯示全部樓層
你這是通過一點(diǎn)一點(diǎn)問改的啊,挺用心的 你那邊這樣改應(yīng)該就行了。
void main(void)          //主函數(shù)
{
        SCON = 0x50;           //設(shè)定串口工作方式
  PCON = 0x00;           //波特率不倍增        
  TMOD = 0x20;           //定時(shí)器1工作于8位自動重載模式, 用于產(chǎn)生波特率
  EA   = 1;
  ES   = 1;              //允許串口中斷
  TL1  = 0xfd;
  TH1  = 0xfd;           //波特率9600
  TR1  = 1;
  while(1)
  {
      switch(keyval)
      {
          case 1:forward();break;
          case 2:backward();break;
          case 3:stop();break;
          case 4:flash();break;
      }   
   }
}
/*************************************************
函數(shù)功能:定時(shí)器T0的中斷服務(wù)子程序
**************************************************/
void  serial() interrupt 4
{
   ES = 0;                //關(guān)閉串行中斷
   RI = 0;                //清除串行接受標(biāo)志位
   keyval = SBUF;            //從串口緩沖區(qū)取得數(shù)據(jù)                                       
  ES = 1;    //允許串口中斷
}
回復(fù)

使用道具 舉報(bào)

ID:858009 發(fā)表于 2021-4-27 16:58 | 顯示全部樓層
啊哈哈123 發(fā)表于 2021-4-27 16:36
你這是通過一點(diǎn)一點(diǎn)問改的啊,挺用心的 你那邊這樣改應(yīng)該就行了。
void main(void)          //主函數(shù)
{
...

這樣修改不行,沒反應(yīng),一個(gè)led都不亮,原來的不能循環(huán),從一到八,就定在八了
回復(fù)

使用道具 舉報(bào)

ID:824490 發(fā)表于 2021-4-27 17:24 | 顯示全部樓層
你為什么要把流水放在串口中斷里動行?你串口沒收到數(shù)據(jù),就進(jìn)不了中斷‘,又如何能讓 switch(keyval)這個(gè)有變化?即進(jìn)了中斷,也只能運(yùn)行一次,除非你不停往串口發(fā)送數(shù)據(jù)。
把你所想的、所做的,畫一個(gè)流程圖,說不定你就能發(fā)現(xiàn)是邏輯問題了。。
這種純屬邏輯的代碼,建議寫代碼前先畫個(gè)流程圖,能幫你更快地寫出你想要的代碼來。
磨刀不誤砍柴工哦。〖佑

回復(fù)

使用道具 舉報(bào)

ID:858009 發(fā)表于 2021-4-27 17:34 | 顯示全部樓層
名字不是重點(diǎn) 發(fā)表于 2021-4-27 17:24
你為什么要把流水放在串口中斷里動行?你串口沒收到數(shù)據(jù),就進(jìn)不了中斷‘,又如何能讓 switch(keyval)這個(gè) ...

修改不出來,找不出問題在哪里,小白一個(gè),大佬技術(shù)指導(dǎo)一下,感謝
回復(fù)

使用道具 舉報(bào)

ID:332214 發(fā)表于 2021-4-27 17:34 | 顯示全部樓層
qwettyuio 發(fā)表于 2021-4-27 16:58
這樣修改不行,沒反應(yīng),一個(gè)led都不亮,原來的不能循環(huán),從一到八,就定在八了

你向串口發(fā)送數(shù)據(jù)了嗎?用hex格式發(fā)送1 試試
回復(fù)

使用道具 舉報(bào)

ID:858009 發(fā)表于 2021-4-27 17:36 | 顯示全部樓層
啊哈哈123 發(fā)表于 2021-4-27 17:34
你向串口發(fā)送數(shù)據(jù)了嗎?用hex格式發(fā)送1 試試

發(fā)送了,一個(gè)led都不亮
回復(fù)

使用道具 舉報(bào)

ID:858009 發(fā)表于 2021-4-27 17:37 | 顯示全部樓層
啊哈哈123 發(fā)表于 2021-4-27 17:34
你向串口發(fā)送數(shù)據(jù)了嗎?用hex格式發(fā)送1 試試

沒有任何反應(yīng)
回復(fù)

使用道具 舉報(bào)

ID:332214 發(fā)表于 2021-4-27 17:38 | 顯示全部樓層
qwettyuio 發(fā)表于 2021-4-27 17:36
發(fā)送了,一個(gè)led都不亮

你改過的完整代碼發(fā)出來看看
回復(fù)

使用道具 舉報(bào)

ID:858009 發(fā)表于 2021-4-27 17:46 | 顯示全部樓層
啊哈哈123 發(fā)表于 2021-4-27 17:38
你改過的完整代碼發(fā)出來看看

#include<reg51.h>    //包含51單片機(jī)寄存器定義的頭文件
unsigned char keyval;  //儲存按鍵值
#define uchar unsigned char
#define uint unsigned int
code tabup[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
code tabdown[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
uint x,y;
/*************************************************
函數(shù)功能:流水燈延時(shí)
**************************************************/
void led_delay(void)
{
   unsigned char i,j;
        for(i=0;i<250;i++)
          for(j=0;j<250;j++);           
}
/*************************************************
函數(shù)功能:軟件消抖延時(shí)
**************************************************/
void delay20ms(void)
{
   unsigned char i,j;
       for(i=0;i<100;i++)
          for(j=0;j<60;j++);           
}
/*************************************************
函數(shù)功能:正向流水點(diǎn)亮LED
**************************************************/
void forward(void)
{                              //不能加while(1),會循環(huán)這一函數(shù),其他按鍵控制無效
        for(x=0;x<8;x++)       
        {
                P1=tabup[x];
                led_delay();
        }               
}
/*************************************************
函數(shù)功能:反向流水點(diǎn)亮LED
**************************************************/
void backward(void)
{                          //不能加while(1),會循環(huán)這一函數(shù),其他按鍵控制無效
        for(y=0;y<8;y++)
        {
                P1=tabdown[y];
                led_delay();
        }
}
/*************************************************
函數(shù)功能:關(guān)閉所有LED
**************************************************/
void stop(void)
{
        P1=0xff;    //關(guān)閉8個(gè)LED
}
/*************************************************
函數(shù)功能:閃爍點(diǎn)亮LED
**************************************************/
void flash(void)
{
  P1=0x00;               //點(diǎn)亮8個(gè)LED
  led_delay();
}
void main(void)          //主函數(shù)
{
        SCON = 0x50;           //設(shè)定串口工作方式
  PCON = 0x00;           //波特率不倍增       
  TMOD = 0x20;           //定時(shí)器1工作于8位自動重載模式, 用于產(chǎn)生波特率
  EA   = 1;
  ES   = 1;              //允許串口中斷
  TL1  = 0xfd;
  TH1  = 0xfd;           //波特率9600
  TR1  = 1;
  while(1);
        {
                switch(keyval)
   {
      case 1:forward();break;
      case 2:backward();break;
      case 3:stop();break;
      case 4:flash();break;
   }
        }
}
/*************************************************
函數(shù)功能:定時(shí)器T0的中斷服務(wù)子程序
**************************************************/
void  serial() interrupt 4
{
   ES = 0;                //關(guān)閉串行中斷
   RI = 0;                //清除串行接受標(biāo)志位
   keyval = SBUF;            //從串口緩沖區(qū)取得數(shù)據(jù)                                           
   ES = 1;    //允許串口中斷
}
回復(fù)

使用道具 舉報(bào)

ID:858009 發(fā)表于 2021-4-27 18:06 | 顯示全部樓層
啊哈哈123 發(fā)表于 2021-4-27 17:38
你改過的完整代碼發(fā)出來看看

#include<reg51.h>    //包含51單片機(jī)寄存器定義的頭文件
unsigned char keyval;  //儲存按鍵值
#define uchar unsigned char
#define uint unsigned int
code tabup[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
code tabdown[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
uint x,y;
/*************************************************
函數(shù)功能:流水燈延時(shí)
**************************************************/
void led_delay(void)
{
   unsigned char i,j;
        for(i=0;i<250;i++)
          for(j=0;j<250;j++);           
}
/*************************************************
函數(shù)功能:軟件消抖延時(shí)
**************************************************/
void delay20ms(void)
{
   unsigned char i,j;
       for(i=0;i<100;i++)
          for(j=0;j<60;j++);           
}
/*************************************************
函數(shù)功能:正向流水點(diǎn)亮LED
**************************************************/
void forward(void)
{                              //不能加while(1),會循環(huán)這一函數(shù),其他按鍵控制無效
        for(x=0;x<8;x++)       
        {
                P1=tabup[x];
                led_delay();
        }               
}
/*************************************************
函數(shù)功能:反向流水點(diǎn)亮LED
**************************************************/
void backward(void)
{                          //不能加while(1),會循環(huán)這一函數(shù),其他按鍵控制無效
        for(y=0;y<8;y++)
        {
                P1=tabdown[y];
                led_delay();
        }
}
/*************************************************
函數(shù)功能:關(guān)閉所有LED
**************************************************/
void stop(void)
{
        P1=0xff;    //關(guān)閉8個(gè)LED
}
/*************************************************
函數(shù)功能:閃爍點(diǎn)亮LED
**************************************************/
void flash(void)
{
  P1=0x00;               //點(diǎn)亮8個(gè)LED
  led_delay();
}
void main(void)          //主函數(shù)
{
        SCON = 0x50;           //設(shè)定串口工作方式
  PCON = 0x00;           //波特率不倍增       
  TMOD = 0x20;           //定時(shí)器1工作于8位自動重載模式, 用于產(chǎn)生波特率
  EA   = 1;
  ES   = 1;              //允許串口中斷
  TL1  = 0xfd;
  TH1  = 0xfd;           //波特率9600
  TR1  = 1;
  while(1);
        {
                switch(keyval)
   {
      case 1:forward();break;
      case 2:backward();break;
      case 3:stop();break;
      case 4:flash();break;
   }
        }
}
/*************************************************
函數(shù)功能:定時(shí)器T0的中斷服務(wù)子程序
**************************************************/
void  serial() interrupt 4
{
   ES = 0;                //關(guān)閉串行中斷
   RI = 0;                //清除串行接受標(biāo)志位
   keyval = SBUF;            //從串口緩沖區(qū)取得數(shù)據(jù)                                           
   ES = 1;    //允許串口中斷
}
回復(fù)

使用道具 舉報(bào)

ID:367369 發(fā)表于 2021-4-27 18:15 | 顯示全部樓層
建議將流水燈循環(huán)放入main函數(shù)的while1中
做出以下修改:
int keyval_flag = 5 ;    //定義標(biāo)志位,表示流水燈運(yùn)行方式  初始5為無操作

void main(void)          //主函數(shù)
{
  SCON = 0x50;           //設(shè)定串口工作方式
  PCON = 0x00;           //波特率不倍增        
  TMOD = 0x20;           //定時(shí)器1工作于8位自動重載模式, 用于產(chǎn)生波特率
  EA   = 1;
  ES   = 1;              //允許串口中斷
  TL1  = 0xfd;
  TH1  = 0xfd;           //波特率9600
  TR1  = 1;
  while(1)
  {
          
        switch(flag)   
   {
      case 1:forward();break;
      case 2:backward();break;
      case 3:stop();break;
      case 4:flash();break;
          default: break;
   }      
          
  }
}

/*************************************************
函數(shù)功能:定時(shí)器T0的中斷服務(wù)子程序
**************************************************/
void  serial() interrupt 4
{
   ES = 0;                //關(guān)閉串行中斷
   RI = 0;                //清除串行接受標(biāo)志位
   keyval_flag = SBUF;            //從串口緩沖區(qū)取得數(shù)據(jù)                                   
        ES = 1;    //允許串口中斷
}
回復(fù)

使用道具 舉報(bào)

ID:858009 發(fā)表于 2021-4-27 18:28 | 顯示全部樓層
game灬boy 發(fā)表于 2021-4-27 18:15
建議將流水燈循環(huán)放入main函數(shù)的while1中
做出以下修改:
int keyval_flag = 5 ;    //定義標(biāo)志位,表示 ...

修改了也不可以,串口發(fā)送任何字符都沒有用
回復(fù)

使用道具 舉報(bào)

ID:275826 發(fā)表于 2021-4-27 19:46 | 顯示全部樓層
把你電路板上12M的晶振換成11.0592M就行了
回復(fù)

使用道具 舉報(bào)

ID:858009 發(fā)表于 2021-4-27 20:00 來自手機(jī) | 顯示全部樓層
tyrl800 發(fā)表于 2021-4-27 19:46
把你電路板上12M的晶振換成11.0592M就行了

用的是開發(fā)板,是是11.596晶振
回復(fù)

使用道具 舉報(bào)

ID:824490 發(fā)表于 2021-4-27 20:06 | 顯示全部樓層

你先在main()中改一下,加入:
       while(1)
{

   switch(keyval)
         
   {
      case 1:
         forward();
         break;
      case 2:
        backward();
        break;
      case 3:
       stop();
       break;
      case 4:
       flash();
       break;
    default:

      break;
   }
keyval++;
if (keyval>4) keyval=1;
}
看是不是能從模式1到4 ,一直循環(huán)? 確定之后,再在串口中斷里改:
void  serial() interrupt 4
{
   ES = 0;                //關(guān)閉串行中斷
   RI = 0;                //清除串行接受標(biāo)志位
   keyval = SBUF;            //從串口緩沖區(qū)取得數(shù)據(jù)                        
  
  SBUF=keyval  ;//反彈收到的數(shù)據(jù)
  
}

從上位機(jī)看看,收到的數(shù)據(jù)是不是你發(fā)出的數(shù)據(jù),不丟碼?

回復(fù)

使用道具 舉報(bào)

ID:858009 發(fā)表于 2021-4-28 09:18 | 顯示全部樓層
名字不是重點(diǎn) 發(fā)表于 2021-4-27 20:06
你先在main()中改一下,加入:
       while(1)
{

進(jìn)入了死循環(huán),串口輸入其它字符無效
回復(fù)

使用道具 舉報(bào)

ID:824490 發(fā)表于 2021-4-28 09:43 | 顯示全部樓層
qwettyuio 發(fā)表于 2021-4-28 09:18
進(jìn)入了死循環(huán),串口輸入其它字符無效

如果中斷優(yōu)先級高的話,死循環(huán)中也要觸發(fā)中斷的
回復(fù)

使用道具 舉報(bào)

ID:858009 發(fā)表于 2021-4-28 09:47 | 顯示全部樓層
名字不是重點(diǎn) 發(fā)表于 2021-4-28 09:43
如果中斷優(yōu)先級高的話,死循環(huán)中也要觸發(fā)中斷的

沒法實(shí)現(xiàn),通過串口調(diào)用數(shù)組控制流水等,大佬,求幫忙。
回復(fù)

使用道具 舉報(bào)

ID:824490 發(fā)表于 2021-4-28 09:50 | 顯示全部樓層
首先你大循環(huán)中,按我給的代碼,4種模式能一直切換不?
回復(fù)

使用道具 舉報(bào)

ID:824490 發(fā)表于 2021-4-28 09:52 | 顯示全部樓層
其次,大循環(huán)空轉(zhuǎn),串口能反彈不?
回復(fù)

使用道具 舉報(bào)

ID:858009 發(fā)表于 2021-4-28 09:52 | 顯示全部樓層
名字不是重點(diǎn) 發(fā)表于 2021-4-28 09:50
首先你大循環(huán)中,按我給的代碼,4種模式能一直切換不?

能切換
回復(fù)

使用道具 舉報(bào)

ID:858009 發(fā)表于 2021-4-28 09:54 | 顯示全部樓層
名字不是重點(diǎn) 發(fā)表于 2021-4-28 09:52
其次,大循環(huán)空轉(zhuǎn),串口能反彈不?

加入中斷代碼出錯(cuò),無法編譯
回復(fù)

使用道具 舉報(bào)

ID:569384 發(fā)表于 2021-4-28 10:22 | 顯示全部樓層
這樣寫是幾個(gè)意思?
switch(keyval)
                 while(1)
   {
      case 1:forward();break;
      case 2:backward();break;
      case 3:stop();break;
      case 4:flash();break;
   }
回復(fù)

使用道具 舉報(bào)

ID:858009 發(fā)表于 2021-4-28 10:30 | 顯示全部樓層
haokey 發(fā)表于 2021-4-28 10:22
這樣寫是幾個(gè)意思?
switch(keyval)
                 while(1)

流水燈不能循環(huán),每次到第八個(gè)led就停了,所以叫了循環(huán),還是不可以,加while1),就不能中斷
回復(fù)

使用道具 舉報(bào)

ID:569384 發(fā)表于 2021-4-29 09:31 | 顯示全部樓層
qwettyuio 發(fā)表于 2021-4-28 10:30
流水燈不能循環(huán),每次到第八個(gè)led就停了,所以叫了循環(huán),還是不可以,加while1),就不能中斷

把流水燈放入主循環(huán)后現(xiàn)在是怎樣了?如果還是不行有沒有檢查一下串口發(fā)送工具是不是加了換行?
回復(fù)

使用道具 舉報(bào)

ID:569384 發(fā)表于 2021-4-29 09:35 | 顯示全部樓層
本帖最后由 haokey 于 2021-4-29 09:40 編輯
qwettyuio 發(fā)表于 2021-4-28 10:30
流水燈不能循環(huán),每次到第八個(gè)led就停了,所以叫了循環(huán),還是不可以,加while1),就不能中斷

我另外有一個(gè)建議,把uint x,y弄成局部變量,在forward和backward里面聲明變量就可以了。
回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

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

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

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