📄 45db.c
字号:
/*=========================================================================*
* 项目: PDK2000E
* 文件: AT45DB081_bsp.c
* 描述: DataFlash的底层驱动
* 编译: LXF、GTX
* 版本: 1.00
* 创建日期: 2006年4月28日
* 最后修订: 2006年4月28日 23:28:12
* 函数列表:
1. At45db081_initial
2. AutoPageRewriteThroughBuffer2
3. MainMemoryPageToBuffer1
4. ProgramBuffer1ToMainMemory
5. ReadDataFromFlash
6. ReadMultiByteFromMainMemory
7. ReadStatus
8. SPI_rbyte
9. SPI_wbyte
10. WriteDataToFlash
11. WriteMultiByteToBuffer1
12. WriteMultiByteToMainMemory
* 修改历史:
* 编译环境: IAR Embedded Workbench for MSP430 V3.40a
* ----------------------------------------------------------------------
* 广州尚地之光电子科技有限公司
* 开发部
*=========================================================================*/
#define _BSP_DB081_C
#include "SYS_main.h"
/**********************************************************************
*
* 名称: SPI_wbyte
* 说明:
* 功能: 向spi写入一个字节
* 调用: none
* 输入: 待写入字节
* 返回值: none
*
***********************************************************************/
void SPI_wbyte( INT8U wbyte )
{
INT8U BitCnt = 8;
SPI_SDO_OUT();
do
{
SPI_SCK_LO();
if ( wbyte & 0x80 )
SPI_SDO_HI();
else
SPI_SDO_LO();
wbyte <<= 1;
SPI_SCK_HI();
}
while ( --BitCnt );
SPI_SDO_HI();
SPI_SCK_HI();
}
/**********************************************************************
*
* 名称: SPI_rbyte
* 说明:
* 功能: 从spi读出一个字节
* 调用: none
* 输入: none
* 返回值: 读出的字节
*
***********************************************************************/
INT8U SPI_rbyte( void )
{
INT8U BitCnt = 8;
INT8U result;
SPI_SDI_IN();
do
{
SPI_SCK_LO();
result <<= 1;
if ( IS_SPI_SDI_HI() )
result |= 1;
SPI_SCK_HI();
}
while ( --BitCnt );
SPI_SDO_OUT();
SPI_SDO_HI();
SPI_SCK_HI();
return( result );
}
/**********************************************************************
*
* 名称: ReadStatus
* 说明:
* 功能: 读出dataflash的状态
* 调用: none
* 输入: none
* 返回值: 读出的状态
*
***********************************************************************/
INT8U ReadStatus( void )
{
INT8U status;
DATA_FLASH_CS_LO();
SPI_wbyte( DATA_FLASH_STATUS );
status = SPI_rbyte();
DATA_FLASH_CS_HI();
return ( status );
}
/**********************************************************************
*
* 名称: WriteByteToBuffer1
* 说明:
* 功能: 向buffer1写入一个字节
* 调用: none
* 输入: 地址,数据
* 返回值: none
*
***********************************************************************/
/*
void WriteByteToBuffer1(INT16S Address, INT8U Data)
{
DATA_FLASH_CS_LO();
SPI_wbyte(BUFFER1_WRITE); // 写入命令
SPI_wbyte(0);
SPI_wbyte(Address/256); // 2位高位地址
SPI_wbyte(Address%256); // 8位低位地址
SPI_wbyte(Data); // 写入数据
DATA_FLASH_CS_HI();
}
*/
/**********************************************************************
*
* 名称: WriteMultiByteToBuffer1
* 说明:
* 功能: 向buffer1写入多个字节
* 调用: none
* 输入: 地址,数据,数据长度
* 返回值: none
*
***********************************************************************/
void WriteMultiByteToBuffer1( INT16S Address, INT8U *Data, INT8U len )
{
INT8U i;
if ( len == 0 )
{
return ;
}
DATA_FLASH_CS_LO();
SPI_wbyte( BUFFER1_WRITE ); // 写入命令
SPI_wbyte( 0 );
SPI_wbyte( Address / 256 ); // 2位高位地址
SPI_wbyte( Address % 256 ); // 8位低位地址
for ( i = 0; i < len; i++ )
{
SPI_wbyte( *Data ); // 写入数据
Data++;
}
DATA_FLASH_CS_HI();
}
/**********************************************************************
*
* 名称: ReadByteFromBuffer1
* 说明:
* 功能: 从buffer1读出一个字节
* 调用: none
* 输入: 地址,数据
* 返回值: none
*
***********************************************************************/
/*
INT8U ReadByteFromBuffer1(INT16S Address)
{
INT8U Data;
DATA_FLASH_CS_LO();
SPI_wbyte(BUFFER1_READ); // 命令
SPI_wbyte(0);
SPI_wbyte(Address/256); // 2位高位地址
SPI_wbyte(Address%256); // 8位低位地址
SPI_wbyte(0);
Data = SPI_rbyte(); // 读出数据
DATA_FLASH_CS_HI();
return (Data);
}
*/
/**********************************************************************
*
* 名称: ErasePage
* 说明:
* 功能: 擦除一页
* 调用: none
* 输入: 地址,数据
* 返回值: none
*
***********************************************************************/
/*
void ErasePage(INT16S PageNum)
{
DATA_FLASH_CS_LO();
PageNum <<= PAGE_RL;
SPI_wbyte(PAGE_ERASE); // 命令
SPI_wbyte(PageNum/256); // 高7位地址
SPI_wbyte(PageNum%256); // 低6位地址
SPI_wbyte(0);
DATA_FLASH_CS_HI();
}
*/
/**********************************************************************
*
* 名称: ReadByteFromMainMemory
* 说明:
* 功能: 从主存区读取一个字节
* 调用: none
* 输入: 页地址,页内地址
* 返回值: 读出的数据
*
***********************************************************************/
#if 0
#ifdef VER_10003
INT8U ReadByteFromMainMemory( INT16S PageNum, INT16S SubAddress )
{
INT8U Data;
PageNum <<= PAGE_RL;
DATA_FLASH_CS_LO();
SPI_wbyte( MAIN_MEMORY_PAGE_READ ); // 命令
SPI_wbyte( PageNum / 256 ); // 高7位页地址
SPI_wbyte( ( ( PageNum % 256 ) & ADDR_MASK) | ( ( SubAddress / 256 ) & (~ADDR_MASK) ) ); //低6位页地址和高2位页内地址
SPI_wbyte( SubAddress % 256 ); // 低8位页内地址
SPI_wbyte( 0 );
SPI_wbyte( 0 );
SPI_wbyte( 0 );
SPI_wbyte( 0 );
Data = SPI_rbyte(); // 读出数据
DATA_FLASH_CS_HI();
return ( Data );
}
#endif
#endif
/**********************************************************************
*
* 名称: ReadMultiByteFromMainMemory
* 说明:
* 功能: 从主存区读取多个字节
* 调用: none
* 输入: 页地址,页内地址,数据存放缓冲区指针,读出长度
* 返回值:
*
***********************************************************************/
INT8U ReadMultiByteFromMainMemory( INT16S PageNum, INT16S SubAddress, INT8U *msg, INT8U len )
{
INT8U i;
i = 255;
if ( len == 0 )
{
return FALSE;
}
while ( IS_DATA_FLASH_BUSY() && i-- )
{
_NOP();
}
if ( i == 0 )
{
return FALSE;
}
PageNum <<= PAGE_RL;
DATA_FLASH_CS_LO();
SPI_wbyte( CONTINUOUS_ARRAY_READ ); // 命令
SPI_wbyte( PageNum / 256 ); // 高7位页地址
SPI_wbyte( ( ( PageNum % 256 ) & ADDR_MASK) | ( ( SubAddress / 256 ) & (~ADDR_MASK) ) );
/*低6位页地址和高2位页内地址*/
SPI_wbyte( SubAddress % 256 ); // 低8位页内地址
SPI_wbyte( 0 );
SPI_wbyte( 0 );
SPI_wbyte( 0 );
SPI_wbyte( 0 );
for ( i = 0; i < len; i++ )
{
*msg = SPI_rbyte(); // 读出数据
msg ++;
}
DATA_FLASH_CS_HI();
return TRUE;
}
/**********************************************************************
*
* 名称: MainMemoryPageToBuffer1
* 说明:
* 功能: 将主存储区的指定页数据传送到buffer1
* 调用: none
* 输入: 页地址
* 返回值:
*
***********************************************************************/
void MainMemoryPageToBuffer1( INT16S PageNum )
{
INT8U i;
DATA_FLASH_CS_LO();
PageNum <<= PAGE_RL;
SPI_wbyte( MAIN_MEMORY_PAGE_TO_BUFFER1_COPY ); // 命令
SPI_wbyte( PageNum / 256 ); // 高7位地址
SPI_wbyte( PageNum % 256 ); // 低6位地址
SPI_wbyte( 0 );
DATA_FLASH_CS_HI();
i = 255;
while ( IS_DATA_FLASH_BUSY() && ( --i ) );
}
/**********************************************************************
*
* 名称: ProgramBuffer1ToMainMemory
* 说明:
* 功能: 将buffer1的数据写入主存储区
* 调用: none
* 输入: 页地址
* 返回值:
*
***********************************************************************/
void ProgramBuffer1ToMainMemory( INT16S PageNum )
{
PageNum <<= PAGE_RL;
DATA_FLASH_CS_LO();
SPI_wbyte( BUFFER1_PROGRAM_WITH_ERASE ); // 命令
SPI_wbyte( PageNum / 256 ); // 高7位地址
SPI_wbyte( PageNum % 256 ); // 低6位地址
SPI_wbyte( 0 );
DATA_FLASH_CS_HI();
}
/**********************************************************************
*
* 名称: WriteMultiByteToMainMemory
* 说明:
* 功能: 将buffer1的数据写入主存储区
* 调用: none
* 输入: 页地址
* 返回值:
*
***********************************************************************/
INT8U WriteMultiByteToMainMemory( INT16S PageNum, INT16S SubAddress, INT8U *MultiByte, INT8U len )
{
INT8U i;
if ( !len )
{
return FALSE;
}
//if (IS_DATA_FLASH_BUSY()) return FALSE;
i = 255;
while ( IS_DATA_FLASH_BUSY() && ( --i ) ); // 等待芯片空闲
if ( i == 0)
{
//phase.Dsp_Pages = 1;return FALSE;
return FALSE;
} //test
MainMemoryPageToBuffer1( PageNum ); // 把指定页读取到buffer1
i = 255;
while ( IS_DATA_FLASH_BUSY() && ( --i ) ); // 等待芯片空闲
if ( !i )
{
//phase.Dsp_Pages = 1;return FALSE;
return FALSE;
} //test
WriteMultiByteToBuffer1( SubAddress, MultiByte, len ); // 向buffer1写入数据
ProgramBuffer1ToMainMemory( PageNum ); // 将buffer1的内容写入flash
// phase.Dsp_Pages = 0;
return TRUE;
}
/*=============================================================================
* 名称: WriteDataToFlash
* 描述: 将数据连续写入Flash,自动分页
* 创建: LXF、GTX 2006年4月20日
* 最后修订: 2006年4月20日 10:05:08
* 调用: None
* 输入参数: None
* 返回值: None
* 特殊说明: IAR Embedded Workbench for MSP430 V3.40a
*=============================================================================*/
void WriteDataToFlash(INT32U TargetAddr, INT8U *save_data, INT8U data_len)
{
INT16U PageNum,SubAddress;
INT8U w_len;
if(!data_len)
return ;
PageNum = TargetAddr / PAGE_BYTE;
SubAddress = TargetAddr % PAGE_BYTE;
while(data_len)
{
if(data_len > (PAGE_BYTE - SubAddress))
w_len = PAGE_BYTE - SubAddress;
else
w_len = data_len;
while ( IS_DATA_FLASH_BUSY() ); // 等待芯片空闲
MainMemoryPageToBuffer1(PageNum); // 把指定页读取到buffer1
while ( IS_DATA_FLASH_BUSY() ); // 等待芯片空闲
WriteMultiByteToBuffer1(SubAddress,save_data,w_len); // 向buffer1写入数据
ProgramBuffer1ToMainMemory(PageNum); // 将buffer1的内容写入flash
data_len -= w_len;
save_data += w_len;
PageNum += 1;
SubAddress = 0;
}
return ;
}
/*=============================================================================
* 名称: ReadDataFromFlash
* 描述: 从Flash中连续读出数据
* 创建: LXF、GTX 2006年4月21日
* 最后修订: 2006年4月21日 15:33:10
* 调用: None
* 输入参数: None
* 返回值: None
* 特殊说明: IAR Embedded Workbench for MSP430 V3.40a
*=============================================================================*/
INT8U ReadDataFromFlash(INT32U TargetAddr, INT8U *read_data, INT8U data_len)
{
INT16U PageNum,SubAddress;
INT8U i;
i = 255;
if ( data_len == 0 )
{
return FALSE;
}
while ( IS_DATA_FLASH_BUSY() && i-- )
{
_NOP();
}
if ( i == 0 )
{
return FALSE;
}
PageNum = TargetAddr / PAGE_BYTE;
SubAddress = TargetAddr % PAGE_BYTE;
PageNum <<= PAGE_RL;
DATA_FLASH_CS_LO();
SPI_wbyte( CONTINUOUS_ARRAY_READ ); // 命令
SPI_wbyte( PageNum / 256 ); // 高7位页地址
SPI_wbyte( ( ( PageNum % 256 ) & ADDR_MASK) | ( ( SubAddress / 256 ) & (~ADDR_MASK) ) ); /*低6位页地址和高2位页内地址*/
SPI_wbyte( SubAddress % 256 ); // 低8位页内地址
SPI_wbyte( 0 );
SPI_wbyte( 0 );
SPI_wbyte( 0 );
SPI_wbyte( 0 );
for ( i = 0; i < data_len; i++ )
{
*read_data = SPI_rbyte(); // 读出数据
read_data ++;
}
DATA_FLASH_CS_HI();
return TRUE;
}
/**********************************************************************
*
* 名称: AutoPageRewriteThroughBuffer2
* 说明:
* 功能: 重写一页
* 调用: none
* 输入: 地址
* 返回值: none
*
***********************************************************************/
void AutoPageRewriteThroughBuffer2( INT16S PageNum )
{
DATA_FLASH_CS_LO();
PageNum <<= PAGE_RL;
SPI_wbyte( AUTO_PAGE_THROUGH_BUFFER2_REWRITE ); // 命令
SPI_wbyte( PageNum / 256 ); // 高7位地址
SPI_wbyte( PageNum % 256 ); // 低6位地址
SPI_wbyte( 0 );
DATA_FLASH_CS_HI();
}
/**********************************************************************
*
* 名称: At45db081_initial
* 说明: BIT4-BIT6工作于IO方式,其中bit7,bit5为输入口,bit6为双向口
* 功能: 初始化at45db081的SPI口线,CS置高
* 调用: none
* 输入: 地址
* 返回值: none
*
***********************************************************************/
void At45db081_initial( void )
{
P1DIR |= BIT6; //OUT
P1DIR &= ~BIT5; //IN OR OUT
DATA_FLASH_CS_HI() ; //set CS hight
}
/*
void main(void)
{
INT8U i,*test;
INT16U page,j;
INT8U array1[10]={0,0,0,0,0,0,0,0,0,0};
INT8U array2[10]={1,2,3,4,5,6,7,8,9,10};
At45db081_initial();
WDTCTL = WDTPW+WDTHOLD; // Stop watchdog timer
for(j=0;j<100;j++)
{
// page=j;
i=ReadMultiByteFromMainMemory(page, 0, array1, 10);
_NOP();
// page=j;
i=WriteMultiByteToMainMemory (page, 0, array2,10);
// page=j;
i=ReadMultiByteFromMainMemory(page, 0, array1,10);
_NOP();
}
_NOP();
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -