STM32CUBEMX配置STM32F429的LWIP+RTOS+IIC实现在局域网内ping通学习记录

注 :未经允许请勿转载,请尊重劳动成果,大家都是知识分子!谢谢!

  一开始是用原子的STM32F103的战舰开发版,不过在CUBE配置的时候LWIP的配置死活找不到,只有移植原子的例程这一条路,果断换个板子。

硬件:STM32F429IGTx;

软件:STM32CUBEMX,KEIL5

 首先先配置LWIP,ETH,RTOS,IIC以及RCC,之所以配置IIC,是因为F429的开发版的芯片结构的问题,是由MCU的IIC总线发出 电平信号给PCF8574这个IO拓展芯片,然后再使能LAN8720。

先看ETH的配置:

STM32CUBEMX配置STM32F429的LWIP+RTOS+IIC实现在局域网内ping通学习记录_第1张图片

注:之前在网上找到的都是关于这个PHY地址的解答,都是要置0,但是其实是有问题的,我的PHY芯片是LAN8270T,在原子的阿波罗开发板上,这个地址是需要置1的。

在设置完PHY芯片之后,就是参数的设置

STM32CUBEMX配置STM32F429的LWIP+RTOS+IIC实现在局域网内ping通学习记录_第2张图片

由于CUBE默认生成的是LAN8722A,但是实际上是8720,所以在这里改过来,至于下面的参数,就需要参考相关手册啦,是不是这样子呢?可以试一下喔。

在这里是选择RMII,选这个的原因参考开发版电路原理图,然后后面的PHY Address这里是浮空的,所以设0。

RTOS我在任务列表里面加了2个任务备用,其他就是常规操作啦,这里就跳过啦

然后是IIC的配置,这里选择的是I2C2,因为这个是GPIOH的PH4和PH5是两根数据线和时钟线

STM32CUBEMX配置STM32F429的LWIP+RTOS+IIC实现在局域网内ping通学习记录_第3张图片

STM32CUBEMX配置STM32F429的LWIP+RTOS+IIC实现在局域网内ping通学习记录_第4张图片

 

由于是需要使能ETH_RESET引脚,所以需要另外选择IIC_INT引脚,在CUBE里面,PB12这个引脚没有办法直接选择IIC,而是选择IIC_SMBA,这个总线可以说是IIC的子集,具有相同的使用方法

STM32CUBEMX配置STM32F429的LWIP+RTOS+IIC实现在局域网内ping通学习记录_第5张图片

STM32CUBEMX配置STM32F429的LWIP+RTOS+IIC实现在局域网内ping通学习记录_第6张图片

STM32CUBEMX配置STM32F429的LWIP+RTOS+IIC实现在局域网内ping通学习记录_第7张图片

(因为之前从原子的例程里面直接移植过IIC的函数,但是并不能用,可能是底层的时钟不一致,以后有机会再研究了)

然后就是配置LWIP,这个相对来说是比较复杂的,不过并不难

STM32CUBEMX配置STM32F429的LWIP+RTOS+IIC实现在局域网内ping通学习记录_第8张图片

在这里由于是在校园网,所以ping的不是路由器,所以是设置的学校局域网的IP地址,所以没有只能DHCP,然后我这里是使用TCP,所以就把UDP给DISABLE,使能TCP。

RCC部分我就是直接选择常规操作了,前面的博客也有介绍到,不懂的请移步百度

STM32CUBEMX配置STM32F429的LWIP+RTOS+IIC实现在局域网内ping通学习记录_第9张图片

接下来就是时钟树的配置,只要不显示红紫色,即时钟频率在允许的范围内就OK啦

STM32CUBEMX配置STM32F429的LWIP+RTOS+IIC实现在局域网内ping通学习记录_第10张图片

然后就是生成相应的工程啦。

在生成工程后,在主函数里面添加PCF8574.h头文件

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "pcf8574.h"
//#include "ethernetif.h"
/* USER CODE END Includes */
然后再主函数里面加入8574的初始化函数

 /* USER CODE BEGIN 2 */
 PCF8574_Init();
  /* USER CODE END 2 */
接下来就是在RTOS里面,在include 里面加入gpio.h和pcf8574.h两个头文件

/* USER CODE END Header */

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

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */     
#include "gpio.h"

#include "pcf8574.h"
//#include "tcp_echoserver.h"

/* USER CODE END Includes */
然后其他的直接看程序啦

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
ETH_HandleTypeDef heth1;
/* 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 myTaskTCPHandle;
osThreadId myTaskLEDHandle;

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

/* USER CODE END FunctionPrototypes */

void StartDefaultTask(void const * argument);
void TCPTask02(void const * argument);
void LEDTask03(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 */

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

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

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

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

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

}

/* 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_ReadBit(ETH_RESET_IO);
    PCF8574_WriteBit(ETH_RESET_IO,1); 
    HAL_Delay(100);
    PCF8574_WriteBit(ETH_RESET_IO,0); 
    HAL_Delay(100);
    
    
    /**
 * In this function, the hardware should be initialized.
 * Called from ethernetif_init().
 *
 * @param netif the already initialized lwip network interface structure
 *        for this ethernetif
 */
    uint8_t MACAddr[6] ;
  heth1.Instance = ETH;
  heth1.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
  heth1.Init.PhyAddress = LAN8720_PHY_ADDRESS;
//    MACAddr[0] = 0x00;
//  MACAddr[1] = 0x80;
//  MACAddr[2] = 0xE1;
//  MACAddr[3] = 0x00;
//  MACAddr[4] = 0x00;
//  MACAddr[5] = 0x00;
  MACAddr[0] = 0x02;
  MACAddr[1] = 0x00;
  MACAddr[2] = 0x00;
  MACAddr[3] = 0x55;
  MACAddr[4] = 0x00;
  MACAddr[5] = 0x48;
  heth1.Init.MACAddr = &MACAddr[0];
  heth1.Init.RxMode = ETH_RXINTERRUPT_MODE;
  heth1.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
  heth1.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
    
    //Tcp_Server_Init();
  /* Infinite loop */
  for(;;)
  {
    //    MX_LWIP_Process();
    osDelay(1);
  }
  /* USER CODE END StartDefaultTask */
}
在RTOS里面搞定程序之后,这里还有一个,由于我在cube里面已经使能了PB12这个引脚,那么我在PCF8574的初始化函数里面把PB12引脚的配置给注释掉,让这个工作在GPIO里面做。

STM32CUBEMX配置STM32F429的LWIP+RTOS+IIC实现在局域网内ping通学习记录_第11张图片

由于我在HAL库里面没有找到us的延时,所以在这里就直接引用了delay.c的延时程序(应该是我懒,懒得找了(╥╯^╰╥))

然后在这里有要说一下的就是,CUBE生成的I2C的文件里面,只有一个初始化函数,其他什么都没有,都是需要自己写的。所以主要的工作量就在这里了其实。然后程序编译,

STM32CUBEMX配置STM32F429的LWIP+RTOS+IIC实现在局域网内ping通学习记录_第12张图片编译通过,然后通过STLINK下载到班子里,然后ping一下

STM32CUBEMX配置STM32F429的LWIP+RTOS+IIC实现在局域网内ping通学习记录_第13张图片

到这里就搞定啦。

总结:前段时间像无头苍蝇一下乱搞,主要是思路没有理清楚,只要理清楚MCU、PCF8574和LAN8720之间的连接方式,以及芯片的使用方法,就会相对来说顺畅一点,感觉自己有进步了一点,有点开心,今晚回去打个王者吧。

                                                                                                                                                  (文章出自:build_oooxf)

 

你可能感兴趣的:(初学)