手把手教你用STM32cube调通STM32H743以太网通信并实现TCP客户端

您所在的位置:网站首页 以太网未启用dhcp什么情况可以用 手把手教你用STM32cube调通STM32H743以太网通信并实现TCP客户端

手把手教你用STM32cube调通STM32H743以太网通信并实现TCP客户端

2024-07-16 17:58| 来源: 网络整理| 查看: 265

STM32H7内核是Cortex-M7,目前接触到与M4最大的区别就是CACHE,M7有两个CACHE,DCACHE和ICACHE。因为这个CACHE踩了很多坑。

本例程软硬件配置为:FreeRTOS+LwIP+LAN8720,在正点原子阿波罗开发板上测试

1. Cube配置

RCC都使用外部晶振,因为后面要用到FreeRTOS,cube会建议使用TIM1作为SYS时钟源

系统

不考虑功耗时钟频率直接拉到最高480MHz

ETH模块使能,配置为RMII模式,MAC地址随便填一个,这里能看到一个warning,说ETH模块只能运行在0x24000000地址起始的RAM中,网上查了一下这个地址是AXI RAM,AXI是一种总线结构,这边先不用管,可以等进入工程后配置。然后就是确认ETH与物理层芯片相连的引脚是否正确,由于使用的是阿波罗开发板,原来默认的发送接口是B12、B13,需要改为G13、G14,最后使能ETH全局中断。这里会发现现在版本的Cube没有配置物理层芯片地址(PHY ADDR)的选项,不用担心,在程序中它会自己遍历0-31的物理地址,找到有应答的地址作为物理层芯片地址。除此之外,将ETH的GPIO口频率都设为最高。

启用FreeRTOS,可根据实际需求修改配置

启动LWIP发现是灰的,移到LWIP上会发现cortex-m7需要启用DCache才能使用LWIP

启用DCache后能正常启用LWIP

设置物理层芯片,这里只有LAN8742可以选,不过没关系,LAN8720也可以用,在通用设置里面可以选择启用哪些操作,这里使能了DNS

最后物理层芯片需要一个硬件复位信号引脚,由于阿波罗开发板中该引脚是由PCF8574芯片控制的,PCF8574芯片需要通过IIC控制,嫌麻烦就看了下正点原子给的原理图,直接把红框中的两个电阻焊掉,用跳线连接LAN8720的复位引脚和H743的GPIO引脚,这个GPIO口随便选,这里用了A5。配置输出电平为High

网络部分的配置就这些,其他模块根据自己需求配置,比如串口、定时器等。这里使能了一个串口作为调试用,波特率直接给到了921600Bit/s,引脚改为A9A10

最后一步设置项目名称等,编译器使用了IAR8.3(编译比keil快很多),设置完了就生成代码

2. 工程配置

main.c中重定向printf用于打印消息,另外提供一个MPU配置函数

/* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ #ifdef __GNUC__ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif PUTCHAR_PROTOTYPE { //HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1 , 0xffff); while ((USART1->ISR & 0X40) == 0); USART1->TDR = (uint8_t) ch; return ch; } /** * @brief Configure the MPU attributes * @param None * @retval None */ static void MPU_Config(void) { MPU_Region_InitTypeDef MPU_InitStruct; /* Disable the MPU */ HAL_MPU_Disable(); /* Configure the MPU attributes as Device not cacheable for ETH DMA descriptors */ MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = 0x30040000; MPU_InitStruct.Size = MPU_REGION_SIZE_256B; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER0; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.SubRegionDisable = 0x00; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /* Configure the MPU attributes as Cacheable write through for LwIP RAM heap which contains the Tx buffers */ MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = 0x30044000; MPU_InitStruct.Size = MPU_REGION_SIZE_16KB; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER1; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.SubRegionDisable = 0x00; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /* Enable the MPU */ HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); } /* USER CODE END 0 */

main()函数中调用MPU_config,并使能SRAM时钟

在ethernetif.c文件的low_level_init函数中添加物理层重启语句

在ethernetif.c文件的low_level_output函数中添加DCache语句

在ethernetif.c文件的low_level_input函数中添加DCache语句

在lwipopts.h文件末尾添加宏定义

#define LWIP_RAM_HEAP_POINTER    (0x30044000)

在中断文件stm32h7xx_it.c中先引入外部信号量,再在ETH中断中添加信号量释放函数

最后打开IAR的Project->Options->Linker->Config->Edit修改RAM起始地址

到这里就软件就配置完了,接下来是TCP客户端的实现

3. TCP客户端

创建TCP客户端的.c文件

加入代码

#include "lwip.h" #include "lwip/api.h" #include "stm32h7xx_hal.h" #include "cmsis_os.h" #include "socket.h" #include "dns.h" void DNS_found_cb(const char *name, const ip_addr_t *ipaddr, void *callback_arg) { uint32_t* ip = (uint32_t*)ipaddr; printf("DNS found: IP %d:%d:%d:%d\n",((*ip)&0xff),(((*ip)>>8)&0xff),(((*ip)>>16)&0xff),(((*ip)>>24)&0xff)); } void network_init(struct netconn *conn) { int sock = -1; conn = netconn_new(NETCONN_TCP); if (conn == NULL){ printf("Set new connection failed...\r\n"); return; } sock = lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(sock < 0){ printf("Get socket failed!... Try again...\r\n"); vTaskDelay(1000); } conn->socket = sock; } int network_connect(struct netconn *conn, char *hostname, int port) { int err; struct sockaddr_in sAddr; ip_addr_t addr; printf("Socket is:%d\r\n",conn->socket); err = dns_gethostbyname(hostname, &addr, DNS_found_cb, NULL); if(err != 0){ printf("DNS failed to get host by name : %d \n",err); return -1; } //addr.addr = htonl(addr.addr); sAddr.sin_addr.s_addr = *((in_addr_t*)(&addr)); sAddr.sin_family = AF_INET; sAddr.sin_port = htons(port); //netconn_bind(conn,IP_ADDR_ANY,port); err = lwip_connect(conn->socket, (struct sockaddr*)(&sAddr), sizeof(struct sockaddr)); if(err != 0){ printf("LwIP connect failed :%d \n", err); return -2; } return 0; } void tcp_client_task(void const * argument) { // struct netbuf *buf; // void *data; // u16_t len; err_t err; struct netconn conn; LWIP_UNUSED_ARG(argument); char ip4[] = "192.168.0.100"; uint16_t port = 30001; printf("Connecting to server: %s :%d ...\r\n",ip4,port); network_init(&conn); CONNECT: err = network_connect(&conn, ip4, port); if (err != ERR_OK){ printf("Connect to server failed:%d \tReconnecting...\r\n",err); vTaskDelay(3000); goto CONNECT; } printf("Connect to server successed!\r\n"); while(1) { vTaskDelay(2000); } }

其中IP地址与端口需要根据自己服务器设置

在main.c文件中添加TCP任务函数

extern void tcp_client_task(void const * argument);

定义全局变量的TCP任务句柄

osThreadId TCPTaskHandle;

在StartDefaultTask中添加TCP任务

osThreadDef(TCPClient, tcp_client_task, osPriorityNormal, 0, 2048); TCPTaskHandle = osThreadCreate(osThread(TCPClient), NULL);

如果需要debug可以打开lwip的debug功能,在debug.h中一下位置添加debug的宏定义

然后在opt.h文件中打开对应的Debug开关,如打开DHCP_DEBUG等等

大功告成,接下来就是烧录,并运行程序。观察串口打印的debug内容,可以看到lwip通过DHCP获得到了IP地址、网关及子网掩码

进入路由器配置页面,可以看到路由器中多了一个Uknown设备,地址为192.168.0.103

服务器端显示,有一个192.168.0.103的TCP客户端连接

ping也可以直接ping通

 

4. 工程文件

STM32H743以太网通信TCP客户端实现

5. Reference

http://www.stmcu.org.cn/module/forum/thread-615089-1-3.html



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3