这段时间研究了使用Mbed开发SensorTile,结果一开始的闪灯程序就遇到问题,程序没有变化。经过一段时间的研究,终于发现并解决了问题。我把解决问题的大致步骤写出来,给大家参考一下。
SensorTile使用了STM32L476JG,它不在Mbed直接支持的芯片中(Mbed支持STM32L476VG和STM32L476RG,没有直接支持STM32L476JG)。
因为STM32L476JG和STM32L476VG/STM32L476RG差别很小,除了封装不同,在就是GPIO有少量不同,STM32L476JG多出了PORTG。按照以前的经验,STM32L476VG/STM32L476RG的程序应该是可以直接运行在STM32L476JG上。于是用NUCLEO_L476RG模板,写了一个LED的闪灯程序,结果编译出错,提示PG_12没有定义。
- #include "mbed.h"
- DigitalOut LED(PG_12);
- int main()
- {
- while(1)
- {
- LED = 0;
- wait(0.1);
- LED = 1;
- wait(0.1);
- }
- }
复制代码
检查了源码,发现PinNames.h和PortNames.h中没有PORTG的定义。于是手工添加了PORTG的定义到PinNames.h和PortNames.h中,这次可以编译通过了。但是程序下载后没有任何反应,于是就想把程序导出来进行仿真。程序导出很方便,但是发现NUCLEO_L476RG导出的程序不完整,在online IDE中编译很正常,在KEIL中提示缺少objects.h,从github的mbed源码中找到这个文件并加入,还是不行,缺少更多的文件,经过多次尝试都是这样,看来是NUCLEO_L476RG的程序库有问题。后来发现使用STM32L476_DISCO模板建立的程序,导出后是完整的,可以在Keil中仿真,这次发现PORTG相关的寄存器被被设置,所以LED不亮。
进一步仿真就需要查看程序源码了,而STM32L476_DISCO模块提供了很多文件是obj格式的,带来不便。先是在online IDE中将mbed库删除,导入mbed-dev,结果这样就无法导出程序了,这好像是online IDE有限制。最后回到开始的STM32L476_DISCO模板程序,将obj文件删除,然后从mbed源码中找到对应文件的C/CPP文件,并加入到项目文件。因为这段时间出了一些意外,时间有些少,所以花费N天才完成这一工作,终于可以深入源码查找问题了。
最后发现,在pinmap.c中,函数uint32_t Set_GPIO_Clock(uint32_t port_idx)中缺少了PORTG的代码,于是仿照上下相关部分代码,添加了PORTG的部分。
- #if defined(GPIOG_BASE)
- case PortG:
- gpio_add = GPIOG_BASE;
- __HAL_RCC_GPIOG_CLK_ENABLE();
- break;
- #endif
复制代码
回到前面的blinky闪灯程序,发现LED还是没有变化。进入仿真模式,并参考了CubuMX产生的代码,发现还需要设置PWR_CR2。再次修改uint32_t Set_GPIO_Clock(uint32_t port_idx)函数:
- #if defined(GPIOG_BASE)
- case PortG:
- gpio_add = GPIOG_BASE;
- __HAL_RCC_SYSCFG_CLK_ENABLE();
- __HAL_RCC_PWR_CLK_ENABLE();
- __HAL_RCC_GPIOG_CLK_ENABLE();
- HAL_PWREx_EnableVddIO2();
- break;
- #endif
复制代码
修改后,LED终于开始闪了。
修改后的SensorTile Mbed程序,目前只修改了GPIO部分,GPIOG对应的外设部分还没有修改,等进行到下一步后在说了。
SensorTileTest.zip
(2.31 MB, 下载次数: 43)