前段时间做项目用到百兆网通信,用到了lwip,一开始是参照原子的例程做移植,因为原子的例程中使用的是lan8720,为了改成dp83848,改寄存器地址,改位定义,改速度计算公式,折腾了好多天也没成功,最后只好听从网友的建议,修改st官方的一个例程,几天下来,竟然成功了,现在将步骤分享给大家,感觉实际工程中用dp83848的还是大多数。.其实本文并不是移植lwip,只是将st官方的例程改成我们项目所需要的,然后我们再在这个基础上完成自己的项目即可,这对新接触lwip又急着做项目的人比较适合,没必要去了解lwip的具体实现,会用就行了。.
本人的项目配置:stm32f407vet6 + dp83848c
1、从官方网站http://www.stmcu.org/document/list/index/category-523下载stsw-stm32070 面向stm32f4x7微控制器的lwip tcp/ip协议栈的演示代码 的英文文档dm00036052.pdf和软件包stsw-stm32070.zip。stsw-stm32070.zip是面向stm32f4x7微控制器的lwip tcp/ip协议栈的基于官方eval开发板的演示代码,显然,我们直接修改这个演示代码要比我们去移植lwip简单得多。dm00036052.pdf是演示代码的说明文档。
2、将stsw-stm32070.zip解压得到stm32f4x7_eth_lwip_v1.1.0文件夹,下面是stm32f4x7_eth_lwip_v1.1.0文件夹架构
3、删除_htmresc文件夹,这个文件夹是st及cmsis公司logo,没什么用。
4、打开project文件夹,这个文件夹包括两个文件夹:freertos和standalone。
freertos文件夹里的程序示例是基于freertos系统的lwip移植示例,这里我们不需要,直接删除。
standalone文件夹里是一些无操作系统lwip移植示例程序,在这里我们工程需要的是普通的数据传输,所以只使用到udp,所以我们只保留udp_echo_client文件夹,其他的都删除掉。在udp_echo_client文件夹中ewarm文件夹是iar ewarm建立的工程,mdk-arm是keil mdk建立的工程。在这里我们选择mdk工程,iar建立的工程可以保留也可以删除。还有一个文件夹ride,打开看了看,应该是用另一款编译软件建立的工程空间,这里我们不需要,直接删除。
5、utilities-》third_party文件夹下面有三个文件夹fatfs_vr0、freertosv7.3 、lwip-1.4.1。fatfs_vr0一个通用的文件系统模块,用于在小型嵌入式系统中实现fat文件系统,freertosv7.3一个迷你操作系统内核的小型嵌入式系统,在这里我们都用不上,直接删除。lwip-1.4.1文件夹是lwip源码,是我们所需要的。
6、打开mdk-arm文件夹里面的mdk工程,我们先编译一下,可以看到有0个错误,三个警告,其中两个警告是定义了变量但是没有使用,我们不去管它,另一个警告是。.\。.\。.\。.\utilities\third_party\lwip-1.4.1\port\stm32f4x7\standalone
\ethernetif.c(366): warning: #1-d: last line of file ends without a newline 提示ethernetif.c文件的最后一行(也就是366行)没有换行,mdk里面每个文件的最后一行必须换行,不然会提示一个警告,这里把366行后面换行再编译,这个警告就消失了。
7、打开 main.h 文件,因为我们电路板上使用的是rmii接口,所以将#define mii_mod注释掉,将//#define rmii_mode取消注释,如下图所示:
在这里要注意rmii的时钟为50mhz,在电路板上直接焊接一个50mhz的有源晶振就可以了。
取消//#define use_dhcp的注释,启用动态地址分配,当地址分配不成功则使用静态ip地址。如图:
本项目中直接删除掉,因为删除掉了serial_debug,所以我们可以将serial_debug.c文件从项目中移除。
点击红色的叉号删除serial_debug.c,然后点击ok就可以了。
将groups栏stm324xg_eval中的stm324x7i_eval.c和stm324x7i_eval_lcd.c删除,将mdk_arm中的启动文件startup_stm32f427x.s删除,将project targets分栏中的项目名stm324x7i_eval删除,将stm324xg_eval中的stm324xg_eval_lcd.c删除,这都是和本项目无关的东西。这时候编译会提示错误,我们将stm32f4x7_eth_bsp.h文件里关于包含lcd函数的头文件删除,如下图。
将stm32f4x7_eth_bsp.c文件里面关于lcd的部分删除掉,如下图,将这些行删除。
将netconf.c中141-148行关于lcd的函数删掉
/* set the lcd text color */
lcd_settextcolor(red);
/* display message on the lcd */
lcd_displaystringline(line5, (uint8_t*)“ network cable is ”);
lcd_displaystringline(line6, (uint8_t*)“ not connected ”);
/* set the lcd text color */
lcd_settextcolor(white);
再编译就没有问题了。
8、按电路图修改时钟,修改 stm32f4xx.h中宏定义标识符hse_value 的值为我们的外部时钟20mhz
设置主 pll 时钟, 在 system_stm32f4xx.c 文件开头的地方配置
所以我们的主 pll 时钟为:
pll = 20mhz * n/ (m*p) = 20mhz* 336 /(20*2) = 168mhz
systeminit()函数中设置的系统时钟大小:
sysclk(系统时钟) = 168mhz
ahb 总线时钟 (hclk=sysclk) = 168mhz
apb1 总线时钟 (pclk1=sysclk/4) = 42mhz
apb2 总线时钟 (pclk2=sysclk/2) = 84mhz
pll 主时钟 = 168mhz
9、这个例程默认的是stm324xg_eval开发板,它使用的主芯片是stm32f407ig,而我们项目所使用的主芯片是stm32f407ve,要更改芯片配置。
选择 device 将下面的主芯片改为
10、下面我们进入main.c函数看一下程序:
首先的注释是说明系统时钟已经配置完成,如果修改的话可以参考第8条。接下来就是配置中断优先级分组nvic_prioritygroupconfig,这个很重要,只要定义了中断,就必须配置中断优先级分组,这个函数在系统中只能被调用一次,一旦分组确定就最好不要更改。这里分配的是组4,4位抢占优先级, 0位响应优先级。
接下来的是条件编译和lcd初始化,在前面我们已经删除serial_debug 串口调试和lcd头文件,这里我们直接将这段程序删除。如下图,将这几行代码删除掉。
删除mian.c下面关于lcd的信息:
删除128行以后的所有数据。
打开stm324xg_eval.h,注释掉第39行#include “stm32_eval_legacy.h”,这个头文件是关于开发板上lcd及按键的声明,本项目中没有用到lcd和按键。
打开stm32f4x7_eth_bsp.c文件,删除关于lcd的一些程序,删除447行至472行的程序和485行到495行的程序,这里的程序是在lcd屏上显示一些语句及本机的ip。删除如下图所示程序。
打开netconf.c文件,删除关于lcd的程序,删除第219至223行程序,删除239至255行程序,删除274至290行程序。这是关于lcd显示分配动态ip的信息的程序。
11、下面是stm32f4x7_eth_bsp.c ; 配置以太网 (gpios, clocks, mac, dma),对于gpio的配置,我们选用的是rmii接口,而且芯片是stm32f407ve,和stm324xg_eval开发板上有些引脚定义有些差别,所以我们要对网口的gpio接口修改:
修改结果如上图所示 , 注意以太网配置那段注释里面,双斜线的是我们rmii没有用到的引脚,还有就是要将pg11/pg13/pg14修改为pb11/pb12/pb13。
12、接下来就是修改关于led和按键的程序了,删除netconf.c里面第179行、第234行和252行,有些行数可能不对,但代码不会变,找到相应代码并修改
将stm324xg_eval.c文件除了#include “stm324xg_eval.h”其他全部删除,如图所示
将stm324xg_eval.h文件除了下图所示程序其他全部删除:
我们项目电路板上所用到的功能就可以在这两个文件夹定义和声明了。
13、在官方udp客户端这个例程中是利用按键中断来发送数据包的,本人开发的项目是当收到下位机的数据后就将数据转发给pc,所以在这里用不到按键中断。之前我们删除了lcd_led_button_init();这个函数,这个函数就是配置led、lcd以及按键初始化及按键中断的函数。所以在这里这个按键中断已经没有作用了,我们可以将udp客户端发送数据包的函数直接复制到主函数中,然后将按键中断函数清空。按键中断函数在stm32f4xx_it.c函数中,如下图,将udp_echoclient_connect();复制到主函数中以便使用,等我们改写主函数时会用到这个函数。这个函数是基于eval开发板写的一个数据收发函数,我们自己实现收发功能都可以参照这个函数来写 , 复制完之后直接将这个中断函数内容清空就可以了。在main.c中还要添加udp_echoclient_connect()函数所在文件对应的头文件#include “udp_echoclient.h”。
13、至此,编译下载,修改电脑ip,连接我们的板子,因为是板子和电脑直接连接而不使用路由器,所以dhcp不会成功,会使用我们分配的静态ip,在main.h里面。这时候应该就可以ping通了,说明lwip已经运行在我们的板子上了,之后我们就可以参照udp_echoclient_connect()实现我们想要的功能,具体的大家就可以自己去分析了……
关于lwip的接口函数使用,大家可以参考周立功的《《lwip接口与编程指南》》,对一般应用足够了,在百度文库上有免费下载
全加器
中国电信“T比特级超长跨距光传输系统关键技术研究与应用示范”项目
传感器的发展通史
PT-7000系列交流钳形电流探头的使用
国巨|推出1206 NPO 630V 10nF电容
STM32F407-DP83848-Lwip移植方法
车载中控屏核心板开机不良的详细分析
共享溜娃小车现身!共享溜娃小车现身:两元半小时,押金99元比售价还贵你怎么看?
硬件工程师教你如何理解地的概念
电动汽车系统中通过隔离降低EMI的三种方案
5G正成为行业应用的关键基础设施
永磁电机内的电磁力及其谐波
同样是1799元,乐Pro3双摄AI版和魅族mx6,你喜欢谁?
lm358电压上限和下限比较 LM358和LM358P区别是什么
华硕带鱼屏显示器MX38VC 4K分辨率底座支持无线充电
Opensignal公布韩国三个主要城市的5G速率
注液工艺五大痛点及应对策略
Seegrid推出Palion 8系列无人自主堆垛车
安卓系统USB产品芯片使用推荐
如何存放电池?