流水灯怎么中断循环执行下个语句

m0_73541403 2023-05-19 18:53:50

按键后一直循环执行不了下一个语句

#include <reg51.h>
#include "key.h"
#include <INTRINS.H>
#include "Delay.h"


unsigned char keynum,ledmod;
void led1()
{
    
    unsigned char i;
    P1=0xfe;
    P2=0xfe;
    for(i=0;i<=7;i++)
    {
        P1=_crol_(P1,1);
        P2=_crol_(P2,1);
        Delay(100);
    }
    i=0;
    
    }

void led2()
{
    unsigned char i;
    P1=0x7f;
    P2=0x7f;
    for(i=0;i<=7;i++)
    {
        P1=_cror_(P1,1);
        P2=_cror_(P2,1);
        Delay(100);
    }
    i=0;
}

void led3()
{
    
        while(1){
            
    unsigned char i;
        P1=0xFF;
    P2=0xFE;
        Delay(100);
        for(i=0;i<=6;i++)
        {
        P2=_crol_(P2,1);
        Delay(100);
        }
        i=0;
        P1=0xFe;
        P2=0xff;
            for(i=0;i<=7;i++)
        {    
        P1=_cror_(P1,1);
            Delay(100);
        }
        i=0;
    }

        
    }

    

void led4()
{
    unsigned char i;
        P1=0xFE;
    P2=0xFF;
        Delay(100);
        for(i=0;i<=6;i++)
        {
        P1=_crol_(P1,1);
        Delay(100);
        }
        i=0;
        P1=0xFF;
        P2=0xfe;
            for(i=0;i<=7;i++)
        {    
        P2=_cror_(P2,1);
            Delay(100);
        }
        i=0;
    }

void main()
{
    while(1)
    {
        keynum=key();
        if(keynum)
        {
            while(keynum==1){led1();}
            while(keynum==2){led2();}
            while(keynum==3){led3();}
            while(keynum==4){led4();}
        }
    }
}

...全文
76 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
CSDN-Ada助手 2023-05-19
精选
  • 打赏
  • 举报
回复
您的问题已经帮您同步至问答, 链接: https://ask.csdn.net/questions/7947940, 请您保持关注, 如果回答有帮助解决此问题, 麻烦您动动小手给相关的回答点赞, Ada会在评论区为您更新结题状态
御姐身萝莉心 2023-05-20
  • 打赏
  • 举报
回复

在最后main函数里的死循环里,建议改成四个判断,不要再嵌入while

while(1)
    {
        keynum=key();
        if(keynum == 1){
          led1();
}
else if(keynum == 2 ){
   led2();
}
    }

类似这样

御姐身萝莉心 2023-05-20
  • 举报
回复
@御姐身萝莉心 你点灯的函数中也嵌入了一个死循环while(1)
基于单片机的LED流水灯设计 设计任务 1掌握MCS-51系列8051、8255的最小电路及外围扩展电路的设计方法 2了解单片机数据转换功能及工作过程 3设计LED流水灯系统,实现8个LED霓虹灯的左、右循环显示 4完成主要功能模块的硬件电路设计 5用proteus软件完成原理电路图的绘制 一 设计方法 本课题使用AT89C51单片机时无须外扩存储器。因此,本流水灯实际上就是一个带有八个 发光二极管的单片机最小应用系统,即为由发光二极管、晶振、复位、电源等电路和必 要的软件组成的单个单片机。 如果要让接在P1.0口的LED1亮起来,那么只要把P1.0口的电平变为低电平就可以了;相 反,如果要接在P1.0口的LED1熄灭,就要把P1.0口的电平变为高电平;同理,接在P1.1 ~P1.7口的其他7个LED的点亮和熄灭的方法同LED1。因此,要实现流水灯功能,我们只 要将发光二极管LED1~LED8依次点亮、熄灭,8只LED灯便会一亮一暗的做流水灯了。 由 于人眼的视觉暂留效应以及单片机执行每条指令的时间很短,我们在控制二极管亮灭的 时候应该延时一段时间,否则我们就看不到"流水"效果了。 二 方案论证与比较 2.1循环移位法 在上个程序中我们是逐个控制P1端口的每个位来实现的,因此程序显得有点复杂,下面 我们利用循环移位指令,采用循环程序结构进行编程。我们在程序一开始就给P1口送一 个数,这个数本身就让P1.0先低,其他位为高,然后延时一段时间,再让这个数据向高 位移动,然后再输出至P1口,这样就实现"流水"效果啦。由于8051系列单片机的指令中 只有对累加器ACC中数据左移或右移的指令,因此实际编程中我们应把需移动的数据先放 到ACC中,让其移动,然后将ACC移动后的数据再转送到P1口,这样同样可以实现"流水" 效果。具体编程如下所示,程序结构确实简单了很多。 2.2查表法 上面的两个程序都是比较简单的流水灯程序,"流水"花样只能实现单一的"从左到右" 流方式。运用查表法所编写的流水灯程序,能够实现任意方式流水,而且流水花样无限 ,只要更改流水花样数据表的流水数据就可以随意添加或改变流水花样,真正实现随心 所欲的流水灯效果。我们首先把要显示流水花样的数据建在一个以TAB为标号的数据表中 ,然后通过查表指令"MOVC A,@A+DPTR"把数据取到累加器A中,然后再送到P1口进行显 示。具体源程序如下,TAB标号处的数据表可以根据实现效果的要求任意修改。 2.3位控法 这是一种比较笨但又最易理解的方法,采用顺序程序结构,用位指令控制P1口的每 一个位输出高低电平,从而来控制相应LED灯的亮灭。 本次实验我们采用的是查表法和循环移位法,这两个方法要比位控法要复杂些,但是程 序要简略的多 三 硬件设计 1单片机时钟电路 时钟电路用于产生单片机工作所需要的时钟信号,单片机本身就是一个复杂的同步时序 电路,为了保证同步工作方式的实现,电路应在唯一的时钟信号控制下严格地按时序进 行工作。 在MCS- 51芯片内部有一个高增益反相放大器,其输入端为芯片引脚X1,输出端为引脚X2,在芯 片的外部跨接晶体振荡器和微调电容,形成反馈电路,就构成了一个稳定的自激振荡器 。 此电路采用12MHz的石英晶体。时钟电路如下图: 2复位电路 电阻的作用是用于上电复位的,VCC以上电,由于电容两端电压不能突变,所以RST上为 高电平,然后电容放电,RST就为低电平了,还可以用手动复位,此电路应用自动复位。 3工作电路 工作电路就是根据总的电路的指令,来反应工作情况。本电路的流水灯电路具体的如下 : 根据各个模块的功能及他们的信号传输,连接电路如下: 四 软件设计 汇编语言和C语言的特点及选择 本设计是硬件电路和软件编程相结合的设计方案,选择合适的编程语言是一个重要的环 节。在单片机的应用系统程序设计时,常用的是汇编语言和C语言。机硬件,程序可读性 和可移植性比较差。而C语言虽然执行效率没有汇编语言高,但语言简洁,使用方便,灵 活,运算丰富,表达化类型多样化,数据结构类型丰富,具有结构化的控制语句,程序 设计自由度大,有很好的可重用性,可移植性等特点。在本设计中采用C语言编写软件程 序。 C语言程序设计 特殊功能寄存器P0一共八位,因此P0寄存器可一次存放一字节数据,寄存器的每位的输 出对应P0.0~P0.7引脚,其中P0.0为P0的低位引脚,P0.7为高位引脚。P0引脚输出高低电 平与寄存器P0存放数据一致,如程序中,P0 = 0x01时,则只有P0.0输出高电平,其它引 脚输出低电平。为了实现流水灯效果,程序设计让P0的八个引脚依次输出高电平即可。 如先让P0 = 0x01,LED1点亮,然后让P0 = 0x02,LED2点亮,依次往下操作,P0 = 0x8
实验三 定时中断实验 一、实验目的 1. 掌握51单片机外部中断的应用。 2. 掌握中断函数的写法。 3. 掌握定时器的定时方法。 4. 掌握LED数码管的显示。 二、实验内容 1. 用外部中断0测量负跳变信号的累计数,同时在LED数码管上显示出来。 2. 用外部中断改变流水灯的方式。 3. 用定时器T1的方式2控制两个LED以不同周期闪烁。 使用定时器T1的方式2来控制P0.0、P0.1引脚的两个LED分别以1s和2s的周期闪烁。 三、实验仿真硬件图 在Proteus软件中建立如下图所示仿真模型并保存。 1. 用外部中断0测量负跳变信号的累计数,同时在LED数码管上显示出来(用中断方式做计数 器)。 2.用外部中断改变流水灯的方式。 中断前:开始时,P0.0~P0.7的8个灯依次点亮。 外部中断0:P0.0~P0.7的左右4个灯闪烁亮8次 外部中断1: P0.0~P0.7的8个灯间隔闪烁8次 改变中断优先级和保护现场,观察运行结果 编程提示 外部中断0请求,由P3.2管脚输入,通过IT0位来决定是低电平有效还是下降沿 有效。一旦输入信号有效,即向CPU申请中断,并建立IE0中断标志。 以外部中断0为例,开放中断源采用以下语句: EA=1; //开放中断总允许位 EX0=1; //开放外部中断0允许位 IT0=1; //置外部中断为边沿(下边沿)触发方式 中断函数结构如下: void int_0() interrupt 0 // interrupt 0表示该函数为中断类型号0的中断函数 { } 同级自然优先级: 外部中断0 定时器T0中断 外部中断1 定时器T1中断 串行口中断中断优先级别的设定: 实验二要求: 初始状态为P0.0~P0.7的8个LED显示灯依次循环点亮;外部中断0服务程序为8个LED灯, 左4个,右4个闪烁8次,外部中断1服务程序8个LED灯,间隔闪烁8次。 设定外部中断0为高优先级,先执行外部1中断,过程中用外部0中断来将其中断,反之不 行。注意保护现场。 设定外部中断1为高优先级,先执行外部0中断,过程中用外部1中断来将其中断,反之不 行。注意保护现场。 实验三(调试下列程序,在错误行后面注明错误及改正方法): #include #define uchar unsigned char; sbit D0=P1^0; sbit D1=P1^1; uchar a,b; void main() { EA=1; ET1=1; TMOD=0x20; TL1=6; TR0=1; a=0; b=0; while(1) ; } void t1() interrupt 1 { a++; b++; if(a=1000) { D0=~D0 a=0; } if(b=4000) { D1=~D1; b=0; } 写出源程序,并注释 实验报告格式 实验三 定时中断实验 学院: 专业: 年级: 实验时间: 姓名: 学号: 指导教师: 一、实验目的 1. 掌握51单片机外部中断的应用。 2. 掌握中断函数的写法。 3. 掌握中断优先级别的使用。 4. 掌握LED数码管的显示。 二、实验内容 1. 用外部中断0测量负跳变信号的累计数,同时在LED数码管上显示出来。 2. 用外部中断改变流水灯的方式。 三、电路图(贴Protues仿真图) 四、程序与注释 1)程序1 2)程序2 3)程序3 六、简答题 1)电平触发和下降沿触发在程序中如何设置? 2)如何设置INT1为优先级?何谓优先? 3)中断服务函数的interrupt后面的数字表示什么? 七、体会 ----------------------- 实验3-外部中断实验报告全文共4页,当前为第1页。 实验3-外部中断实验报告全文共4页,当前为第2页。 实验3-外部中断实验报告全文共4页,当前为第3页。 实验3-外部中断实验报告全文共4页,当前为第4页。

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧