C - 在 C 8051 中递增 18 位

C - Increment 18 bits in C 8051

我已经对 8051 进行了大约两个月的编程,对 C 语言来说还是个新手。我目前正在使用闪存来读取、写入、擦除和分析它。我目前正在写阶段工作,我需要做的任务之一是指定一个地址位置并用数据填充该位置,然后递增到下一个位置并用补充数据填充它。依此类推,直到我到达终点。

我的困境是我有 18 个地址位可以使用,目前为这 18 个位分配了三个字节。无论如何,我可以将这 18 位组合成 intunsigned int 并像这样递增吗?或者是我增加第一个字节的唯一选择,然后当该字节翻转到 0x00 时增加下一个字节,当那个字节翻转时,增加下一个字节?

我目前有:

void inc_address(void)
{
    P6=address_byte1;
    P7=address_byte2;
    P2=address_byte3;
    P5=data_byte;

    while(1)
    {
        P6++;
        if(P6==0x00){P7++;}
        else if(P7==0x00){P2++;}
        else if(P2 < 0x94){break;} //hex 9 is for values dealing with flash chip
        P5=~data_byte;
    }
}

Is there anyway that I could combine those 18 bits into an int or unsigned int and increment like that?

当然可以。假设 intunsigned int 在你的系统上至少有 18 位宽,你可以这样做:

unsigned int next_address = (hi_byte << 16) + (mid_byte << 8) + low_byte + 1;
hi_byte = next_address >> 16;
mid_byte = (next_address >> 8) & 0xff;
low_byte = next_address & 0xff;

<<>>是位移运算符,二进制&是"and"位运算符。

但是,不对类型的大小做出假设会更加安全和便携。为避免这种情况,请包含 stdint.h,并使用类型 uint_least32_t 而不是 unsigned int:

uint_least32_t next_address = ((uint_least32_t) hi_byte << 16)
        + ((uint_least32_t) mid_byte << 8)
        + (uint_least32_t) low_byte
        + 1;

// ...

其中 addressuint32_t:

void inc_address(void)
{
    // Increment address
    address = (address + 1) & 0x0003ffff ;

    // Assert address A0 to A15
    P6 = (address & 0xff)
    P7 = (address >> 8) & 0xff

    // Set least significant two bits of P2 to A16,A17 
    // without modifying other bits in P2
    P2 &= 0xFC ;                   // xxxxxx00
    P2 |= (address >> 16) & 0x03 ; // xxxxxxAA

    // Set data
    P5 = ~data_byte ;
}

但是不清楚为什么该函数被调用 inc_address 但也将 P5 赋值给 ~data_byte,这大概断言了数据总线?它所做的不仅仅是看起来增加一个地址,所以它的命名很糟糕且容易混淆。我还建议函数应该将地址和数据作为参数而不是 global data.