前言
在上一章中,我们写出了第二个接口并在测试用例的保障下进行了重构。接下来的事就很程序化了。查看下一个操作的文档,写测试,实现接口。
流水账
ProgramInPage

分页内编程的接口,操作符后3字节地址,然后一直传要写入的字节。
别看文档上介绍了一堆机制,其实咱在写这个接口时并不关心,因为这是很底层的接口,只提供操作的抽象,具体怎么应用这些机制咱不负责。唯一需要关心下的是256字节的上限,如果超过256字节时会有一些异常啥的话可能我们需要检查下参数。但是阅读文档发现超过了并没有关系,只是会在芯片内部缓冲区覆盖前面写入的。那就无所谓了。
没什么好说的,测试,实现,完成。。。
AT26DF.h
// description: allows anywhere from a single byte of data to 256 bytes of data to be programmed
// into previously erased memory locations.
// parameter : addr the starting address
// buf data buffer.
// len the length of data you want to write.
// return :
// note : if data goes beyond the end of the page will wrap around back to the beginning
// of the same page. So, only the last 256 bytes(size of a page) will be programmed
// into the page specified by addr.
void AT26DF_programInPage(AT26DF_ADDR addr, const uint8_t *buf, uint16_t len);
AT26DFTest.c
TEST(AT26DF, 0LenOrBufNULLDoNothing){
……
AT26DF_programInPage(anyAddr,buf,0);
AT26DF_programInPage(anyAddr,NULL,1);
}
TEST(AT26DF, programInPage){
AT26DF_ADDR startAddr = 0x3434;
SPI_SelectCS_Expect();
SPI_writeByte_Expect(AT26DF_OPC_PROGRAM);
_WriteAddrExpect(startAddr);
for(i = 0; i < len; i++)
SPI_writeByte_Expect(expectData[i]);
SPI_DeselectCS_Expect();
AT26DF_programInPage(startAddr,expectData,len);
}
AT26DF.c
void AT26DF_programInPage(AT26DF_ADDR addr, const uint8_t *buf, uint16_t len){
if(buf == NULL || len == 0)
return;
_csSel();
_spiWrite(AT26DF_OPC_PROGRAM);
_writeAddr(addr);
_spiBurstWrite(buf,len);
_csDesel();
}
BlockErase

擦除扇区,有点意思,有三种擦除模式,因此我们的接口可能得给三个。当然也可以多加一个参数来指定是哪一个,但我就是觉得给三个比较好。这个操作很简单,就是操作码加地址。
AT26DF.h
……
#define AT26DF_OPC_BLOCKERASE_4KB 0x20
#define AT26DF_OPC_BLOCKERASE_32KB 0x52
#define AT26DF_OPC_BLOCKERASE_64KB 0xD8
……
// description: Erase a block of 4K-, 32K-, or 64K-bytes
// parameter : addr any address in the block to be erased.
// return :
// note : Before a Block Erase command can be started, the WriteEnable command must have
// been previously issued to the device to set the WEL bit of the Status Register
// to a logical “1” state.
// for a 4K-byte erase, address bits A11-A0 will be ignored by the device and their
// values can be either a logical “1” or “0”. For a 32K-byte erase, address bits
// A14-A0 will be ignored, and for a 64K-byte erase, address bits A15-A0 will be
// ignored by the device.
void AT26DF_blockErase4KB(AT26DF_ADDR addr);
void AT26DF_blockErase32KB(AT26DF_ADDR addr);
void AT26DF_blockErase64KB(AT26DF_ADDR addr);
AT26DFTest.c
……
TEST(AT26DF, blockErase4KB){
AT26DF_ADDR startAddr = 0x34dfa;
SPI_SelectCS_Expect();
SPI_writeByte_Expect(AT26DF_OPC_BLOCKERASE_4KB);
_WriteAddrExpect(startAddr);
SPI_DeselectCS_Expect();
AT26DF_blockErase4KB(startAddr);
}
TEST(AT26DF, blockErase32KB){
AT26DF_ADDR startAddr = 0x34dfa;
SPI_SelectCS_Expect();
SPI_writeByte_Expect(AT26DF_OPC_BLOCKERASE_32KB);
_WriteAddrExpect(startAddr);
SPI_DeselectCS_Expect();
AT26DF_blockErase32KB(startAddr);
}
TEST(AT26DF, blockErase64KB){
AT26DF_ADDR startAddr = 0x34dfa;
SPI_SelectCS_Expect();
SPI_writeByte_Expect(AT26DF_OPC_BLOCKERASE_64KB);
_WriteAddrExpect(startAddr);
SPI_DeselectCS_Expect();
AT26DF_blockErase64KB(startAddr);
}
AT26DF.c
……
void AT26DF_blockErase4KB(AT26DF_ADDR addr){
_csSel();
_spiWrite(AT26DF_OPC_BLOCKERASE_4KB);
_writeAddr(addr);
_csDesel();
}
void AT26DF_blockErase32KB(AT26DF_ADDR addr){
_csSel();
_spiWrite(AT26DF_OPC_BLOCKERASE_32KB);
_writeAddr(addr);
_csDesel();
}
void AT26DF_blockErase64KB(AT26DF_ADDR addr){
_csSel();
_spiWrite(AT26DF_OPC_BLOCKERASE_64KB);
_writeAddr(addr);
_csDesel();
}
哦,明显的冗余。让我们来提取下。
AT26DFTest.c
……
static AT26DF_ADDR startAddr

本文详细介绍了嵌入式驱动模块的开发过程,从接口设计、测试用例编写到重构优化,全程未使用实际硬件。通过理解芯片手册,实现了包括分页编程、扇区擦除、状态寄存器读写等功能的驱动,并通过单元测试确保代码正确性。
最低0.47元/天 解锁文章
1544

被折叠的 条评论
为什么被折叠?



