找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索

51單片機(jī)流水燈,逐個(gè)點(diǎn)亮,我不能全部都逐個(gè)點(diǎn)亮

查看數(shù): 8582 | 評(píng)論數(shù): 39 | 收藏 0
關(guān)燈 | 提示:支持鍵盤(pán)翻頁(yè)<-左 右->
    組圖打開(kāi)中,請(qǐng)稍候......
發(fā)布時(shí)間: 2019-6-7 13:21

正文摘要:

可以實(shí)現(xiàn)閃爍、輪流點(diǎn)亮和逐個(gè)點(diǎn)亮,但暫停不行(實(shí)物不能暫停,仿真可以),求大佬改一下。 #include<reg52.h> #define uchar unsigned char #define unit unsigned int void delay_ms(unsigned int); sbit ...

回復(fù)

ID:555516 發(fā)表于 2019-7-11 16:21
suncat0504 發(fā)表于 2019-6-18 21:52
在你的代碼中,我沒(méi)有看到中斷處理中,對(duì)其他中斷做禁止和許可的操作啊

我在外部中斷INT0那里將 ET0  ET1 EX1都取反來(lái)實(shí)現(xiàn)中斷的禁止和開(kāi)啟(我之前說(shuō)我仿真可以實(shí)現(xiàn)暫停和開(kāi)始,但實(shí)物不行,后來(lái)我發(fā)現(xiàn)是我焊接的問(wèn)題,事實(shí)上仿真和實(shí)物都可以實(shí)現(xiàn)),但是都只能在按下暫停鍵后讓正在實(shí)施的中斷的代碼全部運(yùn)行完了之后才暫停,想問(wèn)下怎么實(shí)現(xiàn)按下暫停鍵就將正在運(yùn)行中斷的實(shí)物停在那里,就是說(shuō)按下暫停鍵后就停止在那個(gè)燈的位置(前段時(shí)間在期末考試沒(méi)有時(shí)間上論壇)
ID:517466 發(fā)表于 2019-6-18 21:52
czd175711 發(fā)表于 2019-6-17 21:37
我現(xiàn)在附上完整代碼了   可以幫我看看,,謝謝

在你的代碼中,我沒(méi)有看到中斷處理中,對(duì)其他中斷做禁止和許可的操作啊
ID:517466 發(fā)表于 2019-6-18 21:49
czd175711 發(fā)表于 2019-6-17 21:42
但是loopled=0xfe   循環(huán)左移 不應(yīng)該是 0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f 這樣嗎?

在我印象中,匯編語(yǔ)言的左移有兩種,一種是含進(jìn)位的,RLC A;一種是不含進(jìn)位C的左移 RL A,都是循環(huán)模式。對(duì)于循環(huán)左移一次,Bit7變成Bit0;其他的,順序左移。
但是在C語(yǔ)言中,只有<<左移,>>右移,是不具有循環(huán)方式的(抱歉沒(méi)有說(shuō)清楚),也就是說(shuō),在C語(yǔ)言中,使用<<一次后,最右側(cè)Bit0補(bǔ)零;使用>>移位一次后,最左側(cè)Bit7補(bǔ)零。
ID:564631 發(fā)表于 2019-6-18 16:29
你暫停了之后沒(méi)有保存當(dāng)前的值,當(dāng)開(kāi)啟之后丟失了當(dāng)前值,還有一個(gè)就是你暫定后,只是中斷停止了,但是外面的while循環(huán)還在執(zhí)行LED
ID:555516 發(fā)表于 2019-6-17 21:45
1441 發(fā)表于 2019-6-17 17:28
用匯編比較簡(jiǎn)單 左移右移

匯編,,,我不怎么會(huì)匯編,,,而且匯編的可看性不好,,我一個(gè)小白還是先用C語(yǔ)言來(lái)學(xué)比較好
ID:555516 發(fā)表于 2019-6-17 21:42
suncat0504 發(fā)表于 2019-6-17 16:36
循環(huán)左移場(chǎng)合,字節(jié)的Bit0會(huì)自動(dòng)補(bǔ)入0,不或上‘1’的話,會(huì)導(dǎo)致bit0對(duì)應(yīng)的LED也被點(diǎn)亮。
對(duì)于數(shù)據(jù)FF, ...

但是loopled=0xfe   循環(huán)左移 不應(yīng)該是 0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f 這樣嗎?   
ID:555516 發(fā)表于 2019-6-17 21:37
suncat0504 發(fā)表于 2019-6-17 16:41
我是給你舉個(gè)在中斷中禁止其他中斷的例子。你的程序仿真沒(méi)有問(wèn)題,寫(xiě)入芯片后不執(zhí)行,需要調(diào)試。通過(guò)管腳 ...

我現(xiàn)在附上完整代碼了   可以幫我看看,,謝謝
ID:564818 發(fā)表于 2019-6-17 17:28
用匯編比較簡(jiǎn)單 左移右移
ID:517466 發(fā)表于 2019-6-17 16:41
czd175711 發(fā)表于 2019-6-17 14:19
有個(gè)問(wèn)題想問(wèn),,,,為什么要用串口來(lái)實(shí)現(xiàn)中斷?INT0的優(yōu)先級(jí)是最高的,,那用INT0會(huì)不會(huì)更好,而且我小 ...

我是給你舉個(gè)在中斷中禁止其他中斷的例子。你的程序仿真沒(méi)有問(wèn)題,寫(xiě)入芯片后不執(zhí)行,需要調(diào)試。通過(guò)管腳輸出數(shù)據(jù)或者通過(guò)串口向PC發(fā)數(shù)據(jù),來(lái)觀察中間的處理過(guò)程。沒(méi)有你的程序,我也只能告訴你這么做。
ID:517466 發(fā)表于 2019-6-17 16:36
czd175711 發(fā)表于 2019-6-17 14:00
有段代碼不怎么理解 ,想問(wèn)一下什么意思
// 循環(huán)左移
        loopled=loopled

循環(huán)左移場(chǎng)合,字節(jié)的Bit0會(huì)自動(dòng)補(bǔ)入0,不或上‘1’的話,會(huì)導(dǎo)致bit0對(duì)應(yīng)的LED也被點(diǎn)亮。
對(duì)于數(shù)據(jù)FF,不斷左移后的變化是:FE,F(xiàn)C, F8, F0, E0,C0,80, 00
ID:555516 發(fā)表于 2019-6-17 15:29
suncat0504 發(fā)表于 2019-6-10 00:18
/** 流水燈*/
#include


哦,,,我好像理解了,|表示的應(yīng)該是或的意思吧,
ID:555516 發(fā)表于 2019-6-17 14:19
suncat0504 發(fā)表于 2019-6-13 12:50
盡量不要用取反,使用明確的賦值。比如在串口中斷中,禁止使用計(jì)時(shí)器0 的中斷時(shí),
/*------------------ ...

有個(gè)問(wèn)題想問(wèn),,,,為什么要用串口來(lái)實(shí)現(xiàn)中斷?INT0的優(yōu)先級(jí)是最高的,,那用INT0會(huì)不會(huì)更好,而且我小白,,,這個(gè)代碼有點(diǎn)看不懂。   我用INT0中斷去將EX1  ET0  ET1 取反  在仿真上可以實(shí)現(xiàn)暫停,但我將代碼燒錄進(jìn)實(shí)物  卻實(shí)現(xiàn)不了,想問(wèn)下為什么
ID:555516 發(fā)表于 2019-6-17 14:00

有段代碼不怎么理解 ,想問(wèn)一下什么意思
// 循環(huán)左移
        loopled=loopled<<1;
        // 最右補(bǔ)1,防止點(diǎn)亮最后一個(gè)LED
        loopled=loopled|1;


loopled<<1// 循環(huán)左移 到最后loopled應(yīng)該等于0X7F
那么最右補(bǔ)1 怎么能做到防止點(diǎn)亮最后一個(gè)LED


[// 最右補(bǔ)1,防止點(diǎn)亮最后一個(gè)LED
        loopled=loopled|1;】這個(gè)代碼是怎么理解的

ID:560178 發(fā)表于 2019-6-13 17:13
可以先一個(gè)一個(gè)點(diǎn)亮試試,再整合代碼逐個(gè)點(diǎn)亮,加油!
ID:561732 發(fā)表于 2019-6-13 13:48
我也在做這個(gè)
ID:517466 發(fā)表于 2019-6-13 12:50
czd175711 發(fā)表于 2019-6-13 11:01
這個(gè)我知道,我試過(guò)用中斷,但是中斷里面的代碼應(yīng)該是什么?把總中斷EA取反嗎?

盡量不要用取反,使用明確的賦值。比如在串口中斷中,禁止使用計(jì)時(shí)器0 的中斷時(shí),
/*------------------------------------------------
                     串口中斷程序
------------------------------------------------*/
void com_intr (void) interrupt 4 //串行中斷服務(wù)程序
{
    unsigned char Temp;    //定義臨時(shí)變量
    uchar i=0;
    ET=0;                  // 臨時(shí)禁止Timer0的中斷
    if(RI) {               //判斷是接收中斷產(chǎn)生
              RI=0;              //標(biāo)志位清零
              Temp=SBUF;         //讀入緩沖區(qū)的值
        SBUF=Temp;         //把接收到的值再發(fā)回電腦端
         }
   if(TI) {                //如果是發(fā)送標(biāo)志位,清零
                 comio=~comio;
     TI=0;
   }
   ET0=1;                  // 允許Timer0的中斷
}
ID:561674 發(fā)表于 2019-6-13 12:07
suncat0504 發(fā)表于 2019-6-11 22:09
while語(yǔ)句有沒(méi)有{}無(wú)所謂的。有,表示條件為真時(shí)執(zhí)行一段代碼塊,因?yàn)閳?zhí)行語(yǔ)句多,所以用{}包起來(lái)。沒(méi)有{} ...

應(yīng)該會(huì)出錯(cuò)吧
ID:555516 發(fā)表于 2019-6-13 11:01
suncat0504 發(fā)表于 2019-6-12 20:46
利用中斷控制位啊。建議你看看單片機(jī)原理。每個(gè)中斷都有自己的控制位,比如51單片機(jī)中的ET0,ET1,ES等。 ...

這個(gè)我知道,我試過(guò)用中斷,但是中斷里面的代碼應(yīng)該是什么?把總中斷EA取反嗎?
ID:517466 發(fā)表于 2019-6-12 20:58
初學(xué)編程的人,給你們提一個(gè)建議:一點(diǎn)更要養(yǎng)成良好的編程習(xí)慣。比如加注釋,變量、函數(shù)命名方式,對(duì)其縮進(jìn)等等,開(kāi)始可能覺(jué)得很煩,習(xí)慣了就好了。這樣自己做的東西,別人也容易理解。自己以后修改或者代碼重用,也不會(huì)出現(xiàn)摸不到頭腦的情況。
ID:517466 發(fā)表于 2019-6-12 20:54
czd175711 發(fā)表于 2019-6-12 19:15
那我想問(wèn)大佬個(gè)問(wèn)題,我想要實(shí)現(xiàn)用中斷去控制其他中斷的暫停和開(kāi)始該怎么做?

中斷處理中控制其它中斷,還需要考慮優(yōu)先級(jí)的問(wèn)題。比如在低級(jí)中斷中控制高級(jí)中斷,會(huì)出現(xiàn)這樣的情況:低級(jí)的在執(zhí)行高級(jí)中斷禁止的時(shí)候,還沒(méi)來(lái)得及執(zhí)行禁止語(yǔ)句的時(shí)候,高級(jí)中斷發(fā)生了。也就是說(shuō),有時(shí)候,你覺(jué)得你已經(jīng)禁止某個(gè)中斷了,結(jié)果實(shí)際運(yùn)行中,還是出現(xiàn)了那個(gè)被禁止的中斷被執(zhí)行過(guò)。這就是優(yōu)先級(jí)有高低而產(chǎn)生的問(wèn)題,在實(shí)際應(yīng)用中要加以注意。
不忙的時(shí)候,多看看原理方面的書(shū),對(duì)工作會(huì)有很大幫助的。
ID:517466 發(fā)表于 2019-6-12 20:46
czd175711 發(fā)表于 2019-6-12 19:15
那我想問(wèn)大佬個(gè)問(wèn)題,我想要實(shí)現(xiàn)用中斷去控制其他中斷的暫停和開(kāi)始該怎么做?

利用中斷控制位啊。建議你看看單片機(jī)原理。每個(gè)中斷都有自己的控制位,比如51單片機(jī)中的ET0,ET1,ES等。通常控制位=0,就表示禁止那個(gè)中斷的響應(yīng)處理?刂莆=1,表示允許那個(gè)中斷來(lái)的時(shí)候,調(diào)用對(duì)應(yīng)的中斷處理。
ID:555516 發(fā)表于 2019-6-12 19:17
數(shù)據(jù)集 發(fā)表于 2019-6-12 09:14
#include
#include
#define uint unsigned int

謝謝了,樓上的大佬已經(jīng)幫我搞定了,,,謝謝
ID:555516 發(fā)表于 2019-6-12 19:15
suncat0504 發(fā)表于 2019-6-11 22:09
while語(yǔ)句有沒(méi)有{}無(wú)所謂的。有,表示條件為真時(shí)執(zhí)行一段代碼塊,因?yàn)閳?zhí)行語(yǔ)句多,所以用{}包起來(lái)。沒(méi)有{} ...

那我想問(wèn)大佬個(gè)問(wèn)題,我想要實(shí)現(xiàn)用中斷去控制其他中斷的暫停和開(kāi)始該怎么做?
ID:559917 發(fā)表于 2019-6-12 09:26

我印象中我有做過(guò)流水燈
ID:560560 發(fā)表于 2019-6-12 09:16
如果不能的話,我建議你改一下圖
ID:560560 發(fā)表于 2019-6-12 09:14
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define led_8 P1
uchar m;
void ys (uint x)
{ uchar i;
while(x--)
for(i=0;i<120;i++);
}
void main()
{
uchar j,k;
while(1)
{
for(j=0;j<3;j++)
{
m=0x7f;
k=0;
while(k!=8)
{
m=_crol_(m,1);
led_8=m;
ys(500);
k++;
}

led_8=0xff;
ys(500);
for(j=0;j<3;j++)
{
led_8=0x55;
ys(500);
led_8=0xaa;
ys(500);
}
led_8=0xff;
ys(500);
k=0;
while(k!=8)
{
led_8<<=1;
ys(500);
k++;
}

}
}
}
ID:216226 發(fā)表于 2019-6-12 08:48
4樓的寫(xiě)的還可以了
ID:557774 發(fā)表于 2019-6-12 00:03
比我寫(xiě)的好多了,我還是個(gè)初學(xué)者
ID:517466 發(fā)表于 2019-6-11 22:09
while語(yǔ)句有沒(méi)有{}無(wú)所謂的。有,表示條件為真時(shí)執(zhí)行一段代碼塊,因?yàn)閳?zhí)行語(yǔ)句多,所以用{}包起來(lái)。沒(méi)有{}的話,條件為真時(shí),執(zhí)行緊鄰其后的一個(gè)有效語(yǔ)句,哪怕是一個(gè)“;”,表示空語(yǔ)句,什么也不做。樓主的代碼中,所有處理都放在中斷處理中執(zhí)行,所以主處理中什么都不做,僅僅是一個(gè)死循環(huán)罷了。
ID:555516 發(fā)表于 2019-6-11 20:41
冰麒麟 發(fā)表于 2019-6-11 08:26
感覺(jué)你的代碼也有一定的問(wèn)題,while(1)中無(wú)論有沒(méi)有語(yǔ)句好像都需要{}這個(gè)吧,即使是空循壞也是需要這個(gè)的

呃,,,這個(gè)我解釋不了,這個(gè)代碼是我老師說(shuō)的  我并不理解,但他說(shuō)沒(méi)錯(cuò)的
ID:554109 發(fā)表于 2019-6-11 08:26
感覺(jué)你的代碼也有一定的問(wèn)題,while(1)中無(wú)論有沒(méi)有語(yǔ)句好像都需要{}這個(gè)吧,即使是空循壞也是需要這個(gè)的
ID:555516 發(fā)表于 2019-6-10 21:53
文二 發(fā)表于 2019-6-10 01:38
逐個(gè)點(diǎn)亮不是可以用,循環(huán)左移_crol(0,1),我感覺(jué)可以用

我需要逐個(gè)點(diǎn)亮16個(gè)LED燈 所以要2個(gè)端口  ,直接用循環(huán)左移只能點(diǎn)亮一半或者2個(gè)端口一起逐個(gè)點(diǎn)亮
ID:555516 發(fā)表于 2019-6-10 20:25

很強(qiáng),,,我代碼寫(xiě)得有點(diǎn)差 ,,大佬你的代碼很強(qiáng),謝謝
ID:558594 發(fā)表于 2019-6-10 01:38
逐個(gè)點(diǎn)亮不是可以用,循環(huán)左移_crol(0,1),我感覺(jué)可以用
ID:517466 發(fā)表于 2019-6-10 00:27
我的程序中沒(méi)有使用中斷。改成中斷的話,需要調(diào)整按鈕連接的口線,連接到P3口的外部中斷管腳上(INT0或者INT1),同時(shí)把程序中P3組的循環(huán)改成P1。51的外部中斷的設(shè)置,參照的例子很多,也很簡(jiǎn)單。
設(shè)置中斷處理后,當(dāng)按鈕按下時(shí),會(huì)自動(dòng)產(chǎn)生中斷。在中斷處理中執(zhí)行l(wèi)ed()函數(shù)就可以的。
ID:517466 發(fā)表于 2019-6-10 00:21
我發(fā)給你的,沒(méi)有接入LED。你只需要仿真,看到P0,P2,P3口隨著按鈕每按一次,只有一個(gè)口線輸出0(視為點(diǎn)亮LED),并一直保持循環(huán)即可。
ID:517466 發(fā)表于 2019-6-10 00:18
/** 流水燈*/
#include<reg52.h>

#define uchar unsigned char
#define uint unsigned int
       
sbit button=P1^0;

/* 函數(shù)申明 -----------------------------------------------*/
void delay(uint z);
void led(void);

/*
********************************************************************************
** 函數(shù)名稱 : main(void)
** 函數(shù)功能 : 主函數(shù)
********************************************************************************
*/

uchar loopled=0xfe;
uchar flag=0;

void main() {
        P0=loopled;
        P2=0xFF;
        P3=0xFF;
        while(1) {
                // 按鈕按下了?
                if (button==0) {
                          delay(200);
                          // 等待按鈕松開(kāi)
                                while(button==0);
                                if (button==1) {
                                        // 按鈕按下又抬起
                                        led();
                                }
                }
        }
}

// 流水燈
void led(void) {
        // 循環(huán)左移
        loopled=loopled<<1;
        // 最右補(bǔ)1,防止點(diǎn)亮最后一個(gè)LED
        loopled=loopled|1;
  if (loopled==0xff) {
                // 一路循環(huán)完成場(chǎng)合,指向下一組
                flag++;
                // 下一組最后一個(gè)LED點(diǎn)亮
                loopled=0xFE;
                // 三組循環(huán)完成了,重新指向第一組
    if (flag==3) {
                        flag=0;
                }               
        }
        // 將循環(huán)數(shù)據(jù)送給當(dāng)前組
        switch(flag) {
                case 0:// P0組
                        P2=0xFF;  // 關(guān)閉P2組
                        P3=0xFF;  // 關(guān)閉P3組
                        P0=loopled;
                        break;
                case 1:// P2組
                        P0=0xFF;  // 關(guān)閉P0組
                        P3=0xFF;  // 關(guān)閉P3組
                        P2=loopled;
                        break;
                case 2:// P3組
                        P0=0xFF;  // 關(guān)閉P0組
                        P2=0xFF;  // 關(guān)閉P2組
                        P3=loopled;
                        break;
        }
}

/*
********************************************************************************
** 函數(shù)名稱 : delay(uint z)
** 函數(shù)功能 : 延時(shí)函數(shù)
********************************************************************************
*/
void delay(uint z)
{
    uchar j;
    for(z;z>0;z--)
        for(j=100;j>0;j--);
}

流水燈.jpg (452.12 KB, 下載次數(shù): 137)

流水燈.jpg

流水燈·.zip

9.1 KB, 下載次數(shù): 10

ID:555516 發(fā)表于 2019-6-9 19:55
tt123 發(fā)表于 2019-6-8 19:58
逐個(gè)點(diǎn)亮的部份,其實(shí)不用寫(xiě)得那麼難看懂,你寫(xiě)得簡(jiǎn)單一點(diǎn),方便自己,也方便他人。
建議先檢查,測(cè)試一下 ...

呃,, 左移的代碼是跟老師學(xué)的,,,我要做的效果是 按一下按鈕就中斷去點(diǎn)亮下一個(gè)燈,  你能幫我改一下嗎  
ID:386367 發(fā)表于 2019-6-8 19:58
逐個(gè)點(diǎn)亮的部份,其實(shí)不用寫(xiě)得那麼難看懂,你寫(xiě)得簡(jiǎn)單一點(diǎn),方便自己,也方便他人。
建議先檢查,測(cè)試一下硬件連接有沒(méi)問(wèn)題,然後拆分逐個(gè)點(diǎn)亮的代碼部份,逐一調(diào)試。

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

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

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