C - 在 C 8051 中递增 18 位
C - Increment 18 bits in C 8051
我已经对 8051 进行了大约两个月的编程,对 C 语言来说还是个新手。我目前正在使用闪存来读取、写入、擦除和分析它。我目前正在写阶段工作,我需要做的任务之一是指定一个地址位置并用数据填充该位置,然后递增到下一个位置并用补充数据填充它。依此类推,直到我到达终点。
我的困境是我有 18 个地址位可以使用,目前为这 18 个位分配了三个字节。无论如何,我可以将这 18 位组合成 int
或 unsigned 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?
当然可以。假设 int
和 unsigned 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;
// ...
其中 address
是 uint32_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.
我已经对 8051 进行了大约两个月的编程,对 C 语言来说还是个新手。我目前正在使用闪存来读取、写入、擦除和分析它。我目前正在写阶段工作,我需要做的任务之一是指定一个地址位置并用数据填充该位置,然后递增到下一个位置并用补充数据填充它。依此类推,直到我到达终点。
我的困境是我有 18 个地址位可以使用,目前为这 18 个位分配了三个字节。无论如何,我可以将这 18 位组合成 int
或 unsigned 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?
当然可以。假设 int
和 unsigned 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;
// ...
其中 address
是 uint32_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.