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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4068|回復: 26
收起左側

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

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

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


效果圖 (2).jpg
回復

使用道具 舉報

ID:332214 發表于 2021-4-27 16:36 | 顯示全部樓層
你這是通過一點一點問改的啊,挺用心的 你那邊這樣改應該就行了。
void main(void)          //主函數
{
        SCON = 0x50;           //設定串口工作方式
  PCON = 0x00;           //波特率不倍增        
  TMOD = 0x20;           //定時器1工作于8位自動重載模式, 用于產生波特率
  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;
      }   
   }
}
/*************************************************
函數功能:定時器T0的中斷服務子程序
**************************************************/
void  serial() interrupt 4
{
   ES = 0;                //關閉串行中斷
   RI = 0;                //清除串行接受標志位
   keyval = SBUF;            //從串口緩沖區取得數據                                       
  ES = 1;    //允許串口中斷
}
回復

使用道具 舉報

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

這樣修改不行,沒反應,一個led都不亮,原來的不能循環,從一到八,就定在八了
回復

使用道具 舉報

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

回復

使用道具 舉報

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

修改不出來,找不出問題在哪里,小白一個,大佬技術指導一下,感謝
回復

使用道具 舉報

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

你向串口發送數據了嗎?用hex格式發送1 試試
回復

使用道具 舉報

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

發送了,一個led都不亮
回復

使用道具 舉報

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

沒有任何反應
回復

使用道具 舉報

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

你改過的完整代碼發出來看看
回復

使用道具 舉報

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

#include<reg51.h>    //包含51單片機寄存器定義的頭文件
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;
/*************************************************
函數功能:流水燈延時
**************************************************/
void led_delay(void)
{
   unsigned char i,j;
        for(i=0;i<250;i++)
          for(j=0;j<250;j++);           
}
/*************************************************
函數功能:軟件消抖延時
**************************************************/
void delay20ms(void)
{
   unsigned char i,j;
       for(i=0;i<100;i++)
          for(j=0;j<60;j++);           
}
/*************************************************
函數功能:正向流水點亮LED
**************************************************/
void forward(void)
{                              //不能加while(1),會循環這一函數,其他按鍵控制無效
        for(x=0;x<8;x++)       
        {
                P1=tabup[x];
                led_delay();
        }               
}
/*************************************************
函數功能:反向流水點亮LED
**************************************************/
void backward(void)
{                          //不能加while(1),會循環這一函數,其他按鍵控制無效
        for(y=0;y<8;y++)
        {
                P1=tabdown[y];
                led_delay();
        }
}
/*************************************************
函數功能:關閉所有LED
**************************************************/
void stop(void)
{
        P1=0xff;    //關閉8個LED
}
/*************************************************
函數功能:閃爍點亮LED
**************************************************/
void flash(void)
{
  P1=0x00;               //點亮8個LED
  led_delay();
}
void main(void)          //主函數
{
        SCON = 0x50;           //設定串口工作方式
  PCON = 0x00;           //波特率不倍增       
  TMOD = 0x20;           //定時器1工作于8位自動重載模式, 用于產生波特率
  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;
   }
        }
}
/*************************************************
函數功能:定時器T0的中斷服務子程序
**************************************************/
void  serial() interrupt 4
{
   ES = 0;                //關閉串行中斷
   RI = 0;                //清除串行接受標志位
   keyval = SBUF;            //從串口緩沖區取得數據                                           
   ES = 1;    //允許串口中斷
}
回復

使用道具 舉報

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

#include<reg51.h>    //包含51單片機寄存器定義的頭文件
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;
/*************************************************
函數功能:流水燈延時
**************************************************/
void led_delay(void)
{
   unsigned char i,j;
        for(i=0;i<250;i++)
          for(j=0;j<250;j++);           
}
/*************************************************
函數功能:軟件消抖延時
**************************************************/
void delay20ms(void)
{
   unsigned char i,j;
       for(i=0;i<100;i++)
          for(j=0;j<60;j++);           
}
/*************************************************
函數功能:正向流水點亮LED
**************************************************/
void forward(void)
{                              //不能加while(1),會循環這一函數,其他按鍵控制無效
        for(x=0;x<8;x++)       
        {
                P1=tabup[x];
                led_delay();
        }               
}
/*************************************************
函數功能:反向流水點亮LED
**************************************************/
void backward(void)
{                          //不能加while(1),會循環這一函數,其他按鍵控制無效
        for(y=0;y<8;y++)
        {
                P1=tabdown[y];
                led_delay();
        }
}
/*************************************************
函數功能:關閉所有LED
**************************************************/
void stop(void)
{
        P1=0xff;    //關閉8個LED
}
/*************************************************
函數功能:閃爍點亮LED
**************************************************/
void flash(void)
{
  P1=0x00;               //點亮8個LED
  led_delay();
}
void main(void)          //主函數
{
        SCON = 0x50;           //設定串口工作方式
  PCON = 0x00;           //波特率不倍增       
  TMOD = 0x20;           //定時器1工作于8位自動重載模式, 用于產生波特率
  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;
   }
        }
}
/*************************************************
函數功能:定時器T0的中斷服務子程序
**************************************************/
void  serial() interrupt 4
{
   ES = 0;                //關閉串行中斷
   RI = 0;                //清除串行接受標志位
   keyval = SBUF;            //從串口緩沖區取得數據                                           
   ES = 1;    //允許串口中斷
}
回復

使用道具 舉報

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

void main(void)          //主函數
{
  SCON = 0x50;           //設定串口工作方式
  PCON = 0x00;           //波特率不倍增        
  TMOD = 0x20;           //定時器1工作于8位自動重載模式, 用于產生波特率
  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;
   }      
          
  }
}

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

使用道具 舉報

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

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

使用道具 舉報

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

使用道具 舉報

ID:858009 發表于 2021-4-27 20:00 來自觸屏版 | 顯示全部樓層
tyrl800 發表于 2021-4-27 19:46
把你電路板上12M的晶振換成11.0592M就行了

用的是開發板,是是11.596晶振
回復

使用道具 舉報

ID:824490 發表于 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 ,一直循環? 確定之后,再在串口中斷里改:
void  serial() interrupt 4
{
   ES = 0;                //關閉串行中斷
   RI = 0;                //清除串行接受標志位
   keyval = SBUF;            //從串口緩沖區取得數據                        
  
  SBUF=keyval  ;//反彈收到的數據
  
}

從上位機看看,收到的數據是不是你發出的數據,不丟碼?

回復

使用道具 舉報

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

進入了死循環,串口輸入其它字符無效
回復

使用道具 舉報

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

如果中斷優先級高的話,死循環中也要觸發中斷的
回復

使用道具 舉報

ID:858009 發表于 2021-4-28 09:47 | 顯示全部樓層
名字不是重點 發表于 2021-4-28 09:43
如果中斷優先級高的話,死循環中也要觸發中斷的

沒法實現,通過串口調用數組控制流水等,大佬,求幫忙。
回復

使用道具 舉報

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

使用道具 舉報

ID:824490 發表于 2021-4-28 09:52 | 顯示全部樓層
其次,大循環空轉,串口能反彈不?
回復

使用道具 舉報

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

能切換
回復

使用道具 舉報

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

加入中斷代碼出錯,無法編譯
回復

使用道具 舉報

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

使用道具 舉報

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

流水燈不能循環,每次到第八個led就停了,所以叫了循環,還是不可以,加while1),就不能中斷
回復

使用道具 舉報

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

把流水燈放入主循環后現在是怎樣了?如果還是不行有沒有檢查一下串口發送工具是不是加了換行?
回復

使用道具 舉報

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

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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 秋霞a级毛片在线看 | 欧美日韩中文字幕 | 国产中文字幕在线 | 久热精品在线 | 一区二区三区免费观看 | 夜夜艹天天干 | 国产视频福利一区 | 国产精品欧美一区二区三区不卡 | 午夜免费电影院 | 欧美精品在线免费 | 精品人伦一区二区三区蜜桃网站 | 天天综合91 | 久久久久久亚洲 | 不卡一区 | 黄网免费| 成年人免费在线视频 | 亚洲网站在线播放 | 日本成人区 | 成人黄视频在线观看 | 欧美精品久久 | 亚洲一区二区精品视频 | 人人干97 | 久久综合色综合 | a在线观看| 黄色三级免费 | 日本在线视频一区二区 | 成人精品一区二区三区中文字幕 | 成人av免费 | 毛片的网址 | 中文字幕第一页在线 | 性色的免费视频 | 香蕉久久a毛片 | 国产精品欧美一区二区三区不卡 | 亚洲精品九九 | 国产精品视频专区 | 国产av毛片| 欧美一级二级视频 | 99国产精品久久久久老师 | 亚洲成色777777在线观看影院 | 国产精品视频播放 | 黑人精品欧美一区二区蜜桃 |