1. 程式人生 > >STM32cubeMX將STM32F767+LAN8720+LwIP+FreeRTOS的乙太網實現

STM32cubeMX將STM32F767+LAN8720+LwIP+FreeRTOS的乙太網實現

通過STM32cubeMX將STM32F767+LAN8720+LwIP+FreeRTOS的乙太網實現

本文使用了正點原子的阿波羅開發板,接下來我將粗略的對STM32F767通過STM32cubeMX進行乙太網協議配置。

具體步驟


1.首先使能ETH,模式選擇RMII;
在這裡插入圖片描述
2.使能LWIP和FREERTOS;
在這裡插入圖片描述
因為阿波羅的開發板PHY晶片的ETH_DXT1和ETH_DXT0用的是PG13,PG14引腳,和預設的不同,所以這裡改一下
在這裡插入圖片描述
3.配置時鐘,在這裡我放上我自己的時鐘配置圖,只要不標紅就行,我用的是25MHz外部晶振作時鐘源 ;
在這裡插入圖片描述
在這裡插入圖片描述
4.配置ETH,由於阿波羅開發板的LAN8720晶片的PHYAD0引腳懸空,故PHY Address設定為0;
在這裡插入圖片描述


5.由於我用的STM32cubeMX的版本是將LAN8742A作為預設晶片,所以我們這裡不做修改,只用將內部引數改為LAN8720引數即可;
在這裡插入圖片描述
6.配置LWIP,本人這裡不使用DHCP獲取IP地址等資訊,並且我使用的是TCP,所以未對UDP使能,設定如圖;
在這裡插入圖片描述
7.配置FREERTOS,我在這裡加了兩個執行緒備用

在這裡插入圖片描述
8.按下生成按鈕,生成專案,生成時需要選擇編譯軟體為自己用的軟體,本人使用的是V5;

由於阿波羅開發板的PHY晶片的RESET引腳是依靠PCF8574的P7位控制,所以我們要在專案中引入PCF8574的程式碼,以下程式碼可以在阿波羅資料盤中找到
在這裡插入圖片描述

開啟main.c裡的加上#include “pcf8574.h”,並在初始化部分將PCF8574初始化

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f7xx_hal.h"
#include "cmsis_os.h"
#include "lwip.h"
#include "gpio.h"

/* USER CODE BEGIN Includes */
#include "pcf8574.h"
/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); void MX_FREERTOS_Init(void); /* USER CODE BEGIN PFP */ /* Private function prototypes -----------------------------------------------*/ /* USER CODE END PFP */ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * * @retval None */ 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 */ PCF8574_Init(); /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Call init function for freertos objects (in freertos.c) */ MX_FREERTOS_Init(); /* Start scheduler */ osKernelStart(); /* We should never get here as control is now taken by the scheduler */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ }

開啟freertos.c裡的加上
#include “gpio.h”
#include “sys.h”
#include “pcf8574.h”
#include “tcp_echoserver.h”,並在主執行緒將PCF8574初的P7管腳使能
PCF8574_WriteBit(ETH_RESET_IO,0);程式碼如下

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */     
#include "gpio.h"
#include "sys.h"
#include "pcf8574.h"
#include "tcp_echoserver.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */

/* USER CODE END Variables */
osThreadId defaultTaskHandle;
osThreadId myTaskLEDHandle;
osThreadId myTaskTCPHandle;

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
 extern void tcp_echoserver_init(void);
/* USER CODE END FunctionPrototypes */

void StartDefaultTask(void const * argument);
void LEDTask(void const * argument);
void TCPTask(void const * argument);

extern void MX_LWIP_Init(void);
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

/**
  * @brief  FreeRTOS initialization
  * @param  None
  * @retval None
  */
void MX_FREERTOS_Init(void) {
  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* USER CODE BEGIN RTOS_MUTEX */
  /* add mutexes, ... */
  /* USER CODE END RTOS_MUTEX */

  /* USER CODE BEGIN RTOS_SEMAPHORES */
  /* add semaphores, ... */
  /* USER CODE END RTOS_SEMAPHORES */

  /* USER CODE BEGIN RTOS_TIMERS */
  /* start timers, add new ones, ... */
  /* USER CODE END RTOS_TIMERS */

  /* Create the thread(s) */
  /* definition and creation of defaultTask */
  osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
  defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);

  /* definition and creation of myTaskLED */
  osThreadDef(myTaskLED, LEDTask, osPriorityIdle, 0, 128);
  myTaskLEDHandle = osThreadCreate(osThread(myTaskLED), NULL);

  /* definition and creation of myTaskTCP */
  osThreadDef(myTaskTCP, TCPTask, osPriorityIdle, 0, 1024);
  myTaskTCPHandle = osThreadCreate(osThread(myTaskTCP), NULL);

  /* USER CODE BEGIN RTOS_THREADS */
  /* add threads, ... */
  /* USER CODE END RTOS_THREADS */

  /* USER CODE BEGIN RTOS_QUEUES */
  /* add queues, ... */
  /* USER CODE END RTOS_QUEUES */
}

/* USER CODE BEGIN Header_StartDefaultTask */
/**
  * @brief  Function implementing the defaultTask thread.
  * @param  argument: Not used 
  * @retval None
  */
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void const * argument)
{
  /* init code for LWIP */
  MX_LWIP_Init();
  /* USER CODE BEGIN StartDefaultTask */
	PCF8574_WriteBit(ETH_RESET_IO,0);       //Æô¶¯PHYоƬ
 
	Tcp_Server_Init();
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END StartDefaultTask */
}

/* USER CODE BEGIN Header_LEDTask */
/**
* @brief Function implementing the myTaskLED thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_LEDTask */
void LEDTask(void const * argument)
{
  /* USER CODE BEGIN LEDTask */
  /* Infinite loop */
  for(;;)
  {

     osDelay(1); 

  }
  /* USER CODE END LEDTask */
}

/* USER CODE BEGIN Header_TCPTask */
/**
* @brief Function implementing the myTaskTCP thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_TCPTask */
void TCPTask(void const * argument)
{
	
  /* USER CODE BEGIN TCPTask */
  /* Infinite loop */
  for(;;)
  {
	osDelay(1); 
  }
  /* USER CODE END TCPTask */
}

接下來我們的開發板連上電腦,保證電腦IP地址和開發板IP地址在同一網段後按Windows+R後輸入cmd回車開啟CMD,在介面輸入ping xxx.xxx.xxx.xxx(xxx代表開發板IP地址),可以得到
在這裡插入圖片描述
這樣開發板就ping通了,這個時候就可以引入伺服器或是客戶端的程式碼,實現對應功能。