STM32CubeMx開發之路—13使用SPI讀寫W25Q64

STM32CubeMx開發之路—13使用SPI讀寫W25Q64


運行環境

  • Windows10
  • STM32CubeMX Version 5.2.0
  • Keil5(MDK5) Version 5.28.0.0

簡介

本例程主要講解如何使用硬件IIC讀寫24C02


STM32CubeMx基本配置

基礎配置過程請參考 STM32CubeMx開發之路—配置第一個項目


使用printf功能

重定向printf的過程請參考 STM32CubeMx開發之路—3發送USART數據和printf重定向

CubeMX配置

  • SPI配置

  • 根據原理圖可知需要的配置的是SPI2

  • 同時配置CS引腳, 本例CS引腳是PG13

代碼修改

  • 查看W25Q64的手冊(後面配置時需要用的命令都在裏面)

  • 封裝功能函數的代碼(講解寫在代碼裏面)
/* W25Q64的指令 */
uint8_t w25x_read_id = 0x90;					// 讀ID
uint8_t m_addr[3]    = {0,0,0};					// 測試地址0x000000
uint8_t check_addr   = 0x05;					// 檢查線路是否繁忙
uint8_t enable_write = 0x06;					// 使能了才能改變芯片數據
uint8_t erase_addr   = 0x20;					// 擦除命令
uint8_t write_addr   = 0x02;					// 寫數據命令
uint8_t read_addr    = 0x03;					// 讀數據命令

/* 讀ID */
void ReadID(void)
{
	uint8_t temp_ID[5] = {0,0,0,0,0};						// 接收緩存
	
	HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, GPIO_PIN_RESET);	// 使能CS
	HAL_SPI_Transmit(&hspi2, &w25x_read_id, 1, 100);		// 讀ID發送指令
	HAL_SPI_Receive(&hspi2, temp_ID, 5, 100);				// 讀取ID
	HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, GPIO_PIN_SET);	// 失能CS
	
	/* 測試打印 */
	printf("readID is %x%x\n",temp_ID[3],temp_ID[4]);
}

/* 檢查是否繁忙 */
void CheckBusy(void)
{
	uint8_t status=1;
	uint32_t timeCount=0;
	do
	{
		timeCount++;
		if(timeCount > 0xEFFFFFFF) //等待超時
		{
			return ;
		}
		
		HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, GPIO_PIN_RESET);	// 使能CS	
		HAL_SPI_Transmit(&hspi2, &check_addr, 1, 100);			// 發送指令
		HAL_SPI_Receive(&hspi2, &status, 1, 100);				// 讀取
		HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, GPIO_PIN_SET);	// 失能CS
		
	}while((status&0x01)==0x01);
}


/* 寫入數據 */
void ReadData(void)
{
	uint8_t temp_wdata[5] = {0x99,0x88,0x77,0x66,0x55};		// 需要寫入的數據
	
	/* 檢查是否繁忙 */
	CheckBusy();
	
	/* 寫使能 */
	HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, GPIO_PIN_RESET);	// 使能CS
	HAL_SPI_Transmit(&hspi2, &enable_write, 1, 100);		// 發送指令
	HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, GPIO_PIN_SET);	// 失能CS
	
	/* 擦除 */
	HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, GPIO_PIN_RESET);	// 使能CS
	HAL_SPI_Transmit(&hspi2, &erase_addr, 1, 100);			// 發送指令
	HAL_SPI_Transmit(&hspi2, m_addr, 3, 100);				// 發送地址
	HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, GPIO_PIN_SET);	// 失能CS
	
	/* 再次檢查是否繁忙 */
	CheckBusy();
	
	/* 寫使能 */
	HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, GPIO_PIN_RESET);	// 使能CS
	HAL_SPI_Transmit(&hspi2, &enable_write, 1, 100);		// 發送指令
	HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, GPIO_PIN_SET);	// 失能CS

	/* 寫數據 */
	HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, GPIO_PIN_RESET);	// 使能CS
	HAL_SPI_Transmit(&hspi2, &write_addr, 1, 100);			// 發送指令
	HAL_SPI_Transmit(&hspi2, m_addr, 3, 100);				// 地址
	HAL_SPI_Transmit(&hspi2, temp_wdata, 5, 100);			// 寫入數據
	HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, GPIO_PIN_SET);	// 失能CS
}

/* 讀取數據 */
void WriteData(void)
{
	uint8_t temp_rdata[5] = {0,0,0,0,0};					// 讀出數據保存的buff
	
	
	/* 檢查是否繁忙 */
	CheckBusy();	
	
	/* 開始讀數據 */
	HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, GPIO_PIN_RESET);	// 使能CS
	HAL_SPI_Transmit(&hspi2, &read_addr, 1, 100);			// 讀發送指令
	HAL_SPI_Transmit(&hspi2, m_addr, 3, 100);				// 地址
	HAL_SPI_Receive(&hspi2, temp_rdata, 5, 100);			// 拿到數據
	HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, GPIO_PIN_SET);	// 失能CS
	
	/* 測試打印 */
	printf("Read flash data is:%x %x %x %x %x\n",temp_rdata[0],temp_rdata[1],temp_rdata[2],temp_rdata[3],temp_rdata[4]);
}
  • main函數
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */
  

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_SPI2_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  ReadID();
  WriteData();
  ReadData();
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

運行結果

  • 燒錄進去,用串口調試助手
  • 發現輸出的就是我們存進的數據,說明測試成功

源碼

STM32F103ze_SPI_W25Q64.rar

小結

SPI在實際應用過程非常廣泛,而且速度也是比較快的,也是嵌入式需瞭解的協議之一,所以一定要好好理解!

備註:提供一下個人微信號 Hleafleafleaf,歡迎加好友,共同學習!共同進步!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章