新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > MSP430驅動AT45DB041(Flash)進行讀寫操作例程

        MSP430驅動AT45DB041(Flash)進行讀寫操作例程

        作者: 時間:2016-11-13 來源:網絡 收藏
        /*
        分享MSP430驅動AT45DB041(Flash)進行讀寫操作例程

        */
        /*****************************************************************
        * 文件名稱:
        * exflash.c
        * 文件說明:
        * 對擴展FlashAT45DB041進行讀寫操作
        *
        ******************************************************************
        * 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,//發送數據的緩存
        read_Buf; // 接收數據的緩存


        /*****************************************************************
        * 初始化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
        }

        /***************************************************************
        * 讀寫期間的時延
        ****************************************************************/
        void flash_Delay()
        {
        _NOP();
        _NOP();
        _NOP();
        }

        /***************************************************************
        * 發送“1”到AT45DB041
        ***************************************************************/
        void write_ONE()
        {
        P6OUT |= 0x10;//si=1
        P6OUT |= 0x20;//sck=1
        }

        /***************************************************************
        * 發送“0”到AT45DB041
        ****************************************************************/
        void write_ZERO()
        {
        P6OUT &= 0xEF; //si=0
        P6OUT |= 0x20; //sck=1

        }

        /****************************************************************
        * 發送一個Byte到AT45DB041
        *****************************************************************/
        void write_Data()
        {
        char tmp,tmpv=0x80;
        for(tmp=0;tmp<8;tmp++)
        {
        P6OUT &= 0xdf; //sck=0
        if ((write_Buf&tmpv)==0x00)
        { //檢查相應的位是0還是1
        write_ZERO(); // 發送0
        }
        else
        {
        write_ONE(); // 發送1
        }

        tmpv /= 2;
        }
        }

        /**************************************************************
        * 停止對AT45DB041的操作
        **************************************************************/
        void op_Stop()
        {
        P6OUT |= 0x40; //cs=1,去除片選
        }

        /*************************************************************
        * 為對AT45DB041做好準備工作
        **************************************************************/
        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();
        }

        /************************************************************
        * 讀數據之前,進行IO端口的調整
        ************************************************************/
        void opr_Start()
        {
        P6DIR &= 0xF7;//so=0 輸入模式
        P6DIR |= 0x20;//sck =1
        flash_Delay();
        };

        /**********************************************************
        * 從AT45DB041讀一個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; //讀取數據
        }

        tmpv/=2;
        }
        }

        /***************************************************
        * 文件名稱:
        * main.c
        * 文件說明:
        * 對擴展FlashAT45DB041進行操作,在Flash的0x08
        * 位置寫0x08,寫入數據顯示到 LED[0],讀出的數據顯示到LED[1]
        ****************************************************/

        #define MSP430F449_H 0
        #include
        #ifndef LED_IN_USE
        #include "led.c"
        #endif

        #include "exflash.c"
        /****************************************************
        * main函數
        *****************************************************/
        void main(void)
        {
        char wData=0x09; //存放要寫的內容

        /**** 初始化 ****/
        WDTCTL = WDTHOLD + WDTPW; //關閉看門狗
        init_LED(); //初始化LED
        init_EXFlash(); //初始化Flash

        /**** 寫數據到Flash ***/
        write_Buf = 0x84; //寫緩沖區1,指令格式:84H + 15位無關位 + 9位地址位
        op_Start(); //做操作前的準備工作
        write_Data(); //寫操作指令到Flash
        write_Buf = 0x00; //設置八位無關位
        write_Data(); //寫八位無關位
        write_Buf = 0x00; //設置7位無關位和一位地址位
        write_Data(); //寫7位無關位和一位數據位
        write_Buf= 0x08; //設置地址
        write_Data(); //寫地址
        write_Buf = wData; //設置要寫到Flash的內容
        write_Data(); //寫數據到Flash
        op_Stop(); //停止操作

        /******** 讀操作 ************/
        op_Start(); //啟動操作
        write_Buf = 0x54; //讀數據的指令格式:54H + 15位無關位 + 9位地址位 + 8位無關位
        write_Data(); //寫讀指令到Flash
        write_Buf = 0x00; //設置8位無關位
        write_Data(); //寫數據
        write_Buf = 0x00; //設置7位無關位和一位地址位
        write_Data(); //寫數據
        write_Buf = 0x08; //設置另外8位地址
        write_Data(); //寫地址
        write_Buf = 0xff; //設置8位無關位
        write_Data(); //寫數據

        //附加脈沖
        opr_Start(); //準備接收數據
        read_Data(); //接收數據到read_buf
        op_Stop(); //停止操作

        /**** 把寫的內容和讀出的內容顯示到LED ****/
        while(1)
        {
        led_Buf[0]= wData;
        led_Buf[1] =read_Buf;
        led_Display(); // 顯示到LED
        };
        }

        //Microcontrol CODE

        //存儲器 讀寫程序
        #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 輸入口 存儲器的輸出口 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中讀一字節的數據
        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中寫一字節的數據
        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 - 忙標記,0為忙1為不忙。 */
        /* 當Status Register的位0移出之后,接下來的時鐘脈沖序列將使SPI器件繼續*/
        /* 將最新的狀態字節送出。 */
        /* bit6 - 標記最近一次Main Memory Page和Buffer的比較結果,0相同,1不同。 */
        /* bit5 */
        /* bit4 */
        /* bit3 */
        /* bit2 - 這4位用來標記器件密度,對于AT45DB041B,這4位應該是0111,一共能標記 */
        /* 16種不同密度的器件。 */
        /* bit1 */
        /* bit0 - 這2位暫時無效 */
        /******************************************************************************/

        /////讀狀態寄存器的內容 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;
        }

        /*參數: */
        /* PA - 頁地址,0~2047 */
        /* BFA - 指定BUFFER中的起始寫入地址 */
        /* pHeader - 指定數據的首地址 */
        /* len - 指定數據的長度 */
        /******************************************************************************/
        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;
        }

        /******************************************************************************/
        /*描述: */
        /* 將指定數據寫入從某個地址(0~263)開始的BUFFER中。 */
        /*參數: */
        /* buffer - 選擇BUFFER,01H選擇BUFFER 1,02H選擇BUFFER 2 */
        /* 在該指令序列中,操作碼84H選擇BUFFER 1,87H選擇BUFFER 2 */
        /* BFA - BUFFER中的起始地址,0~263 */
        /* pHeader - 待存數據的頭指針 */
        /* len - 待存數據的長度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
        }

        /******************************************************************************/
        /*描述: */
        /* 將指定數據寫入從某個地址(0~263)開始的頁中:包含2個動作,首先將指定數據*/
        /* 寫入到BUFFER 1或者BUFFER 2中,其中可以指定BUFFER中的起始寫入地址,此寫入*/
        /* 動作不影響BUFFER中其它地址中的數據,然后再將BUFFER中的整個數據寫入到某指*/
        /* 定頁中(帶預擦除)。 */
        /*參數: */
        /* buffer - 選擇BUFFER,01H選擇BUFFER 1,02H選擇BUFFER 2 */
        /* PA - 頁地址,0~2047 */
        /* BFA - 指定BUFFER中的起始寫入地址 */
        /* pHeader - 指定數據的首地址 */
        /* len - 指定數據的長度 */
        /******************************************************************************/
        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;
        }

        /******************************************************************************/
        /*描述: */
        /* 與上一個函數的唯一區別是不帶預擦除。 */
        /******************************************************************************/
        /*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 cs_1;// SPI_CS=1;
        }
        */

        /*////////////////////////////
        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;
        }


        評論


        技術專區

        關閉
        主站蜘蛛池模板: 临沭县| 繁峙县| 永胜县| 南安市| 河津市| 偃师市| 绥阳县| 巴彦淖尔市| 天津市| 莱芜市| 旺苍县| 乐昌市| 杂多县| 泸定县| 永胜县| 合阳县| 泽普县| 威远县| 鹤山市| 兰考县| 景洪市| 石棉县| 广东省| 铁岭市| 河北区| 望谟县| 东台市| 永昌县| 江达县| 东安县| 行唐县| 舞钢市| 甘孜县| 鹿泉市| 荥阳市| 凤冈县| 贵德县| 广西| 宁蒗| 平乡县| 郧西县|