色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

STM32通過硬件SPI模塊軟件模擬驅動來進行拓展

冬至子 ? 來源:ITRelief ? 作者:Sachefgh Xu ? 2023-07-25 14:53 ? 次閱讀

FSMC一般只有STM32大容量產品才具備。因此在使用中小容量產品外接存儲器時,一般會通過硬件SPI模塊軟件模擬驅動來進行拓展。

本文將以常見的 NOR Flash(多個廠家有對標的同類產品)為例。

我使用的是普亞的P25Q32SH,這個flash除了貴和多一些功能外,在基本控制方面和華邦的W25Q32差不多,基本指令通用。但不同flash之間還是存在一些差異,要注意適配。

一、封裝

8引腳的spi Flash除了封裝方式有些差異,引腳排列基本是一模一樣的。

圖片

代碼:

總的來說還是很簡單的。因為時間比較趕,只求能用,存在代碼冗余和效率較低的問題,歡迎改進指正!

//******************************************************************************
//* 文件名   ExtFlashSPI.h
//* 介紹:    利用STM32硬件spi實現對spi的控制
//*  基于W25Q32,在基礎指令方面兼容
//*  使用其他芯片請參照手冊進行指令集和參數的適配
//*  
//*  ※適用最大容量為16M(128Mbit)Flash 
//* 
//* @Author  Sachefgh Xu 
//*********************************模塊介紹************************************
// 適用8引腳的spi flash
//
//
//
//引腳配置: /VCC  一般選擇 2.7-3.6v 的元件,flash對電壓有要求,推薦供電接穩壓管
//    /GND  接地
//    /CS   片選,低電平使能;上電時應當置高電平,推薦NSS引腳使能上拉或外接上拉
//    /DI(IO0) Data-in 
//    /DO         Data-out
//    /CLK  時鐘
//    /WP   寫保護 默認不啟用;啟用后高電平+寫使能指令解鎖----------本驅動中WP接vcc拉高
//    /HOLD  Hold-input; 時鐘線和hold均為低電平時觸發暫停;默認高電平------本驅動中HOLD接vcc拉高
//說明:
//對Flash時序的規定:MOSI-》DI,  flash在時鐘上升沿采樣
// MISO- >DO flash在下降沿設置。當片選使能時時鐘處于低電平,視為已接收一個下降沿。主機在上升沿讀取采樣
//配置spi模塊時,時鐘線空閑為低電平,上升沿采樣(CPHA=0,CPOL=0); MSB模式
//
//上電時,模塊寫使能被禁用。
//
/***********************************ED***********************************/
#ifndef _SWSPI_FLASH_H_
#define _SWSPI_FLASH_H_  
#include "stm32f1xx_ll_gpio.h"
#include "stm32f1xx_ll_spi.h"
#include "stm32f1xx_ll_dma.h"
#include "stm32f1xx_ll_utils.h"

/***********************************配置參數***********************************/

#define Flash_SPI SPI1   //連接的硬件spi模塊,spi應配置全雙工主機模式
#define Flash_CSPORT     GPIOA //片選線;應當配置為高速輸出,初始高電平
#define Flash_CSPIN      LL_GPIO_PIN_4

#define BlockNumber  64  //塊數量

#define Page /*Each Page has*/ 256 /*Bytes*/
#define Sector /*Each Sector has*/ 16 /*Pages*/
#define Block /*Each Block has*/ 16 /*Sectors*/
#define AddressMax (BlockNumber * Page * Sector* Block-1) //最大內存地址,每一地址對應一字節


#if (Page==256)
#define PageMsk  0xFFFF00  

 #if (Sector==16)
#define SectorMsk  0xFFF000     
 #endif // (Sector==16)


#endif 


//不同容量Flash只有塊數量有區別,一般扇區數量和頁數量一致。
//24Bits地址 最高8位標定block,高16位標定page

//頁地址     addr & 0xFFFF00
//扇區地址   addr & 0xFFF000
//塊地址  addr & 0xFF0000

//額外指令配置:

//#define _81H  //page erase頁擦除功能.-----w25qxx系列無此功能


/******************************************************************************/

 uint8_t ManufacturerID; //制造商信息
 uint8_t MemoryTypeID;
 uint8_t CapacityID; //容量信息
//上述信息在初始化時讀取

//臨時數據 


/***********************/

__STATIC_INLINE void Flash_GetInformation();
__STATIC_INLINE void Flash_WaitWriteToFinish();



/**
 * @brief  初始化函數,首先調用
 * @note  一并讀取和存儲制造商信息、容量和存儲類型數據
 */
__STATIC_INLINE void Flash_Init()
{ 
 LL_mDelay(7); //等待上電初始化,可刪
 LL_GPIO_SetOutputPin(Flash_CSPORT, Flash_CSPIN);//關閉片選
 //
 LL_SPI_Enable(Flash_SPI); //重新開啟SPI模塊
 LL_SPI_ReceiveData8(Flash_SPI); //置零RXNE
 Flash_GetInformation();
}

/**
 * @brief  讀取制造商ID、存儲類型ID、容量ID
 * @cmd:  90h
 * @note  讀取后存入 ManufacturerID、MemoryTypeID、CapacityID變量中
 */
__STATIC_INLINE void Flash_GetInformation()
{ //讀取Manufacturer ID& Device ID (90h)
 LL_GPIO_ResetOutputPin(Flash_CSPORT, Flash_CSPIN);
 LL_SPI_TransmitData8(Flash_SPI, 0x9FU);
 while (!LL_SPI_IsActiveFlag_RXNE(Flash_SPI)) ; //等待接收完
 LL_SPI_ReceiveData8(Flash_SPI);   //置零RXNE
 LL_SPI_TransmitData8(Flash_SPI, 0x00U);  //生成時鐘
 while(!LL_SPI_IsActiveFlag_RXNE(Flash_SPI)); //等待接收完
 ManufacturerID = LL_SPI_ReceiveData8(Flash_SPI);
 LL_SPI_TransmitData8(Flash_SPI, 0x00U);
 while (!LL_SPI_IsActiveFlag_RXNE(Flash_SPI)) ;//等待接收完
 MemoryTypeID = LL_SPI_ReceiveData8(Flash_SPI);
 LL_SPI_TransmitData8(Flash_SPI, 0x00U);
 while (!LL_SPI_IsActiveFlag_RXNE(Flash_SPI)) ;//等待接收完
 CapacityID = LL_SPI_ReceiveData8(Flash_SPI);
 LL_GPIO_SetOutputPin(Flash_CSPORT, Flash_CSPIN);
 
}

/**
 * @brief  使能擦寫
 * @cmd: 06h
 * @note  再通過指令進行頁寫入、扇區擦除、塊擦除、整片擦除、寫狀態寄存器時均需調用
 */
__STATIC_INLINE void Flash_WriteEnable()
{
 LL_GPIO_ResetOutputPin(Flash_CSPORT, Flash_CSPIN);
 LL_SPI_TransmitData8(Flash_SPI, 0x06U);
 while (!LL_SPI_IsActiveFlag_TXE(Flash_SPI)) ;
 LL_GPIO_SetOutputPin(Flash_CSPORT, Flash_CSPIN);
}

/**
 * @brief  禁用擦寫(寫入鎖)
 * @cmd: 04h
 * @note  寫入、擦除、寫狀態寄存器完成后調用
 */
__STATIC_INLINE void Flash_WriteDisable()
{
 LL_GPIO_ResetOutputPin(Flash_CSPORT, Flash_CSPIN);
 LL_SPI_TransmitData8(Flash_SPI, 0x04U);
 while (!LL_SPI_IsActiveFlag_TXE(Flash_SPI)) ;
 LL_GPIO_SetOutputPin(Flash_CSPORT, Flash_CSPIN);
}
/**
 * @brief  連續字節讀取(常速)
 * @cmd: 03h
 * @param 
 *  uint32_t addr  //24位地址(數據最高8位忽略),每一位代表一字節數據;addr可取任意有效地址
 *  uint8_t    *data //傳入的uint_8數組地址或者 變量地址(當讀取數為1時)
 *  uint8_t  number  //讀取字節數
 *
 * @note  發送指令03h后分3字節從高到低傳輸地址位; Flash將在之后的時鐘周期從傳入地址開始
 * 以地址遞增順序傳出片上數據(數據位數共number位),直到CS被拉高
 * 當number=1,讀取指定位數據
 */
__STATIC_INLINE void Flash_ReadData(uint32_t addr, uint8_t *data, uint16_t length)
{
 LL_GPIO_ResetOutputPin(Flash_CSPORT, Flash_CSPIN);
 LL_SPI_TransmitData8(Flash_SPI, 0x03);
 while (!LL_SPI_IsActiveFlag_TXE(Flash_SPI)) ;//傳輸完畢
 LL_SPI_TransmitData8(Flash_SPI, (uint8_t)(addr >>16)&0xFF);
 while (!LL_SPI_IsActiveFlag_TXE(Flash_SPI)) ;//傳輸完畢
 LL_SPI_TransmitData8(Flash_SPI, (uint8_t)((addr > > 8)&0xFF));
 while (!LL_SPI_IsActiveFlag_TXE(Flash_SPI)) ;//傳輸完畢
 LL_SPI_TransmitData8(Flash_SPI, (uint8_t)(addr & 0xFF));
 while (!LL_SPI_IsActiveFlag_TXE(Flash_SPI)) ;
 LL_SPI_ReceiveData8(Flash_SPI);//置零標志
 //開始讀取
 for(uint16_t i = 0 ; i < length ; i++)
 {
  LL_SPI_TransmitData8(Flash_SPI, 0x00U);//generate clock
  while (!LL_SPI_IsActiveFlag_RXNE(Flash_SPI)) ;//wait till tranfer complete
  data[i] = LL_SPI_ReceiveData8(Flash_SPI);
 }
 LL_GPIO_SetOutputPin(Flash_CSPORT, Flash_CSPIN);
 //延時
 uint16_t dlay=0;
 while (dlay < 960){dlay++;}
}
/**
 * @brief  整片擦除(變為FF)  ※此操作無法復原,使用請謹慎
 * @cmd: 60h(或C7h)
 * @note 將整片flash數據擦除
 */
__STATIC_INLINE void Flash_EraseChip()
{
 Flash_WriteEnable();//使能寫
 LL_GPIO_ResetOutputPin(Flash_CSPORT, Flash_CSPIN);
 LL_SPI_TransmitData8(Flash_SPI, 0x60U);
 while (!LL_SPI_IsActiveFlag_TXE(Flash_SPI)) ;//傳輸完畢
 LL_mDelay(1);
 LL_GPIO_SetOutputPin(Flash_CSPORT, Flash_CSPIN);
 Flash_WaitWriteToFinish();
}

#ifdef _81H    
/**
 * @brief  擦除整個page(將整頁256bytes數據寫為FF)  ※此操作無法復原,使用請謹慎
 * @cmd: 81h
 * @param:  uint32_t addr  //24位頁地址(數據最高8位忽略)。前16位規定頁地址,最后8位無意義(dummy)。
 *  addr可填位于 目標頁 的任一地址 
 * 
 * @note 擦除指定Page上的內容;寫入前必須先進行擦除
 */
__STATIC_INLINE void Flash_ErasePage(uint32_t addr)
{
 Flash_WriteEnable();//使能讀寫
 
 LL_GPIO_ResetOutputPin(Flash_CSPORT, Flash_CSPIN);
 LL_SPI_TransmitData8(Flash_SPI, 0x81U);
 while (!LL_SPI_IsActiveFlag_TXE(Flash_SPI)) ;//傳輸完畢
 LL_SPI_TransmitData8(Flash_SPI, (uint8_t)(addr > > 16)&0xFF);
 while (!LL_SPI_IsActiveFlag_TXE(Flash_SPI)) ;//傳輸完畢
 LL_SPI_TransmitData8(Flash_SPI, (uint8_t)((addr > > 8) & 0xFF));
 while (!LL_SPI_IsActiveFlag_TXE(Flash_SPI)) ;//傳輸完畢
 LL_SPI_TransmitData8(Flash_SPI, 0X00U);
 while (!LL_SPI_IsActiveFlag_TXE(Flash_SPI)) ;//傳輸完畢
 LL_GPIO_SetOutputPin(Flash_CSPORT, Flash_CSPIN);
 Flash_WaitWriteToFinish();
}
#endif
/**
 * @brief  擦除整個sector(4096bytes = 16 pages)  ※此操作無法復原,使用請謹慎
 * @cmd: 20h
 * @param:  uint32_t addr  //24位扇區地址(數據最高8位忽略)。扇區由addr A23-A12確定
 *  addr可填位于 目標扇區 的任一地址
 * @note 擦除指定Page上的內容;寫入前必須先進行擦除
 */
__STATIC_INLINE void Flash_EraseSector(uint32_t addr)
{
 Flash_WriteEnable();
 LL_GPIO_ResetOutputPin(Flash_CSPORT, Flash_CSPIN);
 LL_SPI_TransmitData8(Flash_SPI, 0x20U);
 while (!LL_SPI_IsActiveFlag_TXE(Flash_SPI)) ;
 LL_SPI_TransmitData8(Flash_SPI, (uint8_t)(addr > > 16)&0xFF);
 while (!LL_SPI_IsActiveFlag_TXE(Flash_SPI)) ;
 LL_SPI_TransmitData8(Flash_SPI, (uint8_t)((addr > > 8) & 0xF0));
 while (!LL_SPI_IsActiveFlag_TXE(Flash_SPI)) ;
 LL_SPI_TransmitData8(Flash_SPI, 0X00U);
 while (!LL_SPI_IsActiveFlag_TXE(Flash_SPI)) ;
 LL_GPIO_SetOutputPin(Flash_CSPORT, Flash_CSPIN);
 Flash_WaitWriteToFinish();
}
/**
 * @brief  等待退出寫BUSY狀態
 * @retval   
 */
__STATIC_INLINE void Flash_WaitWriteToFinish()
{
 LL_GPIO_ResetOutputPin(Flash_CSPORT, Flash_CSPIN);
 LL_SPI_TransmitData8(Flash_SPI, 0x05U);
 while (!LL_SPI_IsActiveFlag_RXNE(Flash_SPI)) ;
 LL_SPI_ReceiveData8(Flash_SPI);//clear DR
 do
 {
  LL_SPI_TransmitData8(Flash_SPI, 0x00);//dummy   
  while (!LL_SPI_IsActiveFlag_RXNE(Flash_SPI)) ;
 } while ((LL_SPI_ReceiveData8(Flash_SPI) & 0x01));//忙時循環,不忙退出
 LL_GPIO_SetOutputPin(Flash_CSPORT, Flash_CSPIN);
}

/**************************************************************************************************/

//有問題
/**
 * @brief  寫入數據,伴有覆蓋擦除功能
 * @cmd: 02h
 * @param:  uint32_t addr  //24位地址(數據最高8位忽略),可填片上任意地址;寫入
 * 將從該地址開始遞增, ※但寫入數據長度不能溢出地址所在頁(1頁256Bytes).
 * 
 * @param  uint8_t length //數據長度,必須大于0
 * @param  uint8_t *data  //寫入數據所在地址指針
 * 
 * @note 本函數工作原理如下:
 * 1.通過宏定義判斷是否有頁擦除功能
 * 2.將需要寫入地址所在的扇區/頁數據暫存至temp中
 * 3.進行頁/扇區擦除操作
 * 4.將temp對應位置數據用data中待寫入數據替換
 * 5.將更改后的temp原位寫入
 */
__STATIC_INLINE void Flash_WriteData(uint32_t addr, uint8_t *data, uint16_t length)
{
#ifdef _81H //有頁擦除功能
 Flash_WriteEnable();
 uint8_t temp[Page];
 Flash_ReadData((addr & 0xFFFF00), temp, Page);//Read Page
 //根據邏輯分析儀調整ReadData函數最后延遲時間,當執行下一個06h指令時MISO應當不輸出(0x00)
 Flash_ErasePage(addr); 
 for (uint16_t i = 0; i < length; i++)
 {
  temp[(addr & 0x0000FF) + i] = data[i];
 }//操作成功 
 Flash_WaitWriteToFinish(); 
 Flash_WriteEnable();  
 LL_GPIO_ResetOutputPin(Flash_CSPORT, Flash_CSPIN); 
 LL_SPI_TransmitData8(Flash_SPI, 0x02U); 
 while (!LL_SPI_IsActiveFlag_TXE(Flash_SPI)) ;//傳送頁地址
 LL_SPI_TransmitData8(Flash_SPI, (uint8_t)(addr > > 16)&0xFF);
 while (!LL_SPI_IsActiveFlag_TXE(Flash_SPI)) ;
 LL_SPI_TransmitData8(Flash_SPI, (uint8_t)((addr > > 8) & 0xFF));
 while (!LL_SPI_IsActiveFlag_TXE(Flash_SPI)) ; 
 LL_SPI_TransmitData8(Flash_SPI, 0x00U);
 while (!LL_SPI_IsActiveFlag_TXE(Flash_SPI)) ;
 
 for (uint16_t j = 0; j < Page; j++)
 { //發送沒問題
  LL_SPI_TransmitData8(Flash_SPI,temp[j]);
  while (!LL_SPI_IsActiveFlag_TXE(Flash_SPI)) ;
 }
 LL_GPIO_SetOutputPin(Flash_CSPORT, Flash_CSPIN);
 Flash_WaitWriteToFinish();
#else //無頁擦除功能,扇區(Sector)擦除
 uint8_t temp[Sector * Page]; // 緩存 
 Flash_WriteEnable();
 Flash_ReadData((addr & SectorMsk), temp, Sector * Page); 
 Flash_EraseSector(addr);
 for (uint16_t i = 0; i < length; i++)
 {
  temp[(uint16_t)(addr & 0x000FFF) + i] = data[i];
 }//替換完成
 //將數據原位寫入
 Flash_WriteEnable();
 uint32_t iaddpage= addr & SectorMsk; //扇區的起始地址
 //每次寫一頁,共Sector次
 int m = 0;
 for(uint8_t j = 0 ; j < Sector ; j++)
 {
  Flash_WriteEnable();
  LL_GPIO_ResetOutputPin(Flash_CSPORT, Flash_CSPIN);
  LL_SPI_TransmitData8(Flash_SPI, 0x02U);
  while (!LL_SPI_IsActiveFlag_TXE(Flash_SPI)) ;//傳送頁地址
  LL_SPI_TransmitData8(Flash_SPI, (uint8_t)(iaddpage > > 16)&0xFF);
  while (!LL_SPI_IsActiveFlag_TXE(Flash_SPI)) ;
  LL_SPI_TransmitData8(Flash_SPI, (uint8_t)((iaddpage > > 8) & 0xFF));
  while (!LL_SPI_IsActiveFlag_TXE(Flash_SPI)) ;
  LL_SPI_TransmitData8(Flash_SPI, 0x00U);
  while (!LL_SPI_IsActiveFlag_TXE(Flash_SPI)) ;
  for (uint16_t i = 0; i < Page; i++)
  {
   LL_SPI_TransmitData8(Flash_SPI, temp[m +i]);
   while (!LL_SPI_IsActiveFlag_TXE(Flash_SPI)) ;
  }
  LL_GPIO_SetOutputPin(Flash_CSPORT, Flash_CSPIN);
  m += 256;
  iaddpage += 0x000100U;
  Flash_WaitWriteToFinish(); 
 }
#endif 

}


#endif // !_SWSPI_FLASH_H_
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 存儲器
    +關注

    關注

    38

    文章

    7514

    瀏覽量

    164008
  • SPI
    SPI
    +關注

    關注

    17

    文章

    1711

    瀏覽量

    91774
  • 邏輯分析儀
    +關注

    關注

    3

    文章

    214

    瀏覽量

    23203
  • FSMC模塊
    +關注

    關注

    0

    文章

    9

    瀏覽量

    1940
  • 模擬驅動電路

    關注

    0

    文章

    2

    瀏覽量

    758
收藏 人收藏

    評論

    相關推薦

    基于GPIO模擬SPI接口驅動設計與實現

    SPI總線是我們常用的串行設備接口,一般情況下我們都會適應硬件SPI接口,但有些時候當硬件端口不足時,我們也希望可以使用軟件
    發表于 12-07 16:21 ?6444次閱讀
    基于GPIO<b class='flag-5'>模擬</b>的<b class='flag-5'>SPI</b>接口<b class='flag-5'>驅動</b>設計與實現

    關于在軟件上開發過硬件模擬測試軟件

    不知道各位有沒有關于在軟件上開發過硬件模擬測試軟件,或者是知道有這么一個軟件的,介紹給我,謝謝!或者有關于這個想法的可以與我討論,謝謝!這
    發表于 10-08 15:23

    stm32怎么通過硬件仿真的方法來找錯?

    stm32怎么通過硬件仿真的方法來找錯?
    發表于 09-11 19:17

    硬件SPI軟件模擬SPI速度區別

    ,LORA芯片SX1278等。最近為了驅動彩色OLED顯示屏,為了提高顯示刷新率,需要對程序代碼進行優化。于是,將相關SPI驅動軟件
    發表于 07-01 06:40

    怎樣通過硬件spi讀取offset與gain寄存器的值呢

    之前寫過了mcu通過硬件spi接口向dac芯片ad5764的數據寄存器寫值輸出電壓,ad5764的offset與gain寄存器的值也是可以通過硬件spi讀出來的。第一步:將待讀取的芯片
    發表于 02-14 07:39

    如何軟件模擬SPI

    模擬SPI NRF24L01模塊的簡單使用軟件模擬SPI(注:默認已經充分了解
    發表于 02-16 06:59

    STM32F10x_SPI硬件接口 + 軟件模擬)讀寫Flash(25Q16)

    STM32F10x_SPI硬件接口 + 軟件模擬)讀寫Flash(25Q16)
    的頭像 發表于 03-25 13:59 ?1.1w次閱讀
    <b class='flag-5'>STM32F10x_SPI</b> (<b class='flag-5'>硬件</b>接口 + <b class='flag-5'>軟件</b><b class='flag-5'>模擬</b>)讀寫Flash(25Q16)

    單片機通過模擬SPI驅動LD3320模塊

    單片機通過模擬SPI驅動LD3320模塊僅完成識別部分!僅完成識別部分!僅完成識別部分!根據手冊推薦使用3.3V,而不是5V
    發表于 12-16 16:52 ?7次下載
    單片機<b class='flag-5'>通過</b><b class='flag-5'>模擬</b><b class='flag-5'>SPI</b><b class='flag-5'>驅動</b>LD3320<b class='flag-5'>模塊</b>

    SPI軟件模擬 NRF24L01

    模擬SPI NRF24L01模塊的簡單使用軟件模擬SPI(注:默認已經充分了解
    發表于 12-17 18:04 ?8次下載
    <b class='flag-5'>SPI</b><b class='flag-5'>軟件</b><b class='flag-5'>模擬</b> NRF24L01

    STM32 SPI 軟件NSS和硬件NSS解讀

    [導讀]SSM可以控制內部NSS引腳與SSI(一個寄存器,軟件模式)相連,還是與NSS外部引腳(真正的STM32引腳,硬件模式)相連。真正作用的是內部NSS引腳(內部NSS引腳才真正連接到SP
    發表于 12-22 19:12 ?14次下載
    <b class='flag-5'>STM32</b> <b class='flag-5'>SPI</b> <b class='flag-5'>軟件</b>NSS和<b class='flag-5'>硬件</b>NSS解讀

    硬件SPI軟件模擬SPI速度區別實測

    ,LORA芯片SX1278等。最近為了驅動彩色OLED顯示屏,為了提高顯示刷新率,需要對程序代碼進行優化。于是,將相關SPI驅動軟件
    發表于 12-22 19:13 ?9次下載
    <b class='flag-5'>硬件</b><b class='flag-5'>SPI</b>與<b class='flag-5'>軟件</b><b class='flag-5'>模擬</b><b class='flag-5'>SPI</b>速度區別實測

    軟件模擬SPI

    軟件模擬硬件操作SPI更為簡單,缺點是明顯更加消耗CPU軟件SPI實例:CPOL=1,CPHA
    發表于 12-22 19:15 ?10次下載
    <b class='flag-5'>軟件</b><b class='flag-5'>模擬</b><b class='flag-5'>SPI</b>

    stm32f103使用dma和fpga進行spi通信

    stm32作為從機,fpga作為主機。進行spi通信。stm32使用dma進行數據接收。在dma中斷中
    發表于 12-22 19:29 ?95次下載
    <b class='flag-5'>stm32</b>f103使用dma和fpga<b class='flag-5'>進行</b><b class='flag-5'>spi</b>通信

    單片機spi接口的使用方法有哪些(spi接口和串口的區別)

    如果單片機沒有硬件SPI模塊,或者需要額外的IO引腳實現多個SPI設備的通信,可以使用軟件
    的頭像 發表于 11-10 16:38 ?4025次閱讀

    硬件spi軟件spi的區別

    硬件SPI(串行外設接口)和軟件SPI是兩種不同的SPI傳輸方式。SPI是一種同步串行數據通信協
    的頭像 發表于 12-26 16:55 ?6107次閱讀
    主站蜘蛛池模板: 伊人久久综合影院| 粉嫩无套白浆第一次jk| 久久91精品久久久久久水蜜桃| 午夜dj影院视频观看| 国产在线一区观看| 91popny蜜桃臀| 少妇伦子伦情品无吗| 极品少妇高潮XXXXX| 99久久亚洲精品影院| 十九岁在线观看免费完整版电影| 和姐姐做插得很深| 99久久久无码国产AAA精品| 神马伦理不卡午夜电影| 久久91精品国产91久久户| jk制服喷水| 亚洲 欧洲 国产 日产 综合| 久久婷婷久久一区二区三区| 超嫩校花被灌醉在线观看| 亚洲精品无码葡京AV天堂| 牛牛在线国产精品| 韩国免费啪啪漫画无遮拦健身教练| 97久久无码精品AV| 亚洲电影二区| 日本bbwhd| 久久精品无码一区二区日韩av | 亚洲精品国产在线观看| 欧美片内射欧美美美妇| 精品国产麻豆AV无码| 成人国产三级在线播放| 一二三四高清中文版视频| 乳女教师欲乱动漫无修版动画 | 新图解av吧| 青青青久草| 久久综合狠狠综合狠狠| 国产毛A片久久久久久无码| CHINESE老阿姨免费视频| 一个人在线观看视频免费| 忘忧草在线社区WWW日本-韩国| 欧美区 bt| 老子午夜伦不卡电影院| 国内精品视频久久久久免费|