|
求大家?guī)兔φ乙幌略颍x芒微FT64F0A5單片機(jī)的SPI模塊與W25Q32不能正常通信問(wèn)題點(diǎn):IO模擬SPI與W25Q32通信正常,但是用單片機(jī)SPI模塊無(wú)法正常通信.
W25Q32模塊是網(wǎng)上買(mǎi)的.
例程 是官方DEMO試了一下無(wú)效.
- //---------單片機(jī)與W25Q32 的電壓是,3.3V供電
- #define SPI_DIO PA0 // 只作輸入 (單片機(jī) TO 芯片) W25Q32 DI
- #define SPI_DO PA1 // 輸出 (芯片 TO 單片機(jī)) W25Q32 D0
- #define SPI_CLK PB0 // 時(shí)鐘 W25Q32 CLK
- #define CS PB5 // 片選 W25Q32 CS
- 附上修改后的源碼
- //Project: FT64F0A5_SPI_TEST_000.prj
- // Device: FT64F0AX
- // Memory: Flash 10KX14b, EEPROM 128X8b, SRAM 1KX8b
- // Author:
- //Company:
- //Version:
- // Date:
- //===========================================================
- //===========================================================
- /* ---------------------------------------------------------
- //--- FT61F0A5/FT64F0A5_TRB TSSOP20 IC引腳位圖
- 1- LVDOUT/TIM2_CH1/USART1_CK/OP0+/PA5
- 2- USART1_TX/OP0-/AN3/PA6
- 3- [CLKO]/OP0OUT/[TIM1_CH4]/[USART2_TX]/USART1_RX/ELVD0/AN4/PA7
- 4- MCLRB/TIM1_CH1N/ELVD1/AN5/PC0
- 5- OSC1/[SPI_MISO]/ELVD2/PC1
- 6- OSC2/[SPI_MOSI]ELVD3/PB7
- 7- GND
- 8- ISPDAT/[USART1_TX]/[I2C_SDA]/AN6/PB6
- 9- VDD
- 10- [LVDOUT]/TIM2_CH3/USART2_RX/SPI_NSS/PB5
- 11- PB4/TIM1_BKIN/I2C_SDA/USART2_TX/[LVDOUT]
- 12- PB3/[ADC_ETR]/TIM1_ETR/I2C_SCL/USART2_CK/[LVDOUT]
- 13- PB2/[SPI_SCK]/[TIM1_CH1N]/TIM1_CH3
- 14- PB1/AN0/TIM1_CH2N/TIM1_CH4/CLKO
- 15- PB0/SPI_SCK/[TIM1_CH2]/TIM1_CH3N/[TIM2_CH1]
- 16- PA0/VREFN/SPI_MOSI/TIM1_CH1
- 17- PA1/VREFP/SPI_MISO/TIM1_CH2
- 18- PA2/[I2C_SCL]/[USART1_RX]/[TIM1_CH4]/ISPCLK
- 19- PA3/AN1/[USART2_TX]/[TIM2_CH3]
- 20- PA4/AN2/ADC_ETR/[USART2_RX]/TIM2_CH2
- ------------------------------------------------------- */
- /* ---------------------------------------------------------
- FT61F0A5/FT64F0A5_TRB TSSOP20
- NC--------|1(PA5) (PA4)20|--------NC
- NC--------|2(PA6) (PA3)19|--------NC
- NC--------|3(PA7) (PA2)18|--------NC
- NC--------|4(PC0) (PA1)17|--------NC
- NC--------|5(PC1) (PA0)16|--------NC
- NC--------|6(PB7) (PB0)15|--------NC
- NC--------|7(GND) (PB1)14|--------NC
- NC--------|8(PB6) (PB2)13|--------NC
- NC--------|9(VDD) (PB3)12|--------NC
- NC--------|10(PB5) (PB4)11|--------NC
- ------------------------------------------------------- */
- /* ---------------------------------------------------------
- URAT 9600波特率 發(fā)送 字符型 數(shù)據(jù)
- -第NNN個(gè)數(shù)值: 0xNN
- 測(cè)試模塊W25Q32
- #define MOSI PA0
- #define MISO PA1
- #define SCK PB0
- #define NSS PB5
- #define LED_ON() {PB1 = 1;}
- #define LED_OFF() {PB1 = 0;}
- MCU的SPI模塊或IO模擬SPI 測(cè)試OK.
- 功能說(shuō)明: W25Q32 寫(xiě)一個(gè)數(shù)組,讀一個(gè)數(shù)組,
- 對(duì)比數(shù)組正確 2HZ 閃爍,錯(cuò)誤 長(zhǎng)亮.
- ------------------------------------------------------ */
- #include "SYSCFG.h" //
- //***********************宏定義*****************************
- #define uchar unsigned char
- #define uint unsigned int
- #define ulong unsigned long
- #define MOSI PA0
- #define MISO PA1
- #define SCK PB0
- #define NSS PB5
- #define LED_ON() {PB1 = 1;}
- #define LED_OFF() {PB1 = 0;}
- unsigned char errorFlag = 0; //
- void Fun_PowerInitial(void); //上電初始化
- void Fun_Uart1_Initial(void); //串口初始化
- void SendString(unsigned char *pu8String);
- void PrintOutput(unsigned char u8Number,unsigned char u8Data); //-第NNN個(gè)數(shù)值: 0xNN
- void SPI_INITIAL(void); //SPI 模塊初始化
- void DelayUs(uchar Time); //
- void DelayMs(uchar Time); //
- void DelayS(uchar Time); //
- uchar SPI_RW(uchar data); //
- void WriteEnable(void); //
- void WriteDisable(void); //
- uchar SPI_ReadStatus(void); //
- void SPI_WriteStatus(uchar Status); //
- //uchar SPI_Read(uint addr); //
- //void SPI_Write(uint addr , uchar dat); //
- void SPI_Flash_Read(uchar *pbuf,ulong addr,uint Len); //
- void W25X_Flash_Write_Page(uchar *pbuf,ulong addr,uint Len); //
- void SPI_Flash_Write_NoCheck(uchar *pbuf,ulong addr,uint Len); //
- void W25X_SectorErase(ulong Addr24); //擦除資料圖示的4KB空?
- void W25X_BlockErase(ulong Addr24); //擦除資料圖示的64KB空間
- void W25X_ChipErase(void);
- void init_25c64_io(void); //
- /* -----------------------------------------------------
- ------------------------------------------------------ */
- void interrupt ISR(void)
- {
- }
- /* -----------------------------------------------------
- * 函數(shù)名: main
- * 功能: 主函數(shù)
- * 輸入: 無(wú)
- * 輸出: 無(wú)
- ------------------------------------------------------ */
- void main()
- {
- unsigned char a; //定義一個(gè)變量a。
- unsigned char i; //
- unsigned char Send_DATA[16]; // 要發(fā)送的數(shù)據(jù)
- unsigned char Rec_DATA[16]; // 已接收的數(shù)據(jù)
- Fun_PowerInitial(); //上電初始化
- Fun_Uart1_Initial(); //串口初始化
- SPI_INITIAL(); //SPI初始化
- DelayMs(250); //
- DelayMs(250); //
- init_25c64_io(); //
- for(i=0;i<16;i++)
- {
- Send_DATA[i]=i;
- Rec_DATA[i]=0;
- }
- a=100; //給變量a 賦值。
- PrintOutput(255,a); // //-第NNN個(gè)數(shù)值: 0xNN
- W25X_SectorErase(0x000000); //
- SPI_Flash_Write_NoCheck(Send_DATA,0x000000,16); //寫(xiě)N個(gè)數(shù)
- SPI_Flash_Read(Rec_DATA,0x000000,16); //讀N個(gè)數(shù)
- for(i=0;i<16;i++)
- {
- PrintOutput(i,Rec_DATA[i]); // //-第NNN個(gè)數(shù)值: 0xNN
- }
- for(i=0;i<16;i++)
- {
- if(Send_DATA[i] != Rec_DATA[i])
- {
- errorFlag = 1; //
- break; //
- }
- else
- {
- errorFlag = 0; //
- }
- }
- while(1)
- {
- NOP(); //
- if(errorFlag == 0)
- {
- LED_ON();
- DelayMs(250);
- LED_OFF();
- DelayMs(250);
- }
- else
- {
- LED_ON();
- }
- }
- }
- /* --------------------------------------------------
- 函數(shù)名: Fun_PowerInitial
- 功能: 上電初始化
- 輸入:
- 輸出:
- 說(shuō)明:
- --------------------------------------------------- */
- void Fun_PowerInitial(void) //上電初始化
- {
- OSCCON=0B01110001; //系統(tǒng)時(shí)鐘選擇為內(nèi)部振蕩器16MHz,分頻比為1:1
- INTCON=0; //禁止所有中斷
- PORTA=0B00000000;
- PORTB=0B00000000;
- PORTC=0B00000000;
- WPUA=0B00000010; //弱上拉的開(kāi)關(guān),0-關(guān),1-開(kāi)
- WPUB=0B00000000;
- WPUC=0B00000000;
- WPDA=0B00000000; //弱下拉的開(kāi)關(guān),0-關(guān),1-開(kāi)
- WPDB=0B00000000;
- WPDC=0B00000000;
-
- TRISA=0B11111110; //輸入輸出設(shè)置,0-輸出,1-輸入,SPI_MISO,SPI_MOSI
- TRISB=0B11011100; //SPI_NSS,SPI_SCK
- TRISC=0B00000011;
- PSRC0=0B11111111; //源電流設(shè)置最大
- PSRC1=0B11111111;
- PSRC2=0B00001111;
- PSINK0=0B11111111; //灌電流設(shè)置最大
- PSINK1=0B11111111;
- PSINK2=0B00000011;
- ANSELA=0B00000000; //設(shè)置對(duì)應(yīng)的IO為數(shù)字IO
- }
- /* --------------------------------------------------
- 函數(shù)名: Fun_Uart1_Initial
- 功能: 串口初始化
- 輸入:
- 輸出:
- 說(shuō)明:
- --------------------------------------------------- */
- void Fun_Uart1_Initial(void) //串口初始化
- {
- PCKEN|=0B00100000; //使能UART1模塊時(shí)鐘
- //----默認(rèn)----
- // AFP0 &= 0X3F; //USART1_TX BIT7-BIT6: 00-PA6 01-PA7 10-PB6 11-PA2
- // AFP1 &= 0X3F; //USART1_RX BIT7-BIT6: 00-PA7 01-PA6 10-PA2 11-PB6
- TRISA7=1; //UART_RX
- TRISA6 =0; //UART_TX
- //UR1IER=0B00100001; //使能發(fā)送完成中斷,使能接收數(shù)據(jù)中斷
- UR1IER=0B00000000; //除能發(fā)送完成中斷,除能接收數(shù)據(jù)中斷
- UR1LCR=0B00000001; //8位數(shù)據(jù)長(zhǎng)度,1位停止位,無(wú)奇偶校驗(yàn)位
- UR1MCR=0B00011000; //使能發(fā)送和接收接口
- UR1DLL=104; //波特率=Fmaster/(16*{URxDLH,URxDLL})=9600
- UR1DLH=0;
- UR1TCF=1;
- ODCON0 | = 0x01;
- INTCON=0B11000000;
- }
- void SendString(unsigned char *pu8String)
- {
- static unsigned int Su16SendCnt;
- static unsigned int Su16Delay;
- for(Su16SendCnt=0;Su16SendCnt<43;Su16SendCnt++)
- {
- if(0==pu8String[Su16SendCnt])
- {
- break;
- }
- else
- {
- //---FT64F0A5----
- UR1DATAL = pu8String[Su16SendCnt];
- //---//----延時(shí)等待或等待發(fā)送標(biāo)志位
- //for(Su16Delay=0;Su16Delay<800;Su16Delay++); //延時(shí)等待發(fā)送完成
- while(!UR1TCF); // //1 為完成; 0 未完成 //等待發(fā)送標(biāo)志位
- UR1TCF = 1; //
- }
- }
- }
- /*----------第NNN個(gè)數(shù)值: 0xNN---*/
- void PrintOutput(unsigned char u8Number,unsigned char u8Data) //第NNN個(gè)數(shù)值: 0xNN
- {
- static unsigned char Su8ViewBuffer1[20];
- //--1~255--
- //-----第NNN個(gè)數(shù)值:
- const unsigned char Cu8Array1[]={0xB5,0xDA,0x4E,0x4E,0x4E,0xB8,0xF6,0xCA,0xFD,0xD6,0xB5,0x3A,0x00};
- const unsigned char Cu8_0D_0A[]={0x0d,0x0a,0x00};
- static unsigned int Su8NumBuff[3]; //
- static unsigned int Su8DataBuff[2]; //
- static unsigned int Su8BufferCnt;
- //---- 0~255 轉(zhuǎn)換成10進(jìn)制數(shù)----
- Su8NumBuff[0] = u8Number/100; //
- Su8NumBuff[1] = (u8Number%100)/10; //
- Su8NumBuff[2] = u8Number%10; //
- //--將個(gè)位數(shù)轉(zhuǎn)換 數(shù)字字符
- Su8NumBuff[2] = Su8NumBuff[2] + '0'; // 將數(shù)字轉(zhuǎn)換成字符碼
- //--將十位數(shù)轉(zhuǎn)換 空字符或數(shù)字字符
- if(Su8NumBuff[1] == 0 && Su8NumBuff[0] == 0) //十位數(shù)
- {
- Su8NumBuff[1] = 0x20; // 即為空字符代碼
- }
- else
- {
- Su8NumBuff[1] = Su8NumBuff[1] + '0'; // 將數(shù)字轉(zhuǎn)換成字符碼
- }
- //--將百位數(shù)轉(zhuǎn)換 空字符或數(shù)字字符
- if(Su8NumBuff[0] == 0) //百位數(shù)
- {
- Su8NumBuff[0] = 0x20; // 即為空字符代碼
- }
- else
- {
- Su8NumBuff[0] = Su8NumBuff[0] + '0'; // 將數(shù)字轉(zhuǎn)換成字符碼
- }
- //-----十六進(jìn)制轉(zhuǎn)化 字符顯示-----
- Su8DataBuff[0] = u8Data >> 4; //
- Su8DataBuff[1] = u8Data & 0x0f; //
- //--高8位--
- if(Su8DataBuff[0] < 10) //
- {
- Su8DataBuff[0] = Su8DataBuff[0] + '0'; //小于10的數(shù),轉(zhuǎn)換成 字符(0~9) 顯示
- }
- else
- {
- Su8DataBuff[0] = Su8DataBuff[0] + '7'; //大于或等于10的數(shù),轉(zhuǎn)換成 字符(A~F) 顯示
- }
- //--低8位--
- if(Su8DataBuff[1] < 10) //
- {
- Su8DataBuff[1] = Su8DataBuff[1] + '0'; //
- }
- else
- {
- Su8DataBuff[1] = Su8DataBuff[1] + '7'; //
- }
- for(Su8BufferCnt=0;Su8BufferCnt<12;Su8BufferCnt++)
- {
- Su8ViewBuffer1[Su8BufferCnt]=Cu8Array1[Su8BufferCnt];
- }
- Su8ViewBuffer1[2]=Su8NumBuff[0];
- Su8ViewBuffer1[3]=Su8NumBuff[1];
- Su8ViewBuffer1[4]=Su8NumBuff[2];
- Su8ViewBuffer1[Su8BufferCnt]='0';
- Su8ViewBuffer1[Su8BufferCnt+1]='x';
- Su8ViewBuffer1[Su8BufferCnt+2]=Su8DataBuff[0];
- Su8ViewBuffer1[Su8BufferCnt+3]=Su8DataBuff[1];
- Su8ViewBuffer1[Su8BufferCnt+4]=0x0d;
- Su8ViewBuffer1[Su8BufferCnt+5]=0x0a;
- Su8ViewBuffer1[Su8BufferCnt+6]=0;
- SendString(Su8ViewBuffer1);
- SendString(Cu8_0D_0A);
- }
- /*-------------------------------------------------
- * 函數(shù)名:SPI_INITIAL
- * 功能: 初始化SPI
- * 輸入: 無(wú)
- * 輸出: 無(wú)
- --------------------------------------------------*/
- void SPI_INITIAL(void)
- {
- PCKEN|=0B00010000; //使能SPI模塊時(shí)鐘
- SPICTRL=0B00000000; //禁用NSS引腳
- SPICFG=0B01000000; //設(shè)置為主機(jī)模式,第一個(gè)時(shí)鐘轉(zhuǎn)換的沿是數(shù)據(jù)采樣點(diǎn),SPI空閑時(shí),SCK的時(shí)鐘是處于低電平狀態(tài)
- //SPICFG=0B01110000; //設(shè)置為主機(jī)模式,第二個(gè)時(shí)鐘轉(zhuǎn)換的沿是數(shù)據(jù)采樣點(diǎn),SPI空閑時(shí),SCK的時(shí)鐘是處于高電平狀態(tài)
-
- SPISCR=0B00000000; //波特率設(shè)置為8M,F(xiàn)master/(2*(SPISCR+1)),F(xiàn)master=16M
- //SPISCR=0B00000111; //波特率設(shè)置為1M,F(xiàn)master/(2*(SPISCR+1)),F(xiàn)master=16M
- //SPISCR=0B01001111; //波特率設(shè)置為100KHZ,F(xiàn)master/(2*(SPISCR+1)),F(xiàn)master=16M
- //SPISCR=0B00000000; //波特率設(shè)置為8M,F(xiàn)master/(2*(SPISCR+1)),F(xiàn)master=16M
- SPIRXCRC=0B00000000; //接收數(shù)據(jù)的CRC計(jì)算結(jié)果
- SPITXCRC=0B00000000; //發(fā)送數(shù)據(jù)的CRC計(jì)算結(jié)果
- SPIIER=0B00000000; //禁止所有中斷
- SPICTRL2=0B00000000; //全雙工允許發(fā)送和接收,禁用CRC校驗(yàn)?zāi)K,高比特位優(yōu)先發(fā)送
- SPISTAT=0B00000000;
- SPIEN=1; //啟用SPI
- }
- /*-------------------------------------------------
- * 函數(shù)名: DelayUs
- * 功能: 短延時(shí)函數(shù)
- * 輸入?yún)?shù):Time延時(shí)時(shí)間長(zhǎng)度 延時(shí)時(shí)長(zhǎng)Time Us
- * 返回參數(shù): 無(wú)
- --------------------------------------------------*/
- void DelayUs(uchar Time)
- {
- uchar a;
- for(a=0;a<Time;a++)
- {
- NOP();
- }
- }
- /*-------------------------------------------------
- * 函數(shù)名: DelayMs
- * 功能: 短延時(shí)函數(shù)
- * 輸入?yún)?shù):Time延時(shí)時(shí)間長(zhǎng)度 延時(shí)時(shí)長(zhǎng)Time ms
- * 返回參數(shù): 無(wú)
- --------------------------------------------------*/
- void DelayMs(uchar Time)
- {
- uchar a,b;
- for(a=0;a<Time;a++)
- {
- for(b=0;b<5;b++)
- {
- DelayUs(197);
- }
- }
- }
- /*-------------------------------------------------
- * 函數(shù)名: DelayS
- * 功能: 短延時(shí)函數(shù)
- * 輸入?yún)?shù):Time延時(shí)時(shí)間長(zhǎng)度 延時(shí)時(shí)長(zhǎng)Time S
- * 返回參數(shù): 無(wú)
- --------------------------------------------------*/
- void DelayS(uchar Time)
- {
- uchar a,b;
- for(a=0;a<Time;a++)
- {
- for(b=0;b<10;b++)
- {
- DelayMs(100);
- }
- }
- }
- /*====================================================
- *函數(shù)名:init_25c64_io
- *功能:25C64初始化
- *輸入:無(wú)
- *輸出:無(wú)
- ====================================================*/
- void init_25c64_io(void)
- {
- NSS = 1;
- SCK = 0;
- MOSI = 0;
- }
- // //--- IO口 模擬SPI --
- ///*====================================================
- //*函數(shù)名:SPI_RW
- //*功能:主機(jī)輸出以及輸入一個(gè)字節(jié)
- //*輸入:data
- //*輸出:根據(jù)接收的data輸出給從機(jī)一個(gè)字節(jié)
- //* ------ IO口 模擬SPI -------
- //====================================================*/
- //uchar SPI_RW(uchar data)
- //{
- // uchar i;
- // for(i=0;i<8;i++)
- // {
- // if(data&0x80) MOSI = 1; //output 'uchar',MSB to MOSI
- // else MOSI = 0;
- // NOP();
- // data <<= 1; //shift next bit into MSB
- // SCK = 1; //Set SCK high...
- // NOP();
- // if(MISO) data |= 0x01;
- // else data &= 0xFE;
- // NOP();
- // SCK = 0;
- // }
- // return data;
- //}
- //---- MCU的 SPI 模塊----
- /*-------------------------------------------------
- * 函數(shù)名SPI_RW
- * 功能: 主機(jī)輸出以及輸入一個(gè)字節(jié)
- * 輸入: data
- * 輸出: 根據(jù)接收的data輸出給從機(jī)一個(gè)字節(jié)
- * ---- MCU的 SPI模塊 ----
- --------------------------------------------------*/
- uchar SPI_RW(uchar data)
- {
- uchar spiData;
-
- while(SBUSY); //等待SPI模塊空閑
- SPIDATA=data;
- while(SBUSY||!SPIF);
- SPIF=0;
- spiData=SPIDATA;
- return spiData;
- }
- /*-------------------------------------------------
- * 函數(shù)名WriteEnable
- * 功能: 寫(xiě)允許(將WEN置位)
- --------------------------------------------------*/
- void WriteEnable(void)
- {
- NSS=0;
- SPI_RW(0X06);
- NSS=1;
- }
- /*-------------------------------------------------
- * 函數(shù)名WriteDisable
- * 功能: 寫(xiě)禁止(將WEN復(fù)位)
- --------------------------------------------------*/
- void WriteDisable(void)
- {
- NSS=0;
- SPI_RW(0X04);
- NSS=1;
- }
- /*-------------------------------------------------
- * 函數(shù)名:SPI_ReadStatus
- * 功能: 讀取25C64芯片的狀態(tài)
- * 返回值:狀態(tài)寄存器數(shù)據(jù)字節(jié)
- * 注: 25C64內(nèi)部狀態(tài)寄存器第0位=0表示空閑,0位=1表示忙。
- --------------------------------------------------*/
- uchar SPI_ReadStatus(void)
- {
- uchar status=0;
- NSS=0;
- SPI_RW(0X05); //0x05讀取狀態(tài)的命令字
- status=SPI_RW(0X00);
- NSS=1; //關(guān)閉片選
- return status;
- }
- /*-------------------------------------------------
- * 函數(shù)名:SPI_WriteStatus
- * 功能: 寫(xiě)25C64芯片的狀態(tài)寄存器
- * 注: 只有BP1、BP0(bit7、3、2)可以寫(xiě)
- 25C64內(nèi)部狀態(tài)寄存器第0位=0表示空閑,0位=1表示忙。
- --------------------------------------------------*/
- void SPI_WriteStatus(uchar Status)
- {
- NSS=0;
- SPI_RW(0X01); //0X01寫(xiě)入狀態(tài)的命令字
- SPI_RW(Status); //寫(xiě)入一個(gè)字節(jié)
- NSS=1; //關(guān)閉片選
- }
- // /*-------------------------------------------------
- // * 函數(shù)名SPI_Read
- // * 輸入: 16位的地址
- // * 返回: 讀取的數(shù)據(jù)
- // * 說(shuō)明: 從25C64指定的地址讀取一個(gè)字節(jié)
- // --------------------------------------------------*/
- // uchar SPI_Read(uint addr)
- // {
- // uchar spidata;
- // while(SPI_ReadStatus()&0x01); //判斷是否忙
- // NSS=0; //使能器件
- // SPI_RW(0X03); //發(fā)送讀取命令
- // SPI_RW((uchar)((addr)>>8));
- // SPI_RW((uchar)addr);
- // spidata=SPI_RW(0X00); //讀出數(shù)據(jù)
- // NSS=1;
- // return spidata;
- // }
- // /*-------------------------------------------------
- // * 函數(shù)名SPI_Write
- // * 輸入: 地址,字節(jié)數(shù)據(jù)
- // * 說(shuō)明: 將一個(gè)字節(jié)寫(xiě)入指定的地址
- // --------------------------------------------------*/
- //void SPI_Write(uint addr , uchar dat)
- // {
- // while(SPI_ReadStatus()&0x01); //判斷是否忙
- // WriteEnable(); //SET WEN
- // NSS=0; //使能器件
- // SPI_RW(0X02); //發(fā)送寫(xiě)命令
- // SPI_RW((uchar)((addr)>>8));
- // SPI_RW((uchar)addr);
- //
- // SPI_RW(dat);
- // WriteDisable();
- // NSS=1; //關(guān)閉片選
- // while(SPI_ReadStatus()&0x01);
- // }
- /*-------------------------------------------------
- //讀取SPI FLASH
- //在指定地址開(kāi)始讀取指定長(zhǎng)度的數(shù)據(jù)
- //pbuf:數(shù)據(jù)存儲(chǔ)區(qū)
- //addr:開(kāi)始讀取的地址(24bit)
- //Len:要讀取的字節(jié)數(shù)(最大65535) * 函數(shù)名SPI_Read
- * 輸入: 16位的地址
- * 返回: 讀取的數(shù)據(jù)
- * 說(shuō)明: W25Q32指定的地址讀取一個(gè)字節(jié)
- --------------------------------------------------*/
- void SPI_Flash_Read(uchar *pbuf,ulong addr,uint Len)
- {
- uint i;
- while(SPI_ReadStatus()&0x01); //判斷是否忙
- NSS=0; //使能器件
- SPI_RW(0X03); //發(fā)送讀取命令
- SPI_RW((uchar)((addr)>>16)); //
- SPI_RW((uchar)((addr)>>8));
- SPI_RW((uchar)addr);
- for(i=0;i<Len;i++)
- {
- *pbuf++ = SPI_RW(0X00);
- }
- NSS=1;
- }
- //SPI在一頁(yè)(0~65535)內(nèi)寫(xiě)入少于256個(gè)字節(jié)的數(shù)據(jù)
- //在指定地址開(kāi)始寫(xiě)入最大256字節(jié)的數(shù)據(jù)
- //pbuf:數(shù)據(jù)存儲(chǔ)區(qū)
- //addr:開(kāi)始寫(xiě)入的地址(24bit)
- //Len:要寫(xiě)入的字節(jié)數(shù)(最大256),該數(shù)不應(yīng)該超過(guò)該頁(yè)的剩余字節(jié)數(shù)!!!
- void W25X_Flash_Write_Page(uchar *pbuf,ulong addr,uint Len)
- {
- uint i;
- while(SPI_ReadStatus()&0x01); //判斷是否?
- WriteEnable(); //SET WEL
- NSS=0; //使能器件
- SPI_RW(0x02); //發(fā)送寫(xiě)頁(yè)命令
- SPI_RW((uchar)((addr)>>16)); //發(fā)送24bit地址
- SPI_RW((uchar)((addr)>>8));
- SPI_RW((uchar)addr);
- for(i=0;i<Len;i++) //循環(huán)寫(xiě)數(shù)
- {
- SPI_RW(*pbuf++);
- }
- NSS=1; //取消片選
- while(SPI_ReadStatus()&0x01); //等待寫(xiě)入結(jié)束
- }
- //無(wú)檢驗(yàn)寫(xiě)SPI FLASH
- //必須確保所寫(xiě)的地址范圍內(nèi)的數(shù)據(jù)全部為0XFF,否則在非0XFF處寫(xiě)入的數(shù)據(jù)將失敗!
- //具有自動(dòng)換頁(yè)功能
- //在指定地址開(kāi)始寫(xiě)入指定長(zhǎng)度的數(shù)據(jù)
- //pbuf:數(shù)據(jù)存儲(chǔ)區(qū)
- //addr:開(kāi)始寫(xiě)入的地址(24bit)
- //Len:要寫(xiě)入的字節(jié)數(shù)(最大65535)
- void SPI_Flash_Write_NoCheck(uchar *pbuf,ulong addr,uint Len)
- {
- uint PageLen; // 頁(yè)內(nèi)寫(xiě)入字節(jié)長(zhǎng)度
- PageLen=256-addr%256; // 單頁(yè)剩余的字節(jié)數(shù) (單頁(yè)剩余空間)
- if(Len <= PageLen) PageLen=Len; // 不大于256 個(gè)字節(jié)
- while(1)
- {
- W25X_Flash_Write_Page(pbuf,addr,PageLen);
- if(PageLen == Len) break; // 寫(xiě)入結(jié)束了
- else
- {
- pbuf += PageLen;
- addr += PageLen;
- Len -= PageLen; // 減去已經(jīng)寫(xiě)入了的字節(jié)數(shù)
- if(Len>256) PageLen = 256; // 一次可以寫(xiě)入256 個(gè)字節(jié)
- else PageLen = Len; // 不夠256 個(gè)字節(jié)了
- }
- }
- }
- //*************** 4K扇擦除************************OK
- //擦除一個(gè)扇區(qū)
- //Dst_Addr:扇區(qū)地址 0~511 for w25x16
- //擦除一個(gè)扇區(qū)的最少時(shí)間:150ms
- void W25X_SectorErase(ulong Addr24) //擦除資料圖示的4KB空間
- {
- uchar Addr1; // 最低地址字節(jié)
- uchar Addr2; // 中間地址字節(jié)
- uchar Addr3; // 最高地址字節(jié)
- Addr1=Addr24;
- Addr24=Addr24>>8;
- Addr2=Addr24;
- Addr24=Addr24>>8;
- Addr3=Addr24; // 把地址拆開(kāi)來(lái)
- while(SPI_ReadStatus()&0x01); // 判斷是否忙
- WriteEnable(); // 寫(xiě)允許
- NSS=0;
- SPI_RW(0x20); // 整扇擦除命令
- SPI_RW(Addr3);
- SPI_RW(Addr2);
- SPI_RW(Addr1);
- NSS=1;
- while(SPI_ReadStatus()&0x01); // 等待擦除完成
- }
- //*************** 塊擦除/64K頁(yè)************************* OK
- void W25X_BlockErase(ulong Addr24) //擦除資料圖示的64KB空間
- {
- uchar Addr1; // 最低地址字節(jié)
- uchar Addr2; // 中間地址字節(jié)
- uchar Addr3; // 最高地址字節(jié)
- Addr1=Addr24;
- Addr24=Addr24>>8;
- Addr2=Addr24;
- Addr24=Addr24>>8;
- Addr3=Addr24; // 把地址拆開(kāi)來(lái)
- while(SPI_ReadStatus()&0x01); // 判斷是否忙
- WriteEnable(); // 寫(xiě)允許
- NSS=0;
- SPI_RW(0xD8); // 整扇擦除命令
- SPI_RW(Addr3);
- SPI_RW(Addr2);
- SPI_RW(Addr1);
- NSS=1;
- while(SPI_ReadStatus()&0x01); // 等待擦除完成
- }
- //**************片擦除 ****************** OK
- // W25X16:25S W25X32:40S W25X64:40S
- void W25X_ChipErase(void)
- {
- while(SPI_ReadStatus()&0x01); // 判斷是否忙
- WriteEnable(); // 寫(xiě)允許
- NSS=0;
- SPI_RW(0xC7); // 整片擦除命令
- NSS=1; // 從CS=1時(shí)開(kāi)始執(zhí)行擦除
- while(SPI_ReadStatus()&0x01); // 等待擦除完成
- }
復(fù)制代碼
|
|