51单片机实验有没有人教一下

这是我敲的代码,但无法实现实验效果
一个开关控制两个程序,一个为霹雳灯,一个为灯的奇偶变换


#include 
#include 
#define uchar unsigned char
#define uint  unsigned int
uchar tab[] = { 0x7e,0xbd,0xdb,0xe7,0xdb,0xbd };
sbit key = P0 ^ 7;
uchar a;
void delay(uint b)
{
    uchar t;
    while (b--)
    {
        for (t = 0; t < 120; t++);
    }
}
void main()
{
    unsigned char zt = 0;
    P1 = 0x55;
    while (1)
    {
        if (key == 0) { 
            delay(100);  
            if (key == 0) {
                zt = !zt; 
                if (zt == 0) P1 = 0x55;
            }
            while (!key);
        }
        switch (zt)
        {
        case 0:
            delay(500);
            P1 = crol(P1, 1);
            break;
        case 1:
            for (a = 0; a < 6; a++)
            {
                P1 = tab[a];
                delay(500);
            }
            break;
        }
    }
}

:你的代码中,在奇偶变换的case 1中,你只是将P1赋值为预先定义的一个字符数组中的值,并没有做出奇偶变换的操作。你需要在循环中根据奇偶性对P1进行操作。
参考一下

#include <reg51.h>
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int

uchar tab[] = { 0x7e, 0xbd, 0xdb, 0xe7, 0xdb, 0xbd };

sbit key = P0 ^ 7;

void delay(uint b)
{
    uchar t;
    while (b--)
    {
        for (t = 0; t < 120; t++);
    }
}

void main()
{
    unsigned char zt = 0;
    P1 = 0x55;
    while (1)
    {
        if (key == 0)
        {
            delay(100);
            if (key == 0)
            {
                zt = !zt;
                if (zt == 0) P1 = 0x55;
            }
            while (!key);
        }
        switch (zt)
        {
        case 0:
            delay(500);
            P1 = _crol_(P1, 1); // 使用函数_crol_对P1进行循环移位
            break;
        case 1:
            for (uchar i = 0; i < 8; i++)
            {
                if ((P1 & 0x01) == 0) // 判断奇偶性
                {
                    P1 = P1 >> 1;
                    P1 = P1 | 0x80;
                }
                else
                {
                    P1 = P1 >> 1;
                }
                delay(500);
            }
            break;
        }
    }
}


  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/750922
  • 这篇博客你也可以参考下:物联网卡信号不稳定怎么解决?51物联卡
  • 除此之外, 这篇博客: 51单片机的延时计算中的 最后是指令周期:这个是单片机执行一条指令所需要的时间,它是由机器周期组成的。 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 现在可以回到正文开头的代码中了。这个10us的函数是怎么得出来的呢?
    这个我之前查过很多资料,比如执行while语句需要多少个机器周期。赋值需要多少个周期。也就是查这个占用了我很大一部分时间。直到最后将上面的延时函数直接调到main函数中debug调试,才明白,问题其实很简单啊。
    无论是执行什么语句,最终都会回到汇编上来,debug里单步调试,所有的指令周期就会明明白白了。
    我用main函数直接调用延时函数,如下:

    void Delay10us()		//@12.000MHz
    {
    	unsigned char i;
    
    	_nop_();
    	_nop_();
    	i = 27;
    	while (--i);
    }
    main
    {
        Delay10us();
    }
    

    我用的keil软件,将上述build之后,点击debug,开始调试
    .在这里插入图片描述
    看图片上,开始debug,程序的起始就在C:0x0183 020171 LJMP Delay10us(C:0171),
    这里有个长转移指令LJMP,它要转移到C:0171行去执行Delay10us这个函数。
    那执行LJMP这个指令需要多长时间呢,查找STC数据手册,在1T模式下,此条指令在单片机上运行需要4个时钟周期。
    接下来,按单步调试F11键,如下图:
    在这里插入图片描述
    程序成功转移到C:0171行,跳转到Delay10us函数中,此行程序执行NOP指令,空操作。查STC数据手册,NOP指令占用1个时钟周期。
    接下来C:0172行,依然是NOP指令,1个时钟周期。
    接下来C:0173行,此行执行 MOV R7,#0x1B,将立即数送入寄存器。是将27赋值给i。依然查手册,此条指令2个时钟周期。
    继续:
    在这里插入图片描述
    此时执行到while语句了,这里执行的指令时 DJNZ R7,C:0175,寄存器减1非0转移。此条指令执行1次4个时钟周期。
    上面已经将寄存器填入27了,因此这条指令将执行27次。
    继续:
    在这里插入图片描述
    循环了27次,终于到0了,程序继续向下执行,此行指令RET,子程序返回。此条指令4个时钟周期。
    继续:
    在这里插入图片描述
    程序又回到了起点。
    好了,可以计算一下此次延时的时间了。1个LJMP,4时钟;2个NOP,2时钟;1个MOV,2时钟;27个DJNZ,108时钟;1个RET,4时钟。
    4+2+2+108+4=120。
    单片机的时钟周期是:1(S)/12MHz = 1/12(us)
    此次延时的时间是:120 × 1/12(us)= 10(us)

  • 您还可以看一下 2017CCTC大会老师的【微服务专场】实施微服务架构的关键技术课程中的 实施微服务架构的关键技术小节, 巩固相关知识点