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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7987|回復: 46
收起左側

單片機程序只能順序點亮LED,不能關閉?怎樣能夠完成?

  [復制鏈接]
ID:595237 發(fā)表于 2020-8-10 00:34 | 顯示全部樓層 |閱讀模式
#include<reg51.h>  //包含單片機寄存器的頭文件
sbit S1=P1^0;     //將S1位定義為P1.0

/************延時us函數************************/
void delayus(unsigned int j )
{

    while(j--);
}

/*********************************************/
/*****************************
函數功能:主函數
*****************************/
void main(void)
{  
   unsigned char i ;
        i=0;                 //將i初始化為0
         
        while(1)
         {
                  if(S1==0)     //如果S1鍵按下
                   {
                          delayus(5);  //延時一段時間
                          if(S1==0) //如果再次檢測到S1鍵按下
                            i++;    //i自增1

                if(i==5)  //如果i=5,重新將其置為4
                           i=4;
                                
                   }
                 switch(i)   //使用多分支選擇語句
                                 {
                                   case 1: P0=0xfe;  //第一個LED亮
                                          delayus(600);
                                                 break;
                                        case 2: P0=0xfc;  //第二個LED亮
                                        delayus(800);
                             break;
                                        case 3:P0=0xf8;   //第三個LED亮
                                      delayus(1000);
                                  break;
                                        case 4:P0=0xf0;   //第四個LED亮
                                      delayus(1200);
                                          break;
                                
default:break;
                                  }

        
                                    }
                                 }




按住S1=0鍵點亮:第一個LED亮,第二個LED亮,第三個LED亮,第四個LED亮 ,可以。



放開S1=1鍵關閉:第四個LED滅,第三個LED滅,第二個LED滅,第一個LED滅,加上什么程序,弄了好久不能完成。


回復

使用道具 舉報

ID:10193 發(fā)表于 2020-8-10 07:48 | 顯示全部樓層
放開后i延時自減
回復

使用道具 舉報

ID:687146 發(fā)表于 2020-8-10 07:52 | 顯示全部樓層
你用的總線操,作寫入的16進制格式依次是11111110,11111100,11111000......按照你的描述來看你是低電平點亮LED,所以你要熄滅LED的話只需將對應位改成高電平即可,例如你要熄滅第一個燈點亮第二個燈只需要寫入0xFD即可。
回復

使用道具 舉報

ID:804115 發(fā)表于 2020-8-10 08:25 來自手機 | 顯示全部樓層
看到這樣的代碼,不忍直視,先練習一下如何在大循環(huán)中對一個任務進行延時而不采用delay這種干擾其它任務的方式。另外,寫代碼要逐漸形成分層思想。
回復

使用道具 舉報

ID:592807 發(fā)表于 2020-8-10 08:26 | 顯示全部樓層
可能你硬件沒弄好,按照你的代碼你的P1.0口輸入是GND的時候LED燈亮,輸入VCC是LED滅。那你的P1.0口是否有接VCC上拉和GND下拉。你這種情應該是你只是接了GND下拉,就是按下按鍵后P1.0接到GND上,所以燈正常亮,但是按鍵彈起來后沒有接到VCC上拉,P1.0腳處于懸空狀態(tài),所以沒法滅掉LED燈。
注意:懸空狀態(tài)不屬于高電平也不屬于低電平。
回復

使用道具 舉報

ID:812807 發(fā)表于 2020-8-10 09:37 | 顯示全部樓層
加一個松手檢測,之后將全部燈的引腳置1
回復

使用道具 舉報

ID:332444 發(fā)表于 2020-8-10 09:38 | 顯示全部樓層
只要了解其工作原理,你就可以隨心所欲地控制IO口輸出任意高低點平點亮和關閉。
回復

使用道具 舉報

ID:332444 發(fā)表于 2020-8-10 09:49 | 顯示全部樓層
你這個程序是每按下按鍵則點亮一個LED直到4個LED都點亮,當初次運行程序時4個LED是不亮的,如何實現釋放按鍵就第4個燈滅?因為本來就沒亮又如何去滅,滅是對亮而言的。只有當4個LED都亮才能說再次按下按鍵后從第4個LED開始滅到第1LED滅。所以說思路不清或描述不清。
回復

使用道具 舉報

ID:213173 發(fā)表于 2020-8-10 10:23 | 顯示全部樓層
  1. #include<reg51.h>  //包含單片機寄存器的頭文件
  2. sbit S1=P1^0;     //將S1位定義為P1.0

  3. /************延時us函數************************/
  4. void delayus(unsigned int j )
  5. {
  6.     while(j--);
  7. }

  8. /*****************************
  9. 函數功能:主函數
  10. *****************************/
  11. void main(void)
  12. {  
  13.         unsigned char i=0;//將i初始化為0
  14.         while(1)
  15.         {
  16.                 if(S1==0)     //如果S1鍵按下
  17.                 {
  18.                         delayus(5000);  //延時一段時間
  19.                         if(S1==0) //如果再次檢測到S1鍵按下
  20.                         {
  21.                                 if(i<4)  //加到4為止
  22.                                 {
  23.                                         i++;
  24.                                         P0<<=1;//P0左移1位低位自動補0
  25.                                 }
  26.                                 delayus(25000);//延時約1/4秒
  27.                         }
  28.                 }
  29.                 else     //如果S1鍵抬起
  30.                 {
  31.                         delayus(5000);  //延時一段時間
  32.                         if(S1==1) //如果再次檢測到S1鍵抬起
  33.                         {
  34.                                 if(i>0)  //減到0為止
  35.                                 {
  36.                                         i--;
  37.                                         P0=P0>>1|0x80;//P0右移1位高位補1
  38.                                 }
  39.                                 delayus(25000);//延時約1/4秒
  40.                         }
  41.                 }
  42.         }
  43. }
復制代碼
回復

使用道具 舉報

ID:332444 發(fā)表于 2020-8-10 10:28 | 顯示全部樓層
  1. #include "reg52.h"
  2. unsigned char code DuLiAnJian[]={255,254,252,248,240};
  3. sbit k1=P1^7;
  4. bit k = 0;
  5. void main()
  6. {
  7.         unsigned char wei=0,Xd=0;
  8.         P2=255;初始化端口
  9.         while(1)
  10.         {
  11.                 if(!k1&&!++Xd)按鍵消抖
  12.                 {
  13.                         k?--wei:++wei;按鍵操作變量
  14.                         if(wei>=4||!wei)k=~k;
  15.                         P2=DuLiAnJian[wei];控制LED
  16.                         while(!k1);按鍵釋放
  17.                 }
  18.         }
  19. }
復制代碼
錄像25_轉.gif

是否要這樣的效果?
回復

使用道具 舉報

ID:478073 發(fā)表于 2020-8-10 11:05 | 顯示全部樓層
不是加什么程序的問題,是你設的值不對,你的值是依次是原來亮過的反向值
回復

使用道具 舉報

ID:280512 發(fā)表于 2020-8-10 11:14 | 顯示全部樓層
delayus();  p0=0xff; break;可以吧
回復

使用道具 舉報

ID:595237 發(fā)表于 2020-8-11 08:13 | 顯示全部樓層
謝謝你們的幫助,還是不能解決 題目的 要求,看看題目也不是好難的,就是調試不出來。

按鍵已經上拉10K  接  +   ,

按住按鍵=0 保持,不放開,  LED1亮,延時, LED2亮,延時, LED3亮,延時, LED4亮。

放開按鍵=1  , LED4滅,延時, LED3滅,延時, LED2滅,延時, LED1滅。
回復

使用道具 舉報

ID:595237 發(fā)表于 2020-8-11 08:14 | 顯示全部樓層

調試了,只是點亮led1,下面不會遞加,沒有反應。
回復

使用道具 舉報

ID:595237 發(fā)表于 2020-8-11 08:14 | 顯示全部樓層
xianfajushi 發(fā)表于 2020-8-10 10:28
是否要這樣的效果?

調試了,按鍵按一次,點亮一次,點亮完成,按鍵再按一次 滅一次,

就是不會自動點亮,自動滅。
回復

使用道具 舉報

ID:595237 發(fā)表于 2020-8-11 08:18 | 顯示全部樓層
黃youhui 發(fā)表于 2020-8-10 08:26
可能你硬件沒弄好,按照你的代碼你的P1.0口輸入是GND的時候LED燈亮,輸入VCC是LED滅。那你的P1.0口是否有接 ...

按鍵已經上拉10K  接  +   ,

p0口接  LED   - 負    接 電阻 接 +   。
回復

使用道具 舉報

ID:595237 發(fā)表于 2020-8-11 08:29 | 顯示全部樓層
2538076292 發(fā)表于 2020-8-10 07:52
你用的總線操,作寫入的16進制格式依次是11111110,11111100,11111000......按照你的描述來看你是低電平點亮 ...

111111111,11111110,11111100,11111000,11110000

11110000,11111000,11111100,11111110,111111111
回復

使用道具 舉報

ID:332444 發(fā)表于 2020-8-11 09:22 | 顯示全部樓層
按鍵按住自動遞增,釋放自動遞減。
  1. #include "reg52.h"
  2. unsigned char code DuLiAnJian[]={255,254,252,248,240};
  3. sbit k1=P1^7;
  4. bit k = 0;
  5. void main()
  6. {
  7.         unsigned char wei=0,Xd=0;
  8.         unsigned int YS=47474;
  9.         P2=255;
  10.         while(1)
  11.         {
  12.                 if(!k1)k=0;else k=1;
  13.                 if(!++YS)
  14.                 {
  15.                         if(wei<4&&!k)++wei;
  16.                         if(wei>0&&k)--wei;
  17.                         P2=DuLiAnJian[wei];
  18.                         YS=k?7474:47474;
  19.                 }
  20.         }
  21. }
復制代碼
回復

使用道具 舉報

ID:578842 發(fā)表于 2020-8-11 11:01 | 顯示全部樓層
xianfajushi 發(fā)表于 2020-8-11 09:22
按鍵按住自動遞增,釋放自動遞減。

總工程師厲害,我試過,這個程序對的。
回復

使用道具 舉報

ID:332444 發(fā)表于 2020-8-11 11:13 | 顯示全部樓層
  1. #include "reg52.h"
  2. unsigned char code DuLiAnJian[]={255,254,252,248,240};
  3. sbit k1=P1^7;
  4. bit k = 0;
  5. void main()
  6. {
  7.         unsigned char wei=0,Xd=0;
  8.         unsigned int YS=47474;
  9.         P2=255;
  10.         while(1)
  11.         {
  12.                 if(!++YS)
  13.                 {
  14.                         if(wei<4&&!k1)++wei;
  15.                         else if(wei>0&&k1)--wei;
  16.                         P2=DuLiAnJian[wei];
  17.                         YS=k1?27474:47474;
  18.                 }
  19.         }
  20. }
復制代碼

影響延時參數
回復

使用道具 舉報

ID:813259 發(fā)表于 2020-8-11 16:00 來自手機 | 顯示全部樓層
那你就在最后加上P0=0xff就好了
回復

使用道具 舉報

ID:595237 發(fā)表于 2020-8-11 17:36 | 顯示全部樓層

總工程師厲害,調試過了,能夠用,就延時改了好久,難調出?
回復

使用道具 舉報

ID:332444 發(fā)表于 2020-8-11 18:23 | 顯示全部樓層
YS=k1?474:747;
回復

使用道具 舉報

ID:332444 發(fā)表于 2020-8-11 18:34 | 顯示全部樓層
如果充分理解程序,調節(jié)延時時間這點小技巧不該被難住。
回復

使用道具 舉報

ID:332444 發(fā)表于 2020-8-11 18:43 | 顯示全部樓層
應當理解程序,不當只會復制粘貼運行看效果。
回復

使用道具 舉報

ID:332444 發(fā)表于 2020-8-12 05:03 | 顯示全部樓層
假如 if(!++YS)不好理解不妨用 if(!--YS)再調節(jié)YS=k1?474:747;值或許好理解些,體會知識點的應用。
回復

使用道具 舉報

ID:332444 發(fā)表于 2020-8-12 05:22 | 顯示全部樓層
如果YS=k1?4:7;還是時間不夠長,可設另一個變量予以延長延時時間用即可,如普通的嵌套循環(huán)一樣道理,YS計數完畢令另設的變量計數,當另設變量計數達到數值才執(zhí)行功能語句即可。
回復

使用道具 舉報

ID:332444 發(fā)表于 2020-8-12 07:26 | 顯示全部樓層
if(!++YS&&!++Xd)修改成這樣看看時間夠長?
回復

使用道具 舉報

ID:599260 發(fā)表于 2020-8-12 15:22 | 顯示全部樓層
你設的值不對,你的值是依次是原來亮過的反向值
回復

使用道具 舉報

ID:595237 發(fā)表于 2020-8-12 22:21 | 顯示全部樓層
xianfajushi 發(fā)表于 2020-8-12 07:26
if(!++YS&&!++Xd)修改成這樣看看時間夠長?

謝謝指點!

晚上調試一下 ,一直用快速計算 i, j  ,k 延時,
比如晶振12mhz ,   i-6,j=116,k=214   ,時間50000us
11.0592mhz,i=22,j=36,k=173,時間50000us,

新接觸這樣的延時,不懂調到需要的值。
回復

使用道具 舉報

ID:595237 發(fā)表于 2020-8-12 23:55 | 顯示全部樓層
xianfajushi 發(fā)表于 2020-8-12 07:26
if(!++YS&&!++Xd)修改成這樣看看時間夠長?

if(!++YS&&!++Xd)     不起用處,第一個LED也不亮,

if(!--YS)    能夠用   47474 延時最長,也不夠,

if(!++YS) 能夠用   1   延時最長,也不夠,

i=211,j-255,k=255  晶振11.0592Mhz   可以延時  5s
回復

使用道具 舉報

ID:332444 發(fā)表于 2020-8-13 06:05 | 顯示全部樓層
通常作為演示一個INT足夠了,要達到秒的延時最好用定時器,因為計數延時是無法準確的;
YS=0,Xd=0;if(!++YS&&!++Xd) 這樣寫等于65536*255這個值應該知道,if(++YS==?&&++Xd==?)  都是可以隨意的
if(!++YS){if(!++Xd) {。。。}}看來你的學習還任重道遠,其實這些都是基本語句和邏輯,之上已經說得明白,還可以繼續(xù)嵌套延時if(!++YS){if(!++Xd) {if()++d=={。。。}}}達到延時目標,不過一個CHAR一個INT變量達到5秒應該足夠。
回復

使用道具 舉報

ID:332444 發(fā)表于 2020-8-13 06:24 | 顯示全部樓層
if(!++YS&&!++Xd)     不起用處,第一個LED也不亮,這個不是不能用而是延時超出了你預期等待的時間了,最大值為65536*255,可用一個開關替代按鍵測試到底這個值能延時多長時間。

if(!--YS)    能夠用   47474 延時最長,也不夠,這個值不是最長65536才最長

if(!++YS) 能夠用   1   延時最長,也不夠,這個值為0才最長

雖然看起來有點吹毛求疵,不過麗是這樣的分析。
回復

使用道具 舉報

ID:213173 發(fā)表于 2020-8-13 08:30 | 顯示全部樓層
juncedz 發(fā)表于 2020-8-11 08:14
調試了,只是點亮led1,下面不會遞加,沒有反應。

這是經過驗證的程序你還玩不轉,說明你的硬件電路有問題。
回復

使用道具 舉報

ID:136485 發(fā)表于 2020-8-13 09:01 | 顯示全部樓層
你是按下要一直保持這個狀態(tài),還是松開按鍵就不亮,因為你那循環(huán)里只有四種燈點亮的狀態(tài),你要關掉的還是在循環(huán)里加一個關掉的功能比如if(s1>4){P0=0xFF;}就可以關掉了,你都沒有關掉這步,除非你剛上電S1=0燈是不亮的
回復

使用道具 舉報

ID:332444 發(fā)表于 2020-8-13 09:03 | 顯示全部樓層
按純粹的計數延時計算65536*255=16.7秒*1。08=18秒,12M與11.0592M差不離。而仿真運行到1秒其實實際時間不止1秒,因此,仿真會顯得很長時間。
211*255*255還比65536*255小呢,變量占用大小2個是一樣的,這些都是可分析的,也是基礎知識,莫學無知之輩說用3個CHAR比用1個INT和1個CHAR占用少。
回復

使用道具 舉報

ID:332444 發(fā)表于 2020-8-13 09:06 | 顯示全部樓層
本帖最后由 xianfajushi 于 2020-8-13 09:47 編輯

如果認真計算3個char等同1個int和1個char,256*256*256==65536*256。
回復

使用道具 舉報

ID:595237 發(fā)表于 2020-8-13 16:46 | 顯示全部樓層
xianfajushi 發(fā)表于 2020-8-13 09:06
如果認真計算3個char等同1個int和1個char,256*256*256==65536*256。

謝謝你的指教,我真的是菜鳥,只是想學習,
調試delay(5)  的時間是正確的。
void delay(unsigned char time)
{    unsigned char i,j,k;
       while(time--)
        for(k=46;k>0;k--)
        for(j=152;j>0;j--)
        for(i=70;i>0;i--)   
}

delay(5)    差不多 5s


unsigned int YS=47474;
YS=k1?47474:47474;
if(!++YS&&!++Xd)    用這樣的差不多延時2分鐘,  所以我昨晚說沒有亮燈 ,
是我說錯了,不是程序錯 ,是時間太久,沒有亮燈,不會調節(jié)到5s。

unsigned int YS=0;
YS=k1?0:0;
if(!++YS&&!++Xd)    也是差不多延時2分鐘.
回復

使用道具 舉報

ID:595237 發(fā)表于 2020-8-13 16:53 | 顯示全部樓層
kxcuser 發(fā)表于 2020-8-13 09:01
你是按下要一直保持這個狀態(tài),還是松開按鍵就不亮,因為你那循環(huán)里只有四種燈點亮的狀態(tài),你要關掉的還是在 ...

謝謝,關 也是需要 延 時關 的。
回復

使用道具 舉報

ID:595237 發(fā)表于 2020-8-13 16:56 | 顯示全部樓層
wulin 發(fā)表于 2020-8-13 08:30
這是經過驗證的程序你還玩不轉,說明你的硬件電路有問題。

謝謝,電路絕對沒有錯,程序也是正確,

就是 延時差不多2分鐘,

不懂調節(jié) 到5s
回復

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产成人免费在线 | 午夜精品久久 | 精品日韩 | 日本在线黄色 | 一级片在线播放 | 中文字幕av网站 | 成人av片在线观看 | 波多野吉衣久久 | 国产韩国精品一区二区三区 | 欧美激情综合 | 国产精品高清一区二区 | 亚洲精品视频一区 | 在线观看日本高清二区 | 在线免费观看成人 | 99伊人网| 欧美综合一区二区三区 | 草草网 | 午夜电影福利 | 视频一区二区三区中文字幕 | www中文字幕| a国产一区二区免费入口 | 久久久网| 天天射影院 | 亚洲国产精品成人无久久精品 | 久久91av | 美女国产精品 | 欧美国产日韩一区二区三区 | 亚洲成人av | 亚洲精品1区 | 免费人成激情视频在线观看冫 | 亚洲国产精品va在线看黑人 | 亚洲成人精品一区二区 | 91久久国产综合久久91精品网站 | 在线区 | 色婷婷久久久亚洲一区二区三区 | 国产一区二区三区 | 91国产精品 | 热久久久 | 亚洲成人一区二区 | 欧美三级在线 | 婷婷在线网站 |