📄 at45db_flashm.nc
字号:
module AT45DB_FlashM {
provides interface AT45DB_Flash as FLASH ;
}
implementation
{
/*********************************************
硬件环境:
ATMEG128 ------AT45DB041
PD2 --------SO
PD3 --------SI
PD5 --------SCK
PA3 --------CS
*************************************************/
typedef uint8_t uchar ;
typedef uint8_t UCHAR ;
typedef uint16_t uint ;
typedef uint16_t UINT ;
#define SETB(x, y) (x |= (1 << y)) //位置1
#define CLRB(x, y) (x &= (~(1 << y))) //位置0
#define CHKB(x, y) (x & (1 << y)) //位判断
//设置SPI选中与否
#define SPISimulate_CS_Enable() TOSH_CLR_FLASH_SELECT_PIN()
#define SPISimulate_CS_Disable() TOSH_SET_FLASH_SELECT_PIN()
//设置SPI输出高低电平
#define SPISimulate_SET_MOSI() TOSH_SET_FLASH_OUT_PIN()
#define SPISimulate_CLR_MOSI() TOSH_CLR_FLASH_OUT_PIN()
//设置SPI输出CLK高低电平
#define SPISimulate_SET_CLK() TOSH_SET_FLASH_CLK_PIN()
#define SPISimulate_CLR_CLK() TOSH_CLR_FLASH_CLK_PIN()
void SPISimulate_Init()
{
TOSH_MAKE_FLASH_SELECT_OUTPUT();
TOSH_MAKE_FLASH_OUT_OUTPUT(); //pd3
TOSH_MAKE_FLASH_CLK_OUTPUT();
TOSH_MAKE_FLASH_IN_INPUT(); //pd2
}
/*******************************************************
在CLK的上升沿开始写入数据,开始时SS位片选信号,
描述:SPI模拟写字节
参数:send_data
*******************************************************/
void SPISimulate_WriteByte(uchar send_data)
{
//上升沿发送数据,其模式0
uchar i;
for(i=0;i<8;i++)
{
//开始传输一个数据
SPISimulate_CLR_CLK();
if(send_data&0x80)
{
SPISimulate_SET_MOSI();
}
else
{
SPISimulate_CLR_MOSI();
}
send_data <<= 1;
SPISimulate_SET_CLK();
//asm volatile("NOP"::);
//asm volatile("NOP"::); //延迟时间
TOSH_uwait(2);
}
SPISimulate_CLR_CLK(); //将CLK电平拉低
}
/*******************************************************
CLK的下降沿开始读数据,FLASH的数据从高位开始发送,
*******************************************************/
uchar SPISimulate_ReadByte()
{
uchar i;
uchar rece_byte = 0;
// SPISimulate_CS_Enable();
for(i=0;i<8;i++)
{
SPISimulate_SET_CLK();
TOSH_uwait(1); //延迟时间
rece_byte <<= 1;
if(TOSH_READ_FLASH_IN_PIN()) //下降沿采集数据
{
rece_byte |= 0x01; //将收到的数据放在最低位,通过左移后就到最高位
}
else
{
rece_byte &= 0xFE; //将收到的数据放在最低位,通过左移后就到最高位
}
SPISimulate_CLR_CLK(); //调试更改地方,在此处已通过
TOSH_uwait(1); //延迟时间
}
SPISimulate_SET_CLK(); //读完数据后,SS拉高,同时时钟拉高一次,上升沿重新置数
return (rece_byte);
}
/*******************************************************
Status Register Format:
-----------------------------------------------------------------------
| bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
|--------|--------|--------|--------|--------|--------|----------|--------------|
|RDY/BUSY| COMP | 0 | 1 | 1 | 1 | PROTECT | PAGE SIZE |
| -----------------------------------------------------------------------
bit7 - 忙标记,0为忙1为不忙
当Status Register的位0移出之后,
接下来的时钟脉冲序列将使SPI器件继续
将最新的状态字节送出
bit6 - 标记最近一次Main Memory Page和Buffer的比较结果,0相同,1不同。
bit5
bit4
bit3
bit2 - 这4位用来标记器件密度,对于AT45DB041,这4位应该是0111,一共能标记
16种不同密度的器件。
bit1 - 标识是否有保护主存,标记为1时使能扇区保护,0为未保护
bit0 - 设置一页大小。0时264bytes,1时256bytes
*******************************************************/
uchar AT45DB041_StatusRegisterRead()
{
uchar i;
atomic
{
SPISimulate_CS_Enable();
SPISimulate_WriteByte(0xd7);
i = SPISimulate_ReadByte();
if(i & 0x80 )
TOSH_CLR_DEBUG_IO_PIN();
SPISimulate_CS_Disable();
}
return i;
}
/*******************************************************
描述: 将指定的数据写入buffer 中的指定地址(0-263)
参数: buffer 缓存选择0X01选取buffer 1, 0X02选取buffer 2,
buffer_adderss 缓存字节地址0-263
*writ_pHeader 待写入数据的指针
length 写入数据的长度,<=263
*******************************************************/
void AT45DB041_BufferWrite(uint8_t* data, uint16_t address ,uint8_t len) {
uint i=0;
uchar statu_bit=0;
for(i=0;i<255;++i) //AT45DB041 busy
{
statu_bit=AT45DB041_StatusRegisterRead();
if(CHKB(statu_bit,7)) break;
}
SPISimulate_CS_Enable();
atomic
{
SPISimulate_WriteByte(0x84); //buffer 1 writ //buffer 2 writ case 2:SPISimulate_WriteByte(0x87);break;
SPISimulate_WriteByte(0x00);
SPISimulate_WriteByte(( uchar)(address>>8));
SPISimulate_WriteByte(( uchar)address);
for(i=0;i<len;i++)
{
SPISimulate_WriteByte(*(data + i));
}
SPISimulate_CS_Disable();
}
}
/*******************************************************
描述: 将buffer 数据读回到指定的数据地址
参数: buffer 缓存选择0X01选取buffer 1, 0X02选取buffer 2,
buffer_adderss 缓存字节地址0-263
*read_pHeader 待读回的数据的指针
length 读回数据的长度,<=263
*******************************************************/
void AT45DB041_BufferRead(uint8_t* data, uint16_t address ,uint8_t len) {
uint i = 0;
uchar statu_bit = 0;
for(i=0;i<255;++i) //AT45DB041 busy
{
statu_bit=AT45DB041_StatusRegisterRead();
if(CHKB(statu_bit,7)) break;
}
SPISimulate_CS_Enable();
atomic
{
SPISimulate_WriteByte(0xD4); //buffer 1 writ SPISimulate_WriteByte(0xD6);break; //buffer 2 writ
SPISimulate_WriteByte(0x00);
SPISimulate_WriteByte((uchar)(address>>8));
SPISimulate_WriteByte((uchar)address);
for(i=0;i<len;i++)
{
*(data +i) = SPISimulate_ReadByte();
}
SPISimulate_CS_Disable();
}
}
async command result_t FLASH.init()
{
SPISimulate_Init();
return SUCCESS;
}
async command result_t FLASH.write(uint8_t* data, uint16_t address ,uint16_t page,uint8_t len) {
uint i=0;
uchar statu_bit=0;
//将数据先写入到Buffer中
AT45DB041_BufferWrite(data, address, len);
//等待Busy的结束
for(i=0;i<1000;++i) //AT45DB041 busy
{
statu_bit=AT45DB041_StatusRegisterRead();
if(CHKB(statu_bit,7)) break;
}
atomic
{
SPISimulate_CS_Enable();
SPISimulate_WriteByte(0x83); //buffer1 ,buffer2 SPISimulate_WriteByte(0x86)
SPISimulate_WriteByte((uchar)(page>>7));
SPISimulate_WriteByte((uchar)(page<<1));
SPISimulate_WriteByte(0x00);
SPISimulate_CS_Disable();
}
return SUCCESS;
}
async command result_t FLASH.read(uint8_t* data, uint16_t address , uint16_t page,uint8_t len) {
uint i = 0;
uchar statu_bit = 0;
for(i=0;i<255;++i) //AT45DB041 busy
{
statu_bit=AT45DB041_StatusRegisterRead();
if(CHKB(statu_bit,7)) break;
}
atomic
{
SPISimulate_CS_Enable();
SPISimulate_WriteByte(0xe8);
SPISimulate_WriteByte((uchar)(page>>7));
SPISimulate_WriteByte((uchar)((page<<1)|(address>>8)));
SPISimulate_WriteByte((uchar)address);
for(i=0;i<4;i++)
{
SPISimulate_WriteByte(0x00);
}
for(i=0;i<len;i++)
{
*(data + i) = SPISimulate_ReadByte();
}
SPISimulate_CS_Disable();
}
//*data =AT45DB041_StatusRegisterRead();
//AT45DB041_BufferRead(data, address, len);
return SUCCESS;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -