搜集到的一些资料:
RTT提供的F303的库
GD32 BSP制作1
RTT制作GD32系列BSP
移植RTT到GD32
兆易创新资料下载
GD32标准库移植 (兆易创新官网只提供了标准库) 标准库点灯
GD32芯片包下载 (和固件库包不一样)下载慢的话也可以官网中找GD32F30x AddOn
GITHUB上的RTT和GD32的BSP制作
GD32F305的例程
其实看完上面这些也没必要继续向下看了·······
下面是记录的一些技巧和过程细节
一、新建工程及编译
将下载下来的keil中的芯片包GigaDevice.GD32F30x_DFP.2.2.0.pack,安装上,否则新建项目的时候没办法选择芯片型号
然后GD32F30x_Firmware_Library_V2.1.3\GD32F30x_Firmware_Library_V2.1.3\Template\Keil_project中keil工程,不是为了用它,主要是为了在新建工程的时候复制一下它上面的路径,如下图
还有一些配置
至于上图中的包怎么选,在开始提到的链接里面有
还有一些文件夹的新建及文件新加,如下图
这样能看到文件的命名和分类了,当然也可以按照自己的风格进行重建,鼠标放到文件上,还可以显示文件的位置,便于下图添加文件(右击选中工程,选择Manage Project Items出来)
文件添加完成后,注意把Utilities文件夹下面的gd32f307c_lcd_eval.c屏蔽掉,否则找不到里面头文件,其实也能手动添加一下,但是我添加完成以后看了一下源文件,里面只是一些lcd相关的文件,一般用不到,屏蔽方法如下图,右击选择属性后,把include in target build前面的勾去掉就可以了
上面弄完点击编译按说可以通过了,但是main文件里面的好多函数找不到,应该是根据提供的标准库函数又向上封装了一层,所以就替换了,没有用他的main里面的内容
小技巧,替换他关于串口相关的函数时,可以去GD32F30x_Firmware_Library_V2.1.3\GD32F30x_Firmware_Library_V2.1.3\Examples\USART这个路径下面查看例程源文件,其它外设添加方法类似
下面是实测可以编译通过的led闪烁和串口打印示例
#include "gd32f30x.h"
#include "systick.h"
#include <stdio.h>
#include "main.h"
#include "gd32f30x_gpio.h"
void led_spark(void)
{
static __IO uint32_t timingdelaylocal = 0U;
if(timingdelaylocal){
if(timingdelaylocal < 500U){
gpio_bit_set(GPIOC, GPIO_PIN_6);
}else{
gpio_bit_reset(GPIOC, GPIO_PIN_6);
}
timingdelaylocal--;
}else{
timingdelaylocal = 1000U;
}
}
void GPIO_Config(void)
{
rcu_periph_clock_enable(RCU_GPIOC);
/*LED*/
gpio_init(GPIOC, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
}
void USART_Config(void)
{
/* enable GPIO clock */
rcu_periph_clock_enable(RCU_GPIOA);
/* enable USART clock */
rcu_periph_clock_enable(RCU_USART0);
/* connect port to USARTx_Tx */
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
/* connect port to USARTx_Rx */
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);
/* USART configure */
usart_deinit(USART0);
usart_baudrate_set(USART0, 115200U);
usart_receive_config(USART0, USART_RECEIVE_ENABLE);
usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
usart_enable(USART0);
printf("a usart transmit test example!");
}
int main(void)
{
/* configure systick */
systick_config();
/* initilize the LEDs, USART and key */
GPIO_Config();
USART_Config();
/* print out the clock frequency of system, AHB, APB1 and APB2 */
printf("\r\nCK_SYS is %d", rcu_clock_freq_get(CK_SYS));
printf("\r\nCK_AHB is %d", rcu_clock_freq_get(CK_AHB));
printf("\r\nCK_APB1 is %d", rcu_clock_freq_get(CK_APB1));
printf("\r\nCK_APB2 is %d", rcu_clock_freq_get(CK_APB2));
while (1){
led_spark();
delay_1ms(1);
}
}
/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
usart_data_transmit(USART0, (uint8_t)ch);
while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
return ch;
}
二、仿真及调试查看
一仿真就报了一个看似很正常的错误,如下图(大概意思就是没有那个寄存器读写的权限)
网上一查一大堆,都说改一下下图指的位置的内容就行
我按照网上说的把里面的数都快穷举了一遍,也是不行,后来发现他们都没说到根上,根就是keil5不支持M4内核的设备,和同事核实了一下,他也是这么说的,然后根据这个线索找了个靠谱答案
官网信息参考
找到原因了,接下来就找解决方法,不能别人说不行就不行啊,中间又扒拉了一下gd32官网提供的工具和第三方在线仿真工具,无果
找找找,找到一个看似可以解决的答案
试了大佬方法的第二种,不要问为什么没试第一种(已经穷举了)
倒是不出现开始的错误了,但是总是卡到一段没编译的程序里面,然后看了一下那段程序,是因为宏定义导致变灰的,所以就把#define __SYSTEM_CLOCK_IRC8M (uint32_t)(__IRC8M)放开了,然后把//#define __SYSTEM_CLOCK_120M_PLL_HXTAL (uint32_t)(120000000)屏蔽了(修改了一下时钟源),现在错误如下图(一直卡在这里出不去):
然后想着试试大佬的第三个方法,弄了一下,程序直接一仿真就跑起来来了,不过还是卡在上图那个地方,貌似情况更差了,然后试一下改改.ini文件的寄存器映射内容,去看数据手册
按着手册改的文件如下,还发现gd32f305咋没有AHB2啊
map 0x40000000, 0x4000FFFF read write // APB1
map 0x40010000, 0x400157FF read write // APB2
map 0x40018000, 0x5003FFFF read write // AHB1
map 0x60000000, 0xA0000FFF read write // AHB3
然后发现没啥用,看来不是这个原因啊,不过映射的确不一样,往好处想这是原因之一吧
现在有一瞬间有个想法,要不要把第一步穷尽的做法再搞一遍呢(先找找原因吧还是)
看了一下程序,卡在这好像是因为内部时钟一直不稳定,去了试试呢
去掉之后不卡在那了,但是卡在下面的地方了
找原因的过程在arm社区找到了下面的一个会议介绍,有兴趣的可以点击观看
再接着看,去网上查了一下,这个问题是因为串口的时钟不稳定导致的,这倒是符合前面的倒数第二个问题,所以就把串口相关的去了,奇迹出现,可以仿真了
下一步就是看引脚的变化了,虽然看不了串口,看看模拟出来的引脚电平也能解决一部分逻辑啊
还没看那,又发现一个错误,如下图
查资料的时候又发现个有意思的事情,解决问题竟然还能发论文
上面问题在文章里面找到了原因,是注意映射空间不要超过0x08000000,否则调试时会提示错误:“*** error 129: MapMemmap size truncated to 128MB”,无解
接着看io口电平,一直显示undefined identifier,就算了,直接在控制引脚那里放个全局变量,然后如下图在逻辑分析器里面看变化就行了
上图可以看出时间也是差不多的
关于中断和其它外设就不过多介绍了,感兴趣的可以看大佬们写的文章