GD32作为国产MCU最好的产品线也比较丰富,是替代品STM32是个不错的选择。前段时间用了一个项目GD32的单片机,今天来说说使用的一些体会。
1.硬件
我用的单片机型号是GD32F405RGT6,对应STM32F405RGT6。首先,硬件基本兼容。有一点区别是GD32的31和47脚为NC,STM32的为VCAP。STM这两个引脚需要单独连接一个电容器GND,而GD32则不需要。当然,有这两个电容也没关系,所以硬件GD32可直接替换STM32。
可使用仿真器Jlink,也可以使用STLink,但是,弹框提示将在下载程序时非的ST芯片。
2.软件
在软件方面,为了快速实现功能,直接使用ST的HAL库开发(版本为V1.27.0)。外设有:外高速时钟,Systick定时器、GPIO、串口1(DMA、中断)、SPI1、SPI2、I2C外部中断。用STM32CubeMx生成代码,不做任何改变,直接作为ST上述外设功能正常。说明两者兼容性还是不错的。其他外设基本兼容(未经测试),但是USB有些似乎只能用GD官方提供的USB库。
但是用别人的库文件,总觉得不靠谱,最后改成了GD官方库,版本为GD32F4xx_Firmware_Library_V3.0.0.总结修改过程中的一些经验:
GD的库跟ST以前的标准库非常相似,许多功能不如使用ST的HAL库方便。例如,串口DMA发送数据,使用HAL只需调用一个函数即可:
HAL_UART_Transmit_DMA(&huart1,tx_buffer,64);
而GD库中没有现成的函数,需要自己实现:
void usart_dma_transmit(uint8_t *pData,uint32_t num) { usart_flag_clear(USART0, USART_FLAG_TC); dma_channel_disable(DMA1, DMA_CH7); dma_flag_clear(DMA1, DMA_CH7, DMA_FLAG_FTF); dma_memory_address_config(DMA1, DMA_CH7, DMA_MEMORY_0, (uint32_t)pData); dma_transfer_number_config(DMA1, DMA_CH7, num); dma_channel_enable(DMA1, DMA_CH7); }
还有很多类似的,比如I2C读写24Cxx系列EEPROM的函数,HAL库中还包装了函数:
HAL_I2C_Mem_Write(&hi2c1,AT24Cxx_ADDR_WRITE,addr,I2C_MEMADD_SIZE_16BIT,dat,size,0xFFFFFFFF); HAL_I2C_Mem_Read(&hi2c1,AT24Cxx_ADDR_READ,addr,I2C_MEMADD_SIZE_16BIT,recv_buf,size,0xFFFFFFFF);
GD库也需要自己实现。虽然官方也提供了相关的例程,但只支持24C02等8位地址的器件,24C64等16位地址的设备需要自行修改。
当然,HAL库虽然好用,但是效率很低。记得以前做低功耗的东西,用STM32L151、主频设置低,使用HAL库回调函数写串口中断程序会出错。后来中断部分改为寄存器操作正常,说明效率低。
两者的命名方式不同。HAL库中时钟叫RCC_xxxx,而GD库中时钟叫RCU_xxxx。还有,HAL库中的外设标号从1开始,例如USART1、USART2…,而GD库的外设标号从0开始,USART0、USART1…。
编译后的大小也不同于实现相同功能的程序。GD库编译后的大小如下:
HAL库编译后的大小如下:
可以看到HAL库编译后的代码比GD库大了将近4KB,占用的RAM也大了1KB多。主要是因为HAL库为了不同系列芯片的兼容性好,做了多层包装,程序繁琐。
3.总结
总的来说,HAL库使用方便,但效率低。GD有些功能需要自己实现,但执行效率高。当然,如果使用的话GD我还是建议使用芯片。GD官方库,否则出了问题就不好调查了。
如果用ST我建议使用芯片HAL库。很多人排斥HAL库,一方面感觉效率低,另一方面感觉包装了很多层,看程序比较麻烦。我认为低效率的问题可以通过局部优化来改善。(HAL库还提供了一些类似标准库的高效底层函数,通常是__HAL开头)。而且现在单片机资源比较丰富,很多时候我们不必追求极致的效率。另一方面,官方一直在推动这一点,这也是一种趋势,我们最好与时俱进。
欢迎关注微信官方账号"开发嵌入式技术",你可以在后台给我留言交流。如果你觉得这个微信官方账号对你有帮助,也欢迎和别人分享。