蒗枫_卟残 ﻬ 2023-03-04 20:18 采纳率: 50%
浏览 88
已结题

51流水灯操作时遇到的简单问题,想要问的在最下面,望解答。

运行环境:在51系列中使用的是AT89C52芯片,编译软件为keil4。
目的:在定时器流水灯项目中,按下按钮使led全灭,再按一次使led在熄灭位置亮起,继续进行流水灯操作。
问题:在实现过程中,设定了一个整形变量m,为了去保存P1的状态,然后再把m赋予P1实现原位置亮起,但发现不成,于是单独写了个定时流水灯程序,不加按钮,探究整形m与P1的关系
代码如下:


#include<reg52.h>
#include<intrins.h>

int i = 0;
void timer1_init()
{
    TMOD = 0x10; 
    TH1 = 0x4C;    
    TL1 = 0x00; 
    EA = 1;            
    ET1 = 1;        
    TR1 = 1;         
}

void main()
{
    int x=0,m;

    timer1_init();
     P1 = 0xfe;
    while(1)
    {
        if(i==40)
        {
             P1 =_crol_(P1,1);
          i = 0; 
            x++;
        }
        if(x==2)
        {
            m=P1;
            P1=0xff;
        }
        if(x==4)
        {
            P1=m;
        }
        if(x==6)
        {
            P1=0xfe;
            x=0;
        }
    }
}

void timer1() interrupt 3
{
    TH1 = 0x4C;    
    TL1 = 0x00;
    i++;
}

现象:流水灯正常工作,在第二位时熄灭,等待后未在原位亮起继续流水灯操作,长时间等待后,从第一位亮起
想要了解的问题 :一.sfr P1=0x80特殊寄存器是否能被指针指向
二.整形变量保存的地址是以二进制存储后输出来是否仍为地址,是否是存储溢出导致无法实现目标
三.怎么做才能用一个量,而不是数组来实现目标

不知道有没有有缘人看到这个问题,问的比较基础,希望能够解答一二。

  • 写回答

7条回答 默认 最新

  • dahe0825 2023-03-04 20:52
    关注

    参考chatGPT的内容和自己的思路,
    1.可以将特殊功能寄存器(SFR)P1的地址存储在指针中,并通过指针对其进行操作。例如,可以使用以下代码将P1的地址存储在指针p中,并通过p对其进行操作:
    unsigned char *p;
    p = 0x80;
    *p = 0xff;
    2.整型变量保存的地址是一个十六进制数,可以通过使用%p格式符将其以十六进制形式输出。如果地址存储溢出,那么程序将会出现错误,无法正常工作。

    3.可以使用一个标志变量来实现目标,例如将变量flag初始化为0,当按下按钮时将flag设置为1,当再次按下按钮时将flag设置为0,并将LED灯在熄灭位置亮起。然后在主循环中检查flag的值,如果为1,则不执行流水灯操作,如果为0,则执行流水灯操作。以下是代码:

    #include <reg52.h>
    #include <intrins.h>
    
    int i = 0;
    int flag = 0;
    
    void timer1_init()
    {
    TMOD = 0x10;
    TH1 = 0x4C;
    TL1 = 0x00;
    EA = 1;
    ET1 = 1;
    TR1 = 1;
    }
    
    void main()
    {
    int x = 0;
    int m = 0;
    timer1_init();
    P1 = 0xfe;
    
    while(1)
    {
        if (flag == 0)
        {
            if (i == 40)
            {
                P1 =_crol_(P1,1);
                i = 0; 
                x++;
            }
        
            if (x == 6)
            {
                P1 = 0xfe;
                x = 0;
            }
        }
        
        if (P3_0 == 0)
        {
            flag = 1;
            P1 = 0xff;
            while (P3_0 == 0);
        }
        
        if (flag == 1 && P3_0 == 0)
        {
            flag = 0;
            P1 = 0x7f;
            while (P3_0 == 0);
        }
    }
    }
    
    void timer1() interrupt 3
    {
    TH1 = 0x4C;
    TL1 = 0x00;
    i++;
    }
    

    在这个代码中,当按下按钮时,程序将flag设置为1,将LED全灭。当再次按下按钮时,程序将flag设置为0,并将LED在熄灭位置亮起。在主循环中,如果flag为1,则不执行流水灯操作,如果为0,则执行流水灯操作。

    回答不易,还请一定采纳!!!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(6条)

报告相同问题?

问题事件

  • 系统已结题 3月19日
  • 已采纳回答 3月11日
  • 修改了问题 3月4日
  • 创建了问题 3月4日

悬赏问题

  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改