MSP430驅(qū)動(dòng)AT45DB041(Flash)進(jìn)行讀寫操作例程
分享MSP430驅(qū)動(dòng)AT45DB041(Flash)進(jìn)行讀寫操作例程
*/
/*****************************************************************
* 文件名稱:
* exflash.c
* 文件說明:
* 對(duì)擴(kuò)展FlashAT45DB041進(jìn)行讀寫操作
*
******************************************************************
* MSP430F449
* -----------------
* | |
* | |
* | | ________
* | | | |
* | P6.0|-->| A |
* | P6.1| . | T |
* | P6.2| . | 4 |
* | P6.3| . | 5 |
* | P6.4| . | D |
* | P6.5| . | B |
* | P6.6|-->| 0 |
* | | | 4 |
* | | | 1 |
* |________|
*
****************************************************************/
#ifndef MSP430F449_H
#include <msp430x44x.h>
#endif
unsigned char write_Buf,//發(fā)送數(shù)據(jù)的緩存
read_Buf; // 接收數(shù)據(jù)的緩存
/*****************************************************************
* 初始化AT45DB041B
******************************************************************/
void init_EXFlash()
{
FLL_CTL1 |= SELM_A + FLL_DIV_8;
P6DIR &= 0x80; //si,so,wp,reset,rd_Busy,sck,cs 輸入模式
P6SEL &= 0x80;
P6DIR |= 0x63; //wp,rset,sck,cs =1
P6OUT |= 0x63; //wp,rset,sck,cs=1
}
/***************************************************************
* 讀寫期間的時(shí)延
****************************************************************/
void flash_Delay()
{
_NOP();
_NOP();
_NOP();
}
/***************************************************************
* 發(fā)送“1”到AT45DB041
***************************************************************/
void write_ONE()
{
P6OUT |= 0x10;//si=1
P6OUT |= 0x20;//sck=1
}
/***************************************************************
* 發(fā)送“0”到AT45DB041
****************************************************************/
void write_ZERO()
{
P6OUT &= 0xEF; //si=0
P6OUT |= 0x20; //sck=1
}
/****************************************************************
* 發(fā)送一個(gè)Byte到AT45DB041
*****************************************************************/
void write_Data()
{
char tmp,tmpv=0x80;
for(tmp=0;tmp<8;tmp++)
{
P6OUT &= 0xdf; //sck=0
if ((write_Buf&tmpv)==0x00)
{ //檢查相應(yīng)的位是0還是1
write_ZERO(); // 發(fā)送0
}
else
{
write_ONE(); // 發(fā)送1
}
tmpv /= 2;
}
}
/**************************************************************
* 停止對(duì)AT45DB041的操作
**************************************************************/
void op_Stop()
{
P6OUT |= 0x40; //cs=1,去除片選
}
/*************************************************************
* 為對(duì)AT45DB041做好準(zhǔn)備工作
**************************************************************/
void op_Start()
{
P6DIR |= 0x40;
P6OUT &= 0xbf; //cs=0
flash_Delay();
P6DIR &= 0xCF; //reset
P6DIR |= 0x10; //Si=1
P6DIR |= 0x20; //sck=1
P6OUT |= 0x20; //sck=1
flash_Delay();
}
/************************************************************
* 讀數(shù)據(jù)之前,進(jìn)行IO端口的調(diào)整
************************************************************/
void opr_Start()
{
P6DIR &= 0xF7;//so=0 輸入模式
P6DIR |= 0x20;//sck =1
flash_Delay();
};
/**********************************************************
* 從AT45DB041讀一個(gè)Byte
***********************************************************/
void read_Data()
{
unsigned char tmp,tmpv;
tmpv = 0x80;
read_Buf = 0x00; //清空read_Buf
for(tmp=0;tmp<8;tmp++)
{
P6OUT &= 0xdf; //sck=0
flash_Delay();
P6OUT |= 0x20; //sck=1
if((P6IN & 0x08)!=0x00)
{
read_Buf |= tmpv; //讀取數(shù)據(jù)
}
tmpv/=2;
}
}
/***************************************************
* 文件名稱:
* main.c
* 文件說明:
* 對(duì)擴(kuò)展FlashAT45DB041進(jìn)行操作,在Flash的0x08
* 位置寫0x08,寫入數(shù)據(jù)顯示到 LED[0],讀出的數(shù)據(jù)顯示到LED[1]
****************************************************/
#define MSP430F449_H 0
#include
#ifndef LED_IN_USE
#include "led.c"
#endif
#include "exflash.c"
/****************************************************
* main函數(shù)
*****************************************************/
void main(void)
{
char wData=0x09; //存放要寫的內(nèi)容
/**** 初始化 ****/
WDTCTL = WDTHOLD + WDTPW; //關(guān)閉看門狗
init_LED(); //初始化LED
init_EXFlash(); //初始化Flash
/**** 寫數(shù)據(jù)到Flash ***/
write_Buf = 0x84; //寫緩沖區(qū)1,指令格式:84H + 15位無(wú)關(guān)位 + 9位地址位
op_Start(); //做操作前的準(zhǔn)備工作
write_Data(); //寫操作指令到Flash
write_Buf = 0x00; //設(shè)置八位無(wú)關(guān)位
write_Data(); //寫八位無(wú)關(guān)位
write_Buf = 0x00; //設(shè)置7位無(wú)關(guān)位和一位地址位
write_Data(); //寫7位無(wú)關(guān)位和一位數(shù)據(jù)位
write_Buf= 0x08; //設(shè)置地址
write_Data(); //寫地址
write_Buf = wData; //設(shè)置要寫到Flash的內(nèi)容
write_Data(); //寫數(shù)據(jù)到Flash
op_Stop(); //停止操作
/******** 讀操作 ************/
op_Start(); //啟動(dòng)操作
write_Buf = 0x54; //讀數(shù)據(jù)的指令格式:54H + 15位無(wú)關(guān)位 + 9位地址位 + 8位無(wú)關(guān)位
write_Data(); //寫讀指令到Flash
write_Buf = 0x00; //設(shè)置8位無(wú)關(guān)位
write_Data(); //寫數(shù)據(jù)
write_Buf = 0x00; //設(shè)置7位無(wú)關(guān)位和一位地址位
write_Data(); //寫數(shù)據(jù)
write_Buf = 0x08; //設(shè)置另外8位地址
write_Data(); //寫地址
write_Buf = 0xff; //設(shè)置8位無(wú)關(guān)位
write_Data(); //寫數(shù)據(jù)
//附加脈沖
opr_Start(); //準(zhǔn)備接收數(shù)據(jù)
read_Data(); //接收數(shù)據(jù)到read_buf
op_Stop(); //停止操作
/**** 把寫的內(nèi)容和讀出的內(nèi)容顯示到LED ****/
while(1)
{
led_Buf[0]= wData;
led_Buf[1] =read_Buf;
led_Display(); // 顯示到LED
};
}
//Microcontrol CODE
//存儲(chǔ)器 讀寫程序
#define UCHAR unsigned char
#define UINT unsigned int
///***********************************************************/
#define cs_1 P3OUT=P3OUT|0X01 //cs p3.0
#define cs_0 P3OUT=P3OUT&0Xfe
#define sck_1 P3OUT=P3OUT|0X02 //sck p3.1
#define sck_0 P3OUT=P3OUT&0Xfd
#define si_1 P3OUT=P3OUT|0X04 //si p3.2
#define si_0 P3OUT=P3OUT&0Xfb
#define so P3IN&0X08 //so p3.3 so是MCU 輸入口 存儲(chǔ)器的輸出口 P3.3要定義為輸入口
#define wp_1 P3OUT=P3OUT|0X10 //wp p3.4
#define wp_0 P3OUT=P3OUT&0Xef
#define rst_1 P3OUT=P3OUT|0X20 //rst p3.5
#define rst_0 P3OUT=P3OUT&0Xdf
void nop_041(unsigned char p)
{
while(p--);
}
/////////////從DB041中讀一字節(jié)的數(shù)據(jù)
unsigned char SPI_HostReadByte(void)
{
unsigned char i,rByte=0;
unsigned char xhshuo=0x80;
for(i=0;i<8;i++)
{
sck_0;// SPI_SCK=0
nop_041(20);
sck_1;//SPI_SCK=1
nop_041(20);
if(P3IN&0X08)
rByte=rByte|xhshuo;
xhshuo>>=1;
}
return rByte;
}
/////////////往DB041中寫一字節(jié)的數(shù)據(jù)
void SPI_HostWriteByte(unsigned char wByte)
{
unsigned char i;
for(i=0;i<8;i++)
{
if((wByte< {
si_1;
}//SPI_SI=1
else
{
si_0;
}//SPI_SI=0
sck_0;// SPI_SCK=0;
nop_041(20);
sck_1;// SPI_SCK=1;
nop_041(20);
}
}
/*Status Register Format: */
/* ----------------------------------------------------------------------- */
/* | bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 | */
/* |--------|--------|--------|--------|--------|--------|--------|--------| */
/* |RDY/BUSY| COMP | 0 | 1 | 1 | 1 | X | X | */
/* ----------------------------------------------------------------------- */
/* bit7 - 忙標(biāo)記,0為忙1為不忙。 */
/* 當(dāng)Status Register的位0移出之后,接下來(lái)的時(shí)鐘脈沖序列將使SPI器件繼續(xù)*/
/* 將最新的狀態(tài)字節(jié)送出。 */
/* bit6 - 標(biāo)記最近一次Main Memory Page和Buffer的比較結(jié)果,0相同,1不同。 */
/* bit5 */
/* bit4 */
/* bit3 */
/* bit2 - 這4位用來(lái)標(biāo)記器件密度,對(duì)于AT45DB041B,這4位應(yīng)該是0111,一共能標(biāo)記 */
/* 16種不同密度的器件。 */
/* bit1 */
/* bit0 - 這2位暫時(shí)無(wú)效 */
/******************************************************************************/
/////讀狀態(tài)寄存器的內(nèi)容 0為忙1為不忙
unsigned char AT45DB041B_StatusRegisterRead(void)
{
unsigned char i;
cs_0 ;// SPI_CS=0;
SPI_HostWriteByte(0xd7); ///////////////////////
i=SPI_HostReadByte();
cs_1;// SPI_CS=1
return i;
}
/*參數(shù): */
/* PA - 頁(yè)地址,0~2047 */
/* BFA - 指定BUFFER中的起始寫入地址 */
/* pHeader - 指定數(shù)據(jù)的首地址 */
/* len - 指定數(shù)據(jù)的長(zhǎng)度 */
/******************************************************************************/
void AT45DB041B_ContinuousArrayRead(UINT PA,UINT BFA,unsigned char *pHeader,UINT len)
{
unsigned int i;
do
{
i=AT45DB041B_StatusRegisterRead()&0x80;
}while(!i);
cs_0 ;//SPI_CS=0;
SPI_HostWriteByte(0x52);
SPI_HostWriteByte((unsigned char)(PA>>7));
SPI_HostWriteByte((unsigned char)((PA<<1)|(BFA>>8)));
SPI_HostWriteByte((unsigned char)BFA);
for(i=0;i<4;i++)
{
SPI_HostWriteByte(0x00);
}
for(i=0;i
pHeader[I]=SPI_HostReadByte();
}
cs_1;//SPI_CS=1;
}
/******************************************************************************/
/*描述: */
/* 將指定數(shù)據(jù)寫入從某個(gè)地址(0~263)開始的BUFFER中。 */
/*參數(shù): */
/* buffer - 選擇BUFFER,01H選擇BUFFER 1,02H選擇BUFFER 2 */
/* 在該指令序列中,操作碼84H選擇BUFFER 1,87H選擇BUFFER 2 */
/* BFA - BUFFER中的起始地址,0~263 */
/* pHeader - 待存數(shù)據(jù)的頭指針 */
/* len - 待存數(shù)據(jù)的長(zhǎng)度1~264 */
/******************************************************************************/
void AT45DB041B_BufferWrite(UCHAR buffer,UINT BFA,UCHAR *pHeader,UINT len)
{
unsigned int i;
do
{
i=AT45DB041B_StatusRegisterRead()&0x80;
}while(!i);
cs_0;//SPI_CS=0;
switch(buffer)
{
case 1:
SPI_HostWriteByte(0x84);
break;
case 2:
SPI_HostWriteByte(0x87);
break;
}
SPI_HostWriteByte(0x00);
SPI_HostWriteByte((unsigned char)(BFA>>8));
SPI_HostWriteByte((unsigned char)BFA);
for(i=0;i
SPI_HostWriteByte(pHeader[I]);
}
cs_1;//SPI_CS=1
}
/******************************************************************************/
/*描述: */
/* 將指定數(shù)據(jù)寫入從某個(gè)地址(0~263)開始的頁(yè)中:包含2個(gè)動(dòng)作,首先將指定數(shù)據(jù)*/
/* 寫入到BUFFER 1或者BUFFER 2中,其中可以指定BUFFER中的起始寫入地址,此寫入*/
/* 動(dòng)作不影響B(tài)UFFER中其它地址中的數(shù)據(jù),然后再將BUFFER中的整個(gè)數(shù)據(jù)寫入到某指*/
/* 定頁(yè)中(帶預(yù)擦除)。 */
/*參數(shù): */
/* buffer - 選擇BUFFER,01H選擇BUFFER 1,02H選擇BUFFER 2 */
/* PA - 頁(yè)地址,0~2047 */
/* BFA - 指定BUFFER中的起始寫入地址 */
/* pHeader - 指定數(shù)據(jù)的首地址 */
/* len - 指定數(shù)據(jù)的長(zhǎng)度 */
/******************************************************************************/
void AT45DB041B_BufferToMainMemoryPageProgramWithBuilt_inErase(UCHAR buffer,UINT PA,UINT BFA,UCHAR *pHeader,UINT len)
{
unsigned int i;
AT45DB041B_BufferWrite(buffer,BFA,pHeader,len);
do
{
i=AT45DB041B_StatusRegisterRead()&0x80;
}while(!i);
cs_0;// SPI_CS=0;
switch(buffer)
{
case 1:
SPI_HostWriteByte(0x83);
break;
case 2:
SPI_HostWriteByte(0x86);
break;
}
SPI_HostWriteByte((unsigned char)(PA>>7));
SPI_HostWriteByte((unsigned char)(PA<<1));
SPI_HostWriteByte(0x00);
cs_1;//SPI_CS=1;
}
/******************************************************************************/
/*描述: */
/* 與上一個(gè)函數(shù)的唯一區(qū)別是不帶預(yù)擦除。 */
/******************************************************************************/
/*void AT45DB041B_BufferToMainMemoryPageProgramWithoutBuilt_inErase(UCHAR buffer,UINT PA,UINT BFA,UCHAR *pHeader,UINT len){
unsigned int i;
AT45DB041B_BufferWrite(buffer,BFA,pHeader,len);
do{
i=AT45DB041B_StatusRegisterRead()&0x80;}
while(!i);
cs_0;// SPI_CS=0;
SPI_HostWriteByte(0x88+buffer);
SPI_HostWriteByte((unsigned char)(PA>>7));
SPI_HostWriteByte((unsigned char)(PA<<1));
SPI_HostWriteByte(0x00);
for(i=0;i
}
*/
/*////////////////////////////
void AT45DB041B_BufferToMainMemoryPageProgramWithoutBuilt_inErase(UCHAR buffer,UINT PA,UINT BFA,UCHAR *pHeader,UINT len){
unsigned int i;
AT45DB041B_BufferWrite(buffer,BFA,pHeader,len);
do{
i=AT45DB041B_StatusRegisterRead()&0x80;}
while(!i);
cs_0;// SPI_CS=0;
switch(buffer){
case 1:SPI_HostWriteByte(0x88);break;
case 2:SPI_HostWriteByte(0x89);break;
}
SPI_HostWriteByte((unsigned char)(PA>>7));
SPI_HostWriteByte((unsigned char)(PA<<1));
SPI_HostWriteByte(0x00);
cs_1;//SPI_CS=1;
}
評(píng)論