<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > STM32 SPI W25X16驅動

          STM32 SPI W25X16驅動

          作者: 時間:2016-11-25 來源:網(wǎng)絡 收藏
          前面說了STM32的I2C,作為STM32的另外一個串行接口就不得不提到了——SPI。與I2C差不多,同樣有硬件接口,有庫函數(shù)支持,我們要做的就是結合SPI接口芯片調用庫函數(shù),就能實現(xiàn)SPI驅動了。一切看代碼,你會懂的,注釋非常詳細的,很適合初學者。代碼能夠直接用到實際項目工程里面去的。SPI芯片選用W25X系列。。。

          演示效果使用超級終端或者SecureCRT 5.5(這貨真的不錯)

          本文引用地址:http://www.ex-cimer.com/article/201611/321302.htm

          工程結構圖:

          1、工程里面的beep.c led.c usart1.c 與《STM32 基于庫函數(shù)控制按鍵&nb… 》《STM32 串口例程之查詢收》里面完全一樣,這里就不在上代碼。

          2、main.c

          //程序功能:主要用于測試SPI W25X16驅動是否正常


          #include"stm32f10x.h"
          #include"user_usart1.h"
          #include"user_led.h"
          #include"user_beep.h"
          #include"user_spi_w25x16.h"
          #include


          #define FLASH_ID1 0xef3015
          #define FLASH_ID2 0xef4015
          #define FLASH_WriteAddress 0x000000
          #define FLASH_ReadAddress FLASH_WriteAddress
          #define FLASH_SectorErase FLASH_WriteAddress

          #define CountOf(a) (sizeof(a)/sizeof(*(a)))
          #define DataSize(CountOf(TxDataTable)-1)

          u8 TxDataTable[]="Hello,I am wgchnln,我 愛 ARM,I will persist in learning ARM,堅決不放棄";
          u8 RxDataTable[DataSize];


          //=============================================
          #ifdef __GNUC__

          #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
          #else
          #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
          #endif
          //=============================================



          TestStatus User_SPI_DataCompare(u8 *TxData,u8 *RxData,u8 Num)
          {
          while(Num--)
          {
          if(*TxData!=*RxData)
          {
          return Failed;
          }
          RxData++;
          TxData++;
          }

          return Successed;
          }


          void User_SPI_Test(void)
          {
          vu32 ID,DeviceID;
          u8 Buffer;
          volatile TestStatus Test1=Failed;
          volatile TestStatus Test2=Successed; //存放兩次測試的結果


          printf("正在努力讀取ID號.....");
          User_LedSpark(Led1,2);
          ID=User_SPI_W25X16_ReadID();
          printf("flashID:%x",ID);

          printf("正在努力讀取DeviceID號......");
          User_LedSpark(Led1,2);
          DeviceID=User_SPI_W25X16_ReadDeviceID();
          printf("flashDeviceID:%x",DeviceID);



          if((ID==FLASH_ID1)||(ID==FLASH_ID2))
          {

          printf("ARM在芯片擦除......");
          User_LedSpark(Led1,2);
          User_SPI_W25X16_SectorErase(FLASH_SectorErase);
          printf("完成");


          printf("你要寫入的數(shù)據(jù):%s",TxDataTable);
          printf("努力為你芯片寫入中......");
          User_LedSpark(Led1,2);
          User_SPI_W25X16_ChipWrite(TxDataTable,FLASH_WriteAddress,DataSize);
          printf("完成");


          printf("芯片數(shù)據(jù)讀取......");
          User_LedSpark(Led1,2);
          User_SPI_W25X16_ChipRead(RxDataTable,FLASH_ReadAddress,DataSize);
          printf("完成");
          User_LedSpark(Led1,2);
          printf("為您讀取的數(shù)據(jù):%s",RxDataTable);


          printf("為您做數(shù)據(jù)比較中......");
          User_LedSpark(Led1,2);
          Test1=User_SPI_DataCompare(RxDataTable,TxDataTable,DataSize);
          if(Test1==Successed)
          {
          printf("數(shù)據(jù)相同");
          }
          else
          {
          printf("數(shù)據(jù)不相同");
          User_LedSpark(Led2,2);
          printf("為您分析可能原因:數(shù)據(jù)未寫入、讀取錯誤、或者兩者同時存在");
          }


          printf("再一次芯片擦除......");
          User_LedSpark(Led1,2);
          User_SPI_W25X16_SectorErase(FLASH_SectorErase);
          printf("完成");


          printf("又一次芯片讀取......");
          User_LedSpark(Led1,2);
          User_SPI_W25X16_ChipRead(RxDataTable,FLASH_ReadAddress,DataSize);
          printf("完成");


          printf("判斷是否擦除掉......");
          User_LedSpark(Led1,1);
          for(Buffer=0;Buffer
          {
          if(RxDataTable[Buffer]!=0xff)
          {
          Test2=Failed;
          }
          }
          if(Test2==Failed)
          {
          printf("失敗");
          printf("為您分析的可能原因:讀取錯誤、擦除失敗、或者兩者同時存在");
          }
          else
          {
          printf("擦除OK");
          }


          printf("------------為您展示此次測試結果------------");
          if((Test1==Successed)&&((Test2==Successed)))
          {
          User_LedSpark(Led1,2);
          printf("恭喜你,SPI W25X16驅動測試通過啦");
          }
          else
          {
          User_LedSpark(Led2,2);
          printf("糟糕,SPI功能演示失敗了......原因可能是讀寫數(shù)據(jù)不一致、軟件擦除失敗");
          }
          }


          else
          {
          User_LedSpark(Led2,2);
          printf("悲劇了,SPI功能演示失敗啦.....原因是芯片ID號碼讀取出錯哦");
          }
          }


          int main(void)
          {
          User_USART1Config();
          printf("串口1配置......");
          printf("完成");

          printf("蜂鳴器初始化...");
          User_BeepConfig();
          printf("蜂鳴器測試......");
          User_BeepStatus(BeepStatus_TurnOn);
          printf("完成");

          printf("LED初始化...");
          User_LedConfig();
          printf("LED測試......");
          User_LedSpark(Led0,2);
          printf("完成");

          printf("SPI初始化...");
          User_SPI_Config();
          User_LedSpark(Led0,2);
          printf("完成");

          User_SPI_Test();

          while(1);
          }

          //==================================================
          PUTCHAR_PROTOTYPE
          {


          USART_SendData(USART1, (uint8_t) ch);


          while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
          {}

          return ch;
          }
          //==================================================

          3、user_spi_w25x16.c

          //program function:SPI1 Init && FLASF Chip W25X16 driver


          #include"stm32f10x.h"
          #include"user_spi_w25x16.h"
          #include



          #define WriteEnable0x06
          #define WriteDisable0x04
          #define ReadStatusRegister0x05
          #define WriteStatusRegister0x01
          #define ReadData0x03
          #define FastRead0x0b
          #define FsatReadDualOutput0x3b
          #define PageProgram0x02
          #define BlukErase0xd8
          #define SectorErase0x20
          #define ChipErase0xc7
          #define PowerDown0xb9
          #define WakeUp0xab
          #define DeviceID0xab
          #define ManufatureID0x90
          #define JedecID0x9f

          #define JudgeCode0x01 //用于判斷通訊是否結束用
          #define NoneCode0xa5 //無意義的指令,用于:接收數(shù)據(jù)時,發(fā)送這個質量來產生接收時候的時鐘



          void User_SPI_Config(void)
          {


          SPI_InitTypeDef SPI_InitStructure;

          GPIO_InitTypeDef GPIO_InitStructure;



          RCC_APB2PeriphClockCmd(SPI_24G_CS_Clock,ENABLE);
          GPIO_InitStructure.GPIO_Pin =SPI_24G_CS_Pin;
          GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP;
          GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
          GPIO_Init(SPI_24G_CS_Port,&GPIO_InitStructure);
          GPIO_SetBits(SPI_24G_CS_Port,SPI_24G_CS_Pin);


          RCC_APB2PeriphClockCmd(SPI_VS1003B_CS_Clock,ENABLE);
          GPIO_InitStructure.GPIO_Pin =SPI_VS1003B_CS_Pin;
          GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP;
          GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
          GPIO_Init(SPI_VS1003B_CS_Port,&GPIO_InitStructure);
          GPIO_SetBits(SPI_VS1003B_CS_Port,SPI_VS1003B_CS_Pin);



          RCC_APB2PeriphClockCmd(SPI_W25X16_Clock,ENABLE);

          RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);



          RCC_APB2PeriphClockCmd(SPI_W25X16_CS_Clock,ENABLE);
          GPIO_InitStructure.GPIO_Pin =SPI_W25X16_CS_Pin;
          GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP;
          GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
          GPIO_Init(SPI_W25X16_CS_Port,&GPIO_InitStructure);
          SPI_W25X16_CS_DisSelect;


          RCC_APB2PeriphClockCmd(SPI_W25X16_SCK_Clock,ENABLE);
          GPIO_InitStructure.GPIO_Pin =SPI_W25X16_SCK_Pin;
          GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF_PP;
          GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
          GPIO_Init(SPI_W25X16_SCK_Port,&GPIO_InitStructure);


          RCC_APB2PeriphClockCmd(SPI_W25X16_MISO_Clock,ENABLE);
          GPIO_InitStructure.GPIO_Pin =SPI_W25X16_MISO_Pin;
          GPIO_Init(SPI_W25X16_MISO_Port,&GPIO_InitStructure);


          RCC_APB2PeriphClockCmd(SPI_W25X16_MOSI_Clock,ENABLE);
          GPIO_InitStructure.GPIO_Pin =SPI_W25X16_MOSI_Pin;
          GPIO_Init(SPI_W25X16_MOSI_Port,&GPIO_InitStructure);



          SPI_InitStructure.SPI_Direction =SPI_Direction_2Lines_FullDuplex; //通訊模式:雙向全雙工模式
          SPI_InitStructure.SPI_Mode =SPI_Mode_Master;//主從:主模式
          SPI_InitStructure.SPI_DataSize =SPI_DataSize_8b;//數(shù)據(jù)幀長度:8bits
          SPI_InitStructure.SPI_CPOL =SPI_CPOL_High;//空閑時置高
          SPI_InitStructure.SPI_CPHA =SPI_CPHA_2Edge;//第二個時鐘采樣
          SPI_InitStructure.SPI_NSS =SPI_NSS_Soft;//NSS控制選擇:軟件控制
          SPI_InitStructure.SPI_BaudRatePrescaler =SPI_BaudRatePrescaler_2;//波特率分配系數(shù):2分頻
          SPI_InitStructure.SPI_FirstBit =SPI_FirstBit_MSB;//數(shù)據(jù)幀格式:MSB在前
          SPI_InitStructure.SPI_CRCPolynomial =7;//CRC效驗多項式

          SPI_Init(SPI1,&SPI_InitStructure);

          SPI_Cmd(SPI1,ENABLE);
          }


          u8 User_SPI_W25X16_SendByte(u8 SendByteData)
          {
          u8 ReceiveData;


          while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)!=SET);

          SPI_I2S_SendData(SPI1,SendByteData);


          while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE)!=SET);

          ReceiveData=SPI_I2S_ReceiveData(SPI1);

          return ReceiveData;
          }


          u8 User_SPI_W25X16_ReadByte(void)
          {
          u8 ReceiveData;

          ReceiveData=User_SPI_W25X16_SendByte(NoneCode);

          return ReceiveData;
          }


          vu16 User_SPI_W25X16_SendHalfWord(u16 HalfWord)
          {
          vu16 ReceiveData;


          while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)!=SET);

          SPI_I2S_SendData(SPI1,HalfWord);


          while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE)!=SET);

          ReceiveData=SPI_I2S_ReceiveData(SPI1);

          return ReceiveData;
          }


          void User_SPI_W25X16_WriteEnable(void)
          {

          SPI_W25X16_CS_Select;


          User_SPI_W25X16_SendByte(WriteEnable);


          SPI_W25X16_CS_DisSelect;
          }


          上一頁 1 2 下一頁

          關鍵詞: STM32SPIW25X16驅

          評論


          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();