文章目录
- 移植到正点原子例程
- 下载ST最新F4平台例程适配
- 使用CubeMX从头开始
- 移植标准库上层函数到CubeMX初始化的HAL库
项目要从之前的STM32F107平台移植到STM32F407平台,我的任务主要是底层的移植,让程序在新的平台可以正常运行,主要包含的功能有IIC EEPROM LED ETH LWIP UART这几个的初始化和实现。
重点呢就是其中的网口芯片,是比较常用的DP83848芯片,之前我一直使用正点原子的探索者开发板,使用的芯片是LAN8720,对于新的网口芯片不太熟悉,其复杂的配置操作我也看不明白,只能借助于各大论坛和网站搜索。其实相关的回答还是很多的,但还是那个问题,就是非常的杂乱,还需要很多次的尝试。
移植到正点原子例程
原程序是ST官方例程修改得来的,使用的应该是标准库。所以我一开始计划是把原程序中的网络配置的底层文件移植到正点原子中替换,然后修改IO口的配置,修改PHY_address变成 0x01
就是这个网络驱动的库,替换掉正点原子对应的库,然后修改相关的配置。
但是直接复制过来之后因为是f1的库到f4的环境,所以错误非常的多,我当时就傻眼了,胡乱修改了之后也只能放弃
这个方法虽然没有成功,但是搜索资料得知可以去网络下载ST关于F4平台的DP83848例程
下载ST最新F4平台例程适配
啥也不多说了,下载这个例程就可以了
https://www.stmcu.org.cn/document/detail/index/id-213647
本以为这个例程有了,也是基于F4的,移植总该没有这么多的错误了吧,当我移植到正点原子的例程中的过程,还是出现了非常非常多的问题,应该是没有经验,我并不知道从那开始,修改了半天的错误之后也只能放弃
现在已经探索了一天多了,依然没有头绪,而时间只有一星期左右,这时候我想到了把原来的代码一步一步的直接移植到刚刚下载的DP83848的例程中,反正就网口部分最复杂,我不动这个部分就好了。
说弄就弄,这非常的幸运,找到了以为大佬写的文章,根据这个文章,开始一步一步的修改下载好的ST例程,因为ST例程照顾了很多的模式,所以有很多需要修改模式还有注释掉一些功能。
详细的内容参照这篇文章,步骤非常的详细,讲解的也非常好
STM32F407_DP83848_Lwip移植方法要点
但是我不知道是不是我哪里出了问题,依然无法调试通,始终没有办法ping通,不过既然说到这个地方了,那我就多说两句这个说明文档忽略掉的一个IP地址配置的部分吧。
IP地址的配置在main.h的位置,MAC地址就不用多说了,IP_ADDR是板子的本地IP地址,NETMASK是子网掩码,GW_ADDR是我们的网关地址,这个是UDP的
使用CubeMX从头开始
折腾了三天,结果还是没有进展,这时候不管是ST官方例程还是正点原子的例程已经被我修改的面目全非,因为我对这块基础知识掌握的严重不足,所以也没办法去从理论分析。
这时候一个拯救我跳出水坑的软件出现了那就是Cube MX,抱着死马当活马医的心态,我开始安装配置
安装配置过程见这篇文章
CubeMX安装教程及安装过程问题处理(cube打不开/cube无法生成文件/jre环境配置有问题)
安装好之后
STM32CubeMX ETH DP83848 + LWIP 完美ping通以及收发数据
没想到这个软件通过配置DP83848的模式之后,就可以自己完成配置,虽然中间过程也遇到了很多坑,这个软件真的是简单上手,但是使用过程中理解不通透就会出现很多看不见的错误。
最开始我是简单配置了ETH+LWIP+MCO2,初始化了网口的功能,因为当时抱着试试看的心态,找到的那篇文章也是个半瓶水的水平,过程没有写完整。所以我就不知道主程序中还要去写==MX_LWIP_Process();==这个函数,所以当时我依然无法ping通。因为不熟悉这个软件,也不相信这个软件可以直接就这样调通,所以我看到不行,也就以为不行了,没有去再继续百度查找资料
这种情况下当时只能去求助老师寻找解决办法,老师帮助我找到的一篇文章中,我突然看到了==MX_LWIP_Process();==这个函数,恍然大悟,原来是我当时少了操作,所以立马去试了试,结果就成功的ping通了,当时非常的高兴。
不过也多亏我昨天使用CubeMX软件尝试了一下,看到那篇文章刚好也是针对CubeMX生成的程序调试,当时瞬间全部联结了起来。所以多个方案多个准备,就算是当时感觉没有用,失败了,但谁知道不会孕育着成功呢?
接下来就是快乐的移植后面的内容,本以为会非常简单了,因为之前那个ST官方例程的方案我虽然没有移植成功网口驱动,但其他的所有上层函数我全部移植正确。
移植标准库上层函数到CubeMX初始化的HAL库
CubeMX生成代码之后,我找到了一些测试的代码,测试了一下,验证了UART ETH IIC的功能正常,但是上层封装的函数还没有移植。
其实一开始是非常的头疼的,因为看到要移植过来的上层代码文件有 EEPROM LED Global COMM UDP_SERVER,主要是这几个,一开始比较头铁,全都移植了过来,结果可想而知,简直就是灾难,根本没有办法调试。
然后睡了一觉醒来之后,发现不能这样弄,要一步一步的来,虽然底层库有变化,但是万变不离其宗,一定是可以的。
首先从EEPROM开始,移植过来之后,才意识到,我得先移植IIC的服务函数才可以。这里我还借助了一下正点原子的HAL库例程来参考,也就是参考着F103的原代码和正点原子例程来移植到F407平台。
那就移植IIC,这里有个问题,非常重要,我在这里栽了一下,就是u8 u16 u32的问题,因为标准库比较老,所以定义是u8 u16 u32这种,我天真的以为是HAL库中没有定义,我补上就可以了,然后添加了这段到了main.h中,以为自己特别机智
typedef uint32_t u32; ///32位
typedef uint16_t u16; ///16位
typedef uint8_t u8; ///8位
灾难就是这里开始崩塌的,可以说是雪崩的节奏,因为定义发生了冲突,新旧的定义导致很多地方直接就疯狂报错,当时直接700多个错误。发现了之后,为了杜绝一切问题,我删掉了这个后来加上的,然后把老代码中的全部u8 u16 u32一律替换成了uint8_t uint16_t uint32_t ,在头文件中也把
#include “stm32f4xx.h”
修改成了
#include “stm32f4xx_hal.h”
保证了一致性,这样的话,就问题大幅度的减少,剩下的就是比对函数了,把一些底层函数对应上,替换成hal库的。
一定要记得头文件的定义,因为后面调用都是头文件来查找要用的函数,如果不写上,就会有警告甚至错误。
这样就算是把IIC的函数移植过来了,还能保持跟远平台的函数接口一致。
接下来就是EEPROM了,这个就比较简单了,因为IIC的都有了。主要还是u8 u16 u32问题。
出现了新问题的是移植网络服务函数,因为之前只是ping通,并没有上层函数来进行方便的收发还有内容的检测。
这里要仔细对比和之前的程序中网络服务函数的功能,尽量不要重复,把需要的写进去,然后能用官方最新函数定义的要替换成新的,更少的出现问题。
网络这块新老的冲突有一个就是ip_addr,这里如果报错的话可以去看看ip4_addr,原则上不要把老的定义带过来,也不要添加定义,就用新的对应的替换掉。
对于UART,这里有个更有启发意义的移植
这个函数hal库是没有的
通过搜索关键词flag,逐一排查,找到了类似的定义,这样的话就可以替换过来,同样用这种方法我也找到了
USART_FLAG_TXE 要替换成 UART_FLAG_TXE
不过也有另一种方式,直接把USART_GetFlagStatus函数直接在原代码中复制过来,毕竟也是服务函数。
这样处理也可以让程序正常运行,没有错误。
好了,这样就算是都大功告成了,剩下的就是修修补补的警告,消除一下,把一些定义规范一下,把缺少的类似于
#include “string.h”
都定义上,还有调用到的.h 头文件都配置好就行了。
大功告成,接下来弄旋转编码器。