久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 2375|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

輝芒微FT64F0A5單片機(jī)的SPI模塊與W25Q32不能正常通信問(wèn)題 附程序與datasheet

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:59830 發(fā)表于 2023-6-25 15:45 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
求大家?guī)兔φ乙幌略颍x芒微FT64F0A5單片機(jī)的SPI模塊與W25Q32不能正常通信問(wèn)題點(diǎn):IO模擬SPI與W25Q32通信正常,但是用單片機(jī)SPI模塊無(wú)法正常通信.
W25Q32模塊是網(wǎng)上買(mǎi)的.

例程  是官方DEMO試了一下無(wú)效.
  1. //---------單片機(jī)與W25Q32 的電壓是,3.3V供電
  2. #define SPI_DIO   PA0   // 只作輸入 (單片機(jī) TO 芯片)    W25Q32 DI
  3. #define SPI_DO    PA1    // 輸出     (芯片 TO 單片機(jī))      W25Q32 D0
  4. #define SPI_CLK   PB0    // 時(shí)鐘                                   W25Q32 CLK
  5. #define CS        PB5   // 片選                                        W25Q32 CS

  6. 附上修改后的源碼
  7. //Project: FT64F0A5_SPI_TEST_000.prj
  8. // Device: FT64F0AX
  9. // Memory: Flash 10KX14b, EEPROM 128X8b, SRAM 1KX8b
  10. // Author:
  11. //Company:
  12. //Version:
  13. //   Date:
  14. //===========================================================

  15. //===========================================================
  16. /*  ---------------------------------------------------------
  17.          //--- FT61F0A5/FT64F0A5_TRB   TSSOP20 IC引腳位圖
  18. 1- LVDOUT/TIM2_CH1/USART1_CK/OP0+/PA5                                             
  19. 2- USART1_TX/OP0-/AN3/PA6                                                                        
  20. 3- [CLKO]/OP0OUT/[TIM1_CH4]/[USART2_TX]/USART1_RX/ELVD0/AN4/PA7      
  21. 4- MCLRB/TIM1_CH1N/ELVD1/AN5/PC0                                                      
  22. 5- OSC1/[SPI_MISO]/ELVD2/PC1                                                         
  23. 6- OSC2/[SPI_MOSI]ELVD3/PB7                                                            
  24. 7- GND                                                                          
  25. 8- ISPDAT/[USART1_TX]/[I2C_SDA]/AN6/PB6                                          
  26. 9- VDD                                                                           
  27. 10- [LVDOUT]/TIM2_CH3/USART2_RX/SPI_NSS/PB5  
  28. 11- PB4/TIM1_BKIN/I2C_SDA/USART2_TX/[LVDOUT]   
  29. 12- PB3/[ADC_ETR]/TIM1_ETR/I2C_SCL/USART2_CK/[LVDOUT]   
  30. 13- PB2/[SPI_SCK]/[TIM1_CH1N]/TIM1_CH3            
  31. 14- PB1/AN0/TIM1_CH2N/TIM1_CH4/CLKO   
  32. 15- PB0/SPI_SCK/[TIM1_CH2]/TIM1_CH3N/[TIM2_CH1]
  33. 16- PA0/VREFN/SPI_MOSI/TIM1_CH1               
  34. 17- PA1/VREFP/SPI_MISO/TIM1_CH2
  35. 18- PA2/[I2C_SCL]/[USART1_RX]/[TIM1_CH4]/ISPCLK
  36. 19- PA3/AN1/[USART2_TX]/[TIM2_CH3]
  37. 20- PA4/AN2/ADC_ETR/[USART2_RX]/TIM2_CH2

  38. -------------------------------------------------------    */

  39. /*  ---------------------------------------------------------
  40.              FT61F0A5/FT64F0A5_TRB   TSSOP20
  41.          NC--------|1(PA5)       (PA4)20|--------NC
  42.          NC--------|2(PA6)       (PA3)19|--------NC
  43.          NC--------|3(PA7)       (PA2)18|--------NC
  44.          NC--------|4(PC0)       (PA1)17|--------NC
  45.          NC--------|5(PC1)       (PA0)16|--------NC
  46.          NC--------|6(PB7)       (PB0)15|--------NC
  47.          NC--------|7(GND)       (PB1)14|--------NC
  48.          NC--------|8(PB6)       (PB2)13|--------NC
  49.          NC--------|9(VDD)       (PB3)12|--------NC
  50.          NC--------|10(PB5)      (PB4)11|--------NC

  51. -------------------------------------------------------    */

  52. /*  ---------------------------------------------------------
  53. URAT  9600波特率  發(fā)送  字符型  數(shù)據(jù)  
  54. -第NNN個(gè)數(shù)值: 0xNN
  55.   測(cè)試模塊W25Q32     
  56. #define                MOSI        PA0
  57. #define                MISO        PA1
  58. #define                SCK                PB0
  59. #define                NSS                PB5
  60. #define         LED_ON()           {PB1 = 1;}
  61. #define         LED_OFF()   {PB1 = 0;}

  62. MCU的SPI模塊或IO模擬SPI 測(cè)試OK.
  63. 功能說(shuō)明: W25Q32 寫(xiě)一個(gè)數(shù)組,讀一個(gè)數(shù)組,
  64.   對(duì)比數(shù)組正確 2HZ 閃爍,錯(cuò)誤 長(zhǎng)亮.
  65. ------------------------------------------------------    */

  66. #include "SYSCFG.h"   //

  67. //***********************宏定義*****************************
  68. #define                uchar        unsigned char
  69. #define                uint                unsigned int
  70. #define                ulong        unsigned long


  71. #define                MOSI        PA0
  72. #define                MISO        PA1
  73. #define                SCK                PB0
  74. #define                NSS                PB5

  75. #define         LED_ON()           {PB1 = 1;}
  76. #define         LED_OFF()   {PB1 = 0;}


  77. unsigned char  errorFlag = 0; //

  78. void Fun_PowerInitial(void);     //上電初始化
  79. void Fun_Uart1_Initial(void);   //串口初始化
  80. void SendString(unsigned char *pu8String);
  81. void PrintOutput(unsigned char u8Number,unsigned char u8Data); //-第NNN個(gè)數(shù)值: 0xNN

  82. void SPI_INITIAL(void);                //SPI  模塊初始化

  83. void DelayUs(uchar Time);               //
  84. void DelayMs(uchar Time);               //
  85. void DelayS(uchar Time);                //
  86. uchar SPI_RW(uchar data);               //
  87. void WriteEnable(void);                 //
  88. void WriteDisable(void);                //
  89. uchar SPI_ReadStatus(void);             //
  90. void SPI_WriteStatus(uchar Status);     //

  91. //uchar SPI_Read(uint addr);              //
  92. //void SPI_Write(uint addr , uchar dat);  //

  93. void SPI_Flash_Read(uchar *pbuf,ulong addr,uint Len);        //
  94. void W25X_Flash_Write_Page(uchar *pbuf,ulong addr,uint Len); //
  95. void SPI_Flash_Write_NoCheck(uchar *pbuf,ulong addr,uint Len);  //
  96. void W25X_SectorErase(ulong Addr24); //擦除資料圖示的4KB空?
  97. void W25X_BlockErase(ulong Addr24);  //擦除資料圖示的64KB空間
  98. void W25X_ChipErase(void);

  99. void init_25c64_io(void); //

  100. /*  -----------------------------------------------------
  101. ------------------------------------------------------  */
  102. void interrupt ISR(void)
  103. {

  104. }


  105. /*  -----------------------------------------------------
  106. *        函數(shù)名: main
  107. *        功能:  主函數(shù)
  108. *        輸入:  無(wú)
  109. *        輸出:  無(wú)
  110. ------------------------------------------------------    */
  111. void main()
  112. {
  113.         unsigned char a; //定義一個(gè)變量a。
  114.     unsigned char i;  //
  115.     unsigned char  Send_DATA[16];  // 要發(fā)送的數(shù)據(jù)
  116.     unsigned char  Rec_DATA[16];   // 已接收的數(shù)據(jù)

  117.         Fun_PowerInitial();     //上電初始化
  118.         Fun_Uart1_Initial();    //串口初始化

  119.         SPI_INITIAL();                                        //SPI初始化

  120.         DelayMs(250); //
  121.     DelayMs(250); //

  122.     init_25c64_io(); //

  123.     for(i=0;i<16;i++)
  124.     {
  125.         Send_DATA[i]=i;
  126.         Rec_DATA[i]=0;  
  127.     }

  128.         a=100; //給變量a 賦值。
  129.     PrintOutput(255,a); //  //-第NNN個(gè)數(shù)值: 0xNN


  130.     W25X_SectorErase(0x000000);  //

  131.     SPI_Flash_Write_NoCheck(Send_DATA,0x000000,16);    //寫(xiě)N個(gè)數(shù)
  132.     SPI_Flash_Read(Rec_DATA,0x000000,16);   //讀N個(gè)數(shù)

  133.         for(i=0;i<16;i++)
  134.     {
  135.                 PrintOutput(i,Rec_DATA[i]); //  //-第NNN個(gè)數(shù)值: 0xNN         
  136.     }

  137.     for(i=0;i<16;i++)
  138.     {
  139.         if(Send_DATA[i] != Rec_DATA[i])
  140.         {
  141.              errorFlag = 1; //
  142.              break;  //
  143.         }
  144.         else
  145.         {
  146.              errorFlag = 0; //
  147.         }
  148.     }

  149.         while(1)
  150.     {
  151.         NOP();  //
  152.         if(errorFlag == 0)
  153.         {
  154.                         LED_ON();
  155.                         DelayMs(250);  
  156.                         LED_OFF();
  157.                         DelayMs(250);            
  158.         }
  159.         else
  160.         {
  161.             LED_ON();
  162.         }
  163.     }
  164. }



  165. /*   --------------------------------------------------
  166. 函數(shù)名: Fun_PowerInitial
  167. 功能: 上電初始化
  168. 輸入:
  169. 輸出:
  170. 說(shuō)明:
  171. ---------------------------------------------------   */
  172. void Fun_PowerInitial(void)     //上電初始化
  173. {
  174.         OSCCON=0B01110001;                //系統(tǒng)時(shí)鐘選擇為內(nèi)部振蕩器16MHz,分頻比為1:1

  175.         INTCON=0;                                                        //禁止所有中斷

  176.     PORTA=0B00000000;
  177.     PORTB=0B00000000;
  178.     PORTC=0B00000000;

  179.         WPUA=0B00000010;                        //弱上拉的開(kāi)關(guān),0-關(guān),1-開(kāi)               
  180.         WPUB=0B00000000;
  181.         WPUC=0B00000000;        

  182.         WPDA=0B00000000;                        //弱下拉的開(kāi)關(guān),0-關(guān),1-開(kāi)
  183.         WPDB=0B00000000;
  184.         WPDC=0B00000000;
  185.                
  186.         TRISA=0B11111110;                        //輸入輸出設(shè)置,0-輸出,1-輸入,SPI_MISO,SPI_MOSI
  187.         TRISB=0B11011100;                        //SPI_NSS,SPI_SCK
  188.         TRISC=0B00000011;

  189.         PSRC0=0B11111111;                        //源電流設(shè)置最大
  190.         PSRC1=0B11111111;
  191.         PSRC2=0B00001111;

  192.         PSINK0=0B11111111;                        //灌電流設(shè)置最大
  193.         PSINK1=0B11111111;
  194.         PSINK2=0B00000011;

  195.         ANSELA=0B00000000;                        //設(shè)置對(duì)應(yīng)的IO為數(shù)字IO            
  196. }



  197. /*   --------------------------------------------------
  198. 函數(shù)名: Fun_Uart1_Initial
  199. 功能: 串口初始化
  200. 輸入:
  201. 輸出:
  202. 說(shuō)明:
  203. ---------------------------------------------------   */
  204. void Fun_Uart1_Initial(void)   //串口初始化
  205. {
  206.     PCKEN|=0B00100000;                        //使能UART1模塊時(shí)鐘

  207.       //----默認(rèn)----
  208. //    AFP0 &= 0X3F;    //USART1_TX BIT7-BIT6: 00-PA6 01-PA7 10-PB6 11-PA2
  209. //    AFP1 &= 0X3F;    //USART1_RX BIT7-BIT6: 00-PA7 01-PA6 10-PA2 11-PB6

  210.     TRISA7=1;                                         //UART_RX
  211.     TRISA6 =0;                                        //UART_TX

  212.     //UR1IER=0B00100001;                        //使能發(fā)送完成中斷,使能接收數(shù)據(jù)中斷
  213.     UR1IER=0B00000000;                        //除能發(fā)送完成中斷,除能接收數(shù)據(jù)中斷

  214.     UR1LCR=0B00000001;                    //8位數(shù)據(jù)長(zhǎng)度,1位停止位,無(wú)奇偶校驗(yàn)位
  215.     UR1MCR=0B00011000;                    //使能發(fā)送和接收接口

  216.     UR1DLL=104;                                        //波特率=Fmaster/(16*{URxDLH,URxDLL})=9600
  217.     UR1DLH=0;  
  218.     UR1TCF=1;
  219.     ODCON0  |  = 0x01;
  220.     INTCON=0B11000000;   
  221. }


  222. void SendString(unsigned char *pu8String)
  223. {
  224.         static unsigned int Su16SendCnt;
  225.         static unsigned int Su16Delay;

  226.         for(Su16SendCnt=0;Su16SendCnt<43;Su16SendCnt++)
  227.         {
  228.                 if(0==pu8String[Su16SendCnt])
  229.                 {
  230.                         break;
  231.                 }
  232.                 else
  233.                 {
  234.             //---FT64F0A5----
  235.             UR1DATAL = pu8String[Su16SendCnt];
  236.                //---//----延時(shí)等待或等待發(fā)送標(biāo)志位
  237.             //for(Su16Delay=0;Su16Delay<800;Su16Delay++);   //延時(shí)等待發(fā)送完成
  238.                         while(!UR1TCF);  //  //1 為完成; 0 未完成   //等待發(fā)送標(biāo)志位

  239.                         UR1TCF = 1;  //

  240.                 }
  241.         }
  242. }


  243. /*----------第NNN個(gè)數(shù)值: 0xNN---*/
  244. void PrintOutput(unsigned char u8Number,unsigned char u8Data)  //第NNN個(gè)數(shù)值: 0xNN
  245. {
  246.         static unsigned char Su8ViewBuffer1[20];
  247.                  //--1~255--
  248.     //-----第NNN個(gè)數(shù)值:
  249.     const unsigned char Cu8Array1[]={0xB5,0xDA,0x4E,0x4E,0x4E,0xB8,0xF6,0xCA,0xFD,0xD6,0xB5,0x3A,0x00};
  250.         const unsigned char Cu8_0D_0A[]={0x0d,0x0a,0x00};

  251.         static unsigned int Su8NumBuff[3];  //
  252.     static unsigned int Su8DataBuff[2];  //
  253.     static unsigned int Su8BufferCnt;  

  254.     //---- 0~255 轉(zhuǎn)換成10進(jìn)制數(shù)----
  255.         Su8NumBuff[0] = u8Number/100;  //
  256.     Su8NumBuff[1] = (u8Number%100)/10;  //        
  257.     Su8NumBuff[2] = u8Number%10;  //  

  258.     //--將個(gè)位數(shù)轉(zhuǎn)換  數(shù)字字符
  259.     Su8NumBuff[2] = Su8NumBuff[2] + '0';  // 將數(shù)字轉(zhuǎn)換成字符碼
  260.     //--將十位數(shù)轉(zhuǎn)換  空字符或數(shù)字字符
  261.     if(Su8NumBuff[1] == 0 && Su8NumBuff[0] == 0)  //十位數(shù)
  262.     {
  263.         Su8NumBuff[1] = 0x20;  // 即為空字符代碼
  264.     }
  265.     else
  266.     {
  267.        Su8NumBuff[1] = Su8NumBuff[1] + '0';  // 將數(shù)字轉(zhuǎn)換成字符碼
  268.     }     
  269.     //--將百位數(shù)轉(zhuǎn)換  空字符或數(shù)字字符
  270.     if(Su8NumBuff[0] == 0)  //百位數(shù)
  271.     {
  272.         Su8NumBuff[0] = 0x20;  // 即為空字符代碼
  273.     }
  274.     else
  275.     {
  276.         Su8NumBuff[0] = Su8NumBuff[0] + '0';  // 將數(shù)字轉(zhuǎn)換成字符碼
  277.     }   

  278.         //-----十六進(jìn)制轉(zhuǎn)化  字符顯示-----
  279.         Su8DataBuff[0] = u8Data >> 4; //
  280.     Su8DataBuff[1] = u8Data & 0x0f; //  
  281.              //--高8位--        
  282.     if(Su8DataBuff[0] < 10)       //
  283.     {
  284.         Su8DataBuff[0] = Su8DataBuff[0] + '0';  //小于10的數(shù),轉(zhuǎn)換成 字符(0~9) 顯示
  285.     }
  286.     else
  287.     {
  288.         Su8DataBuff[0] = Su8DataBuff[0] + '7';  //大于或等于10的數(shù),轉(zhuǎn)換成 字符(A~F) 顯示
  289.     }   
  290.                  //--低8位--        
  291.     if(Su8DataBuff[1] < 10)     //
  292.     {
  293.         Su8DataBuff[1] = Su8DataBuff[1] + '0';  //
  294.     }
  295.     else
  296.     {
  297.         Su8DataBuff[1] = Su8DataBuff[1] + '7';  //
  298.     }

  299.         for(Su8BufferCnt=0;Su8BufferCnt<12;Su8BufferCnt++)
  300.         {
  301.                 Su8ViewBuffer1[Su8BufferCnt]=Cu8Array1[Su8BufferCnt];
  302.         }
  303.         Su8ViewBuffer1[2]=Su8NumBuff[0];
  304.         Su8ViewBuffer1[3]=Su8NumBuff[1];
  305.         Su8ViewBuffer1[4]=Su8NumBuff[2];
  306.     Su8ViewBuffer1[Su8BufferCnt]='0';
  307.     Su8ViewBuffer1[Su8BufferCnt+1]='x';
  308.     Su8ViewBuffer1[Su8BufferCnt+2]=Su8DataBuff[0];
  309.     Su8ViewBuffer1[Su8BufferCnt+3]=Su8DataBuff[1];   
  310.         Su8ViewBuffer1[Su8BufferCnt+4]=0x0d;
  311.         Su8ViewBuffer1[Su8BufferCnt+5]=0x0a;
  312.         Su8ViewBuffer1[Su8BufferCnt+6]=0;

  313.         SendString(Su8ViewBuffer1);
  314.         SendString(Cu8_0D_0A);
  315. }


  316. /*-------------------------------------------------
  317. *        函數(shù)名:SPI_INITIAL
  318. *        功能:          初始化SPI
  319. *        輸入:         無(wú)
  320. *        輸出:          無(wú)
  321. --------------------------------------------------*/
  322. void SPI_INITIAL(void)
  323. {
  324.      PCKEN|=0B00010000;                                //使能SPI模塊時(shí)鐘

  325.      SPICTRL=0B00000000;                                //禁用NSS引腳

  326.      SPICFG=0B01000000;                                //設(shè)置為主機(jī)模式,第一個(gè)時(shí)鐘轉(zhuǎn)換的沿是數(shù)據(jù)采樣點(diǎn),SPI空閑時(shí),SCK的時(shí)鐘是處于低電平狀態(tài)
  327.      //SPICFG=0B01110000;                                //設(shè)置為主機(jī)模式,第二個(gè)時(shí)鐘轉(zhuǎn)換的沿是數(shù)據(jù)采樣點(diǎn),SPI空閑時(shí),SCK的時(shí)鐘是處于高電平狀態(tài)
  328.          
  329.         SPISCR=0B00000000;                                //波特率設(shè)置為8M,F(xiàn)master/(2*(SPISCR+1)),F(xiàn)master=16M
  330.      //SPISCR=0B00000111;                                //波特率設(shè)置為1M,F(xiàn)master/(2*(SPISCR+1)),F(xiàn)master=16M
  331.          //SPISCR=0B01001111;                                //波特率設(shè)置為100KHZ,F(xiàn)master/(2*(SPISCR+1)),F(xiàn)master=16M
  332.      //SPISCR=0B00000000;                                //波特率設(shè)置為8M,F(xiàn)master/(2*(SPISCR+1)),F(xiàn)master=16M

  333.      SPIRXCRC=0B00000000;                        //接收數(shù)據(jù)的CRC計(jì)算結(jié)果
  334.      SPITXCRC=0B00000000;                        //發(fā)送數(shù)據(jù)的CRC計(jì)算結(jié)果
  335.      SPIIER=0B00000000;                                        //禁止所有中斷
  336.      SPICTRL2=0B00000000;                                //全雙工允許發(fā)送和接收,禁用CRC校驗(yàn)?zāi)K,高比特位優(yōu)先發(fā)送
  337.      SPISTAT=0B00000000;                                
  338.      SPIEN=1;                                                                        //啟用SPI
  339. }


  340. /*-------------------------------------------------
  341. *        函數(shù)名:        DelayUs
  342. *        功能:                  短延時(shí)函數(shù)
  343. *        輸入?yún)?shù):Time延時(shí)時(shí)間長(zhǎng)度 延時(shí)時(shí)長(zhǎng)Time Us
  344. *        返回參數(shù): 無(wú)
  345. --------------------------------------------------*/
  346. void DelayUs(uchar Time)
  347. {
  348.      uchar a;
  349.      for(a=0;a<Time;a++)
  350.      {
  351.          NOP();
  352.          }
  353. }
  354. /*-------------------------------------------------
  355. *        函數(shù)名:        DelayMs
  356. *        功能:                  短延時(shí)函數(shù)
  357. *        輸入?yún)?shù):Time延時(shí)時(shí)間長(zhǎng)度 延時(shí)時(shí)長(zhǎng)Time ms
  358. *        返回參數(shù): 無(wú)
  359. --------------------------------------------------*/
  360. void DelayMs(uchar Time)
  361. {
  362.      uchar a,b;
  363.      for(a=0;a<Time;a++)
  364.      {
  365.          for(b=0;b<5;b++)
  366.          {
  367.              DelayUs(197);
  368.          }
  369.      }
  370. }
  371. /*-------------------------------------------------
  372. *        函數(shù)名:        DelayS
  373. *        功能:                  短延時(shí)函數(shù)
  374. *        輸入?yún)?shù):Time延時(shí)時(shí)間長(zhǎng)度 延時(shí)時(shí)長(zhǎng)Time S
  375. *        返回參數(shù): 無(wú)
  376. --------------------------------------------------*/
  377. void DelayS(uchar Time)
  378. {
  379.      uchar a,b;
  380.      for(a=0;a<Time;a++)
  381.      {
  382.          for(b=0;b<10;b++)
  383.          {
  384.              DelayMs(100);
  385.          }
  386.      }
  387. }



  388. /*====================================================
  389. *函數(shù)名:init_25c64_io
  390. *功能:25C64初始化
  391. *輸入:無(wú)
  392. *輸出:無(wú)
  393. ====================================================*/        
  394. void init_25c64_io(void)
  395. {
  396.     NSS = 1;
  397.          SCK = 0;
  398.     MOSI = 0;
  399. }

  400. //       //---  IO口 模擬SPI  --
  401. ///*====================================================
  402. //*函數(shù)名:SPI_RW
  403. //*功能:主機(jī)輸出以及輸入一個(gè)字節(jié)
  404. //*輸入:data
  405. //*輸出:根據(jù)接收的data輸出給從機(jī)一個(gè)字節(jié)
  406. //* ------  IO口 模擬SPI  -------
  407. //====================================================*/                  
  408. //uchar SPI_RW(uchar data)
  409. //{
  410. //   uchar i;
  411. //        for(i=0;i<8;i++)
  412. //        {
  413. //                if(data&0x80) MOSI = 1;                //output 'uchar',MSB to MOSI
  414. //                else MOSI = 0;
  415. //                NOP();
  416. //                data <<= 1;                                        //shift next bit into MSB
  417. //                SCK = 1;                                        //Set SCK high...
  418. //                NOP();
  419. //                if(MISO) data |= 0x01;
  420. //                else data &= 0xFE;
  421. //                NOP();
  422. //                SCK = 0;
  423. //        }
  424. //        return data;
  425. //}


  426.        //----  MCU的 SPI 模塊----
  427. /*-------------------------------------------------
  428. *        函數(shù)名SPI_RW
  429. *        功能:          主機(jī)輸出以及輸入一個(gè)字節(jié)
  430. *        輸入:         data
  431. *        輸出:          根據(jù)接收的data輸出給從機(jī)一個(gè)字節(jié)
  432. *  ----  MCU的 SPI模塊 ----
  433. --------------------------------------------------*/
  434. uchar SPI_RW(uchar data)
  435. {
  436.     uchar spiData;
  437.                            
  438.     while(SBUSY);                                //等待SPI模塊空閑
  439.     SPIDATA=data;
  440.     while(SBUSY||!SPIF);
  441.     SPIF=0;
  442.     spiData=SPIDATA;
  443.     return spiData;
  444. }


  445.   /*-------------------------------------------------
  446. *        函數(shù)名WriteEnable
  447. *        功能:          寫(xiě)允許(將WEN置位)
  448. --------------------------------------------------*/
  449. void WriteEnable(void)
  450. {
  451.      NSS=0;
  452.      SPI_RW(0X06);
  453.      NSS=1;
  454. }
  455. /*-------------------------------------------------
  456. *        函數(shù)名WriteDisable
  457. *        功能:          寫(xiě)禁止(將WEN復(fù)位)
  458. --------------------------------------------------*/
  459. void WriteDisable(void)
  460. {
  461.      NSS=0;
  462.      SPI_RW(0X04);
  463.      NSS=1;
  464. }
  465. /*-------------------------------------------------
  466. *        函數(shù)名:SPI_ReadStatus
  467. *        功能:         讀取25C64芯片的狀態(tài)
  468. *        返回值:狀態(tài)寄存器數(shù)據(jù)字節(jié)
  469. *        注:                  25C64內(nèi)部狀態(tài)寄存器第0位=0表示空閑,0位=1表示忙。
  470. --------------------------------------------------*/
  471. uchar SPI_ReadStatus(void)
  472. {
  473.      uchar status=0;
  474.      NSS=0;
  475.      SPI_RW(0X05);                                //0x05讀取狀態(tài)的命令字
  476.      status=SPI_RW(0X00);
  477.      NSS=1;                                                        //關(guān)閉片選
  478.      return status;
  479. }
  480.   /*-------------------------------------------------
  481. *        函數(shù)名:SPI_WriteStatus
  482. *        功能:         寫(xiě)25C64芯片的狀態(tài)寄存器
  483. *        注:                  只有BP1、BP0(bit7、3、2)可以寫(xiě)
  484.                                  25C64內(nèi)部狀態(tài)寄存器第0位=0表示空閑,0位=1表示忙。
  485. --------------------------------------------------*/
  486. void SPI_WriteStatus(uchar Status)
  487. {
  488.      NSS=0;
  489.      SPI_RW(0X01);                //0X01寫(xiě)入狀態(tài)的命令字
  490.      SPI_RW(Status);                //寫(xiě)入一個(gè)字節(jié)
  491.      NSS=1;                                        //關(guān)閉片選
  492. }



  493. //  /*-------------------------------------------------
  494. // *        函數(shù)名SPI_Read
  495. // *        輸入:          16位的地址
  496. // *        返回:         讀取的數(shù)據(jù)
  497. // *        說(shuō)明:          從25C64指定的地址讀取一個(gè)字節(jié)
  498. // --------------------------------------------------*/
  499. // uchar SPI_Read(uint addr)
  500. // {
  501. //     uchar spidata;
  502. //     while(SPI_ReadStatus()&0x01);                //判斷是否忙
  503. //     NSS=0;                                                                                        //使能器件
  504. //     SPI_RW(0X03);                                                                //發(fā)送讀取命令
  505. //     SPI_RW((uchar)((addr)>>8));
  506. //     SPI_RW((uchar)addr);
  507. //     spidata=SPI_RW(0X00);                                        //讀出數(shù)據(jù)
  508. //     NSS=1;
  509. //     return spidata;
  510. // }
  511. //   /*-------------------------------------------------
  512. // *        函數(shù)名SPI_Write
  513. // *        輸入:          地址,字節(jié)數(shù)據(jù)
  514. // *        說(shuō)明:          將一個(gè)字節(jié)寫(xiě)入指定的地址
  515. // --------------------------------------------------*/
  516. //void SPI_Write(uint addr , uchar dat)
  517. // {
  518. //     while(SPI_ReadStatus()&0x01);                //判斷是否忙
  519. //     WriteEnable();                                                                        //SET WEN
  520. //     NSS=0;                                                                                        //使能器件
  521. //     SPI_RW(0X02);                                                                //發(fā)送寫(xiě)命令
  522. //     SPI_RW((uchar)((addr)>>8));                        
  523. //     SPI_RW((uchar)addr);
  524. //     
  525. //     SPI_RW(dat);
  526. //     WriteDisable();
  527. //     NSS=1;                                                                                        //關(guān)閉片選
  528. //     while(SPI_ReadStatus()&0x01);
  529. // }




  530.   /*-------------------------------------------------
  531. //讀取SPI FLASH  
  532. //在指定地址開(kāi)始讀取指定長(zhǎng)度的數(shù)據(jù)
  533. //pbuf:數(shù)據(jù)存儲(chǔ)區(qū)
  534. //addr:開(kāi)始讀取的地址(24bit)
  535. //Len:要讀取的字節(jié)數(shù)(最大65535) *        函數(shù)名SPI_Read
  536. *        輸入:          16位的地址
  537. *        返回:         讀取的數(shù)據(jù)
  538. *        說(shuō)明:          W25Q32指定的地址讀取一個(gè)字節(jié)
  539. --------------------------------------------------*/
  540. void SPI_Flash_Read(uchar *pbuf,ulong addr,uint Len)  
  541. {
  542.      uint i;
  543.      while(SPI_ReadStatus()&0x01);                //判斷是否忙
  544.      NSS=0;                                                                                        //使能器件
  545.      SPI_RW(0X03);                                                                //發(fā)送讀取命令

  546.          SPI_RW((uchar)((addr)>>16));  //  
  547.      SPI_RW((uchar)((addr)>>8));
  548.      SPI_RW((uchar)addr);

  549.          for(i=0;i<Len;i++)
  550.      {
  551.          *pbuf++ = SPI_RW(0X00);
  552.      }
  553.      NSS=1;
  554. }


  555. //SPI在一頁(yè)(0~65535)內(nèi)寫(xiě)入少于256個(gè)字節(jié)的數(shù)據(jù)
  556. //在指定地址開(kāi)始寫(xiě)入最大256字節(jié)的數(shù)據(jù)
  557. //pbuf:數(shù)據(jù)存儲(chǔ)區(qū)
  558. //addr:開(kāi)始寫(xiě)入的地址(24bit)
  559. //Len:要寫(xiě)入的字節(jié)數(shù)(最大256),該數(shù)不應(yīng)該超過(guò)該頁(yè)的剩余字節(jié)數(shù)!!!  
  560. void W25X_Flash_Write_Page(uchar *pbuf,ulong addr,uint Len)
  561. {
  562.         uint i;
  563.     while(SPI_ReadStatus()&0x01);                //判斷是否?
  564.     WriteEnable();                 //SET WEL
  565.     NSS=0;                         //使能器件   
  566.     SPI_RW(0x02);                  //發(fā)送寫(xiě)頁(yè)命令
  567.     SPI_RW((uchar)((addr)>>16));   //發(fā)送24bit地址   
  568.     SPI_RW((uchar)((addr)>>8));   
  569.     SPI_RW((uchar)addr);  

  570.     for(i=0;i<Len;i++)               //循環(huán)寫(xiě)數(shù)
  571.     {
  572.         SPI_RW(*pbuf++);      
  573.     }
  574.     NSS=1;                              //取消片選
  575.     while(SPI_ReadStatus()&0x01);   //等待寫(xiě)入結(jié)束   
  576. }


  577. //無(wú)檢驗(yàn)寫(xiě)SPI FLASH
  578. //必須確保所寫(xiě)的地址范圍內(nèi)的數(shù)據(jù)全部為0XFF,否則在非0XFF處寫(xiě)入的數(shù)據(jù)將失敗!
  579. //具有自動(dòng)換頁(yè)功能
  580. //在指定地址開(kāi)始寫(xiě)入指定長(zhǎng)度的數(shù)據(jù)
  581. //pbuf:數(shù)據(jù)存儲(chǔ)區(qū)
  582. //addr:開(kāi)始寫(xiě)入的地址(24bit)
  583. //Len:要寫(xiě)入的字節(jié)數(shù)(最大65535)
  584. void SPI_Flash_Write_NoCheck(uchar *pbuf,ulong addr,uint Len)
  585. {
  586.     uint PageLen;                  // 頁(yè)內(nèi)寫(xiě)入字節(jié)長(zhǎng)度
  587.     PageLen=256-addr%256;    // 單頁(yè)剩余的字節(jié)數(shù) (單頁(yè)剩余空間)
  588.     if(Len <= PageLen) PageLen=Len; // 不大于256 個(gè)字節(jié)
  589.     while(1)
  590.     {
  591.         W25X_Flash_Write_Page(pbuf,addr,PageLen);
  592.         if(PageLen == Len) break;   // 寫(xiě)入結(jié)束了
  593.         else
  594.         {
  595.             pbuf += PageLen;
  596.             addr += PageLen;
  597.             Len -= PageLen;              //  減去已經(jīng)寫(xiě)入了的字節(jié)數(shù)
  598.             if(Len>256) PageLen = 256;   // 一次可以寫(xiě)入256 個(gè)字節(jié)
  599.             else  PageLen = Len;          // 不夠256 個(gè)字節(jié)了
  600.         }
  601.     }
  602. }


  603. //*************** 4K扇擦除************************OK
  604. //擦除一個(gè)扇區(qū)
  605. //Dst_Addr:扇區(qū)地址 0~511 for w25x16
  606. //擦除一個(gè)扇區(qū)的最少時(shí)間:150ms
  607. void W25X_SectorErase(ulong Addr24) //擦除資料圖示的4KB空間
  608. {
  609.     uchar Addr1;       // 最低地址字節(jié)
  610.     uchar Addr2;       // 中間地址字節(jié)
  611.     uchar Addr3;       // 最高地址字節(jié)  

  612.     Addr1=Addr24;
  613.     Addr24=Addr24>>8;
  614.     Addr2=Addr24;
  615.     Addr24=Addr24>>8;
  616.     Addr3=Addr24;                      // 把地址拆開(kāi)來(lái)  
  617.     while(SPI_ReadStatus()&0x01);   // 判斷是否忙   
  618.     WriteEnable();                       // 寫(xiě)允許
  619.     NSS=0;
  620.     SPI_RW(0x20);       // 整扇擦除命令
  621.     SPI_RW(Addr3);
  622.     SPI_RW(Addr2);
  623.     SPI_RW(Addr1);
  624.     NSS=1;
  625.     while(SPI_ReadStatus()&0x01);    // 等待擦除完成
  626. }


  627. //*************** 塊擦除/64K頁(yè)************************* OK
  628. void W25X_BlockErase(ulong Addr24)  //擦除資料圖示的64KB空間
  629. {
  630.     uchar Addr1;       // 最低地址字節(jié)
  631.     uchar Addr2;       // 中間地址字節(jié)
  632.     uchar Addr3;       // 最高地址字節(jié)  

  633.     Addr1=Addr24;
  634.     Addr24=Addr24>>8;
  635.     Addr2=Addr24;
  636.     Addr24=Addr24>>8;
  637.     Addr3=Addr24;                      // 把地址拆開(kāi)來(lái)  
  638.     while(SPI_ReadStatus()&0x01);  // 判斷是否忙   
  639.     WriteEnable();                      // 寫(xiě)允許
  640.     NSS=0;
  641.     SPI_RW(0xD8);       // 整扇擦除命令
  642.     SPI_RW(Addr3);
  643.     SPI_RW(Addr2);
  644.     SPI_RW(Addr1);
  645.     NSS=1;
  646.     while(SPI_ReadStatus()&0x01);   // 等待擦除完成
  647. }

  648. //**************片擦除  ****************** OK
  649. // W25X16:25S     W25X32:40S   W25X64:40S
  650. void W25X_ChipErase(void)
  651. {
  652.     while(SPI_ReadStatus()&0x01);      // 判斷是否忙   
  653.     WriteEnable();                     // 寫(xiě)允許
  654.     NSS=0;
  655.     SPI_RW(0xC7);                      // 整片擦除命令
  656.     NSS=1;                             // 從CS=1時(shí)開(kāi)始執(zhí)行擦除
  657.     while(SPI_ReadStatus()&0x01);      // 等待擦除完成   
  658. }
復(fù)制代碼


FT64F0Ax_SPI.pdf

1.02 MB, 下載次數(shù): 1

FT64F0A5_SPI_TEST_000.rar

5.79 KB, 下載次數(shù): 1

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏3 分享淘帖 頂1 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:59830 發(fā)表于 2023-6-26 14:57 | 只看該作者
今天找到原因,25C64 與 25Q32 驅(qū)動(dòng)是有區(qū)別的.

按25Q32修改后能正常通信了.

//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);      // 等待擦除完成   
}




FT64F0A5_SPI_TEST_000.rar

5.79 KB, 下載次數(shù): 2

評(píng)分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 国产一区二区黑人欧美xxxx | 欧美成人高清 | 91丨国产 | 亚洲一区二区三区四区五区中文 | 自拍偷拍第一页 | 国产网站在线播放 | 日韩欧美视频免费在线观看 | 免费超碰 | 久久精品色欧美aⅴ一区二区 | 国产精品99久久久久久久久久久久 | 激情黄色在线观看 | 日韩美女在线看免费观看 | 视频在线观看亚洲 | 99精品视频在线 | 亚洲国产aⅴ精品 | 中文字幕1区2区3区 亚洲国产成人精品女人久久久 | 国产高清91| 久久国产精品首页 | 色在线免费视频 | 亚洲精品v日韩精品 | 亚洲福利网 | 亚洲一区二区不卡在线观看 | 成人精品福利 | 特一级毛片 | 久久国产精品免费一区二区三区 | 在线视频中文字幕 | 91精品国产综合久久香蕉麻豆 | 久久婷婷麻豆国产91天堂 | 亚洲h在线观看 | 日韩一区二区三区av | 精品视频一区二区三区在线观看 | 亚洲一区影院 | 亚洲综合在线一区 | 成人av一区二区三区 | 粉嫩国产精品一区二区在线观看 | 一区二区三区在线播放 | 国产精品毛片一区二区在线看 | 99国产精品久久久 | 天天干天天草 | 国产欧美在线视频 | 天天搞天天搞 |