立创逻辑派FPGA-G1开发板支持Cortex-M1软核开发,这对于众多MCU爱好者来说,Cortex-M1无疑是一个亲切而熟悉的名词。在接下来的步骤中,我将带领大家使用Gowin软件内置的Cortex-M1软核,进行软硬件编程的实际操作。我们的目标是实现一个简洁而实用的功能——通过按键来控制LED灯的开关。让我们携手步入编程实践之旅。
1、FPGA 硬件搭建
首先我们这里打开,Gowin 软件,点开IP核里面搜索 M1 即可,如下图所示:
双击之后,进入配置界面,这里面包括 Cortex-M1、APB Bus Peripherals 和 AHB Bus Peripherals 配置选项,如下图所示:
1.1、Cortex-M1 内核介绍
这里我们双击 Cortex-M1 内核系统配置,如下图所示:
1.1.1、Common 界面,如下图所示:
Number of interrupts :配置 Cortex-M1 外部中断数量,可选择 1、8、16 或 32,默认为 32
OS Extension :配置 Cortex-M1 是否支持操作系统,默认为支持。
Small Multiplier:配置 Cortex-M1 small 模式硬件乘法器,默认为 normal 模式。
Big Endian:配置 Cortex-M1 数据大端格式,默认为小端格式。
External Interrupts:配置 4 个扩展的外部中断输入。若不选,则不支持扩展的外部中断输入。
1.1.2、DEbug 界面,如下图所示:
- Enable Debug:开启 Cortex-M1 Debug 功能,默认为开启 Debug。
- Debug Port Select:配置调试器接口,可以选择 JTAG、Serial Wire 和 JTAG and Serial Wire,默认为 JTAG and Serial Wire 是J-link上面的调试端口(JTAG模式下),这里我们选择 Serial Wire ,来用于DAP Link 调试。
- Small Debug:配置 Small 模式调试器,默认为 Full 模式调试器。
1.1.3、Memory 界面,如下图所示:
ITCM Select:可以选择 Internal Instruction Memory 或 External InstructionMemory ,默认 Internal Instruction Memory 。
- Internal Instruction Memory:内部指令存储器,片内 Block RAM 硬件存储资源,起始地址 0x00000000;
- External Instruction Memory:外部指令存储器,如 SPI-Flash Memory 等,起始地址 0x00000000。
ITCM Size:配置内部指令存储器 Size,可以选择 1/2/4/8/16/32/64/128/256/512KB。而我们的逻辑派最大只支持64KB,这里我们选择默认为32KB。
ITCM Initialization: ITCM 初始化配置,只有在勾选了 Initialize ITCM 的情况下,该配置才能被启用,如果选择 Initialize ITCM,则支持 ITCM 初始化,可以在 ITCM Initialization Path 导入 ITCM 初始值文件路径。如果选择使用片外 SPI-Flash Memory 下载引导方式,ITCM 初始值根据不同的 ITCM Size 导入不同的 bootload 文件路径。注意 ITCM Initialization Path 导入的文件路径中,不能有以数字命名或 \r \n 等转义字符的文件夹路径。
DTCM Select 配置:可以选择 Internal Data Memory 或 External Data Memory ,默认 Internal Data Memory 。
- Internal Data Memory:内部数据存储器,片内 Block RAM 硬件存储资源,起始地址 0x20000000。
- External Data Memory:外部数据存储器,如 DDRx Memory 等,起始地址 0x20100000
DTCM Size 配置:如果选择已选择 Internal Data Memory,则逻辑派的 DTCM Size 最大只支持64KB,这里我们选中默认为32KB。
Cortex-M1 内核界面最终配置,其余保持默认,配置完毕点击 OK ,如下图所示:
2、GPIO 介绍
在 Gowin_EMPU_M1 IP核 的配置界面可以看到。
AHB总线上: GPIO、 CAN、 Ethernet、 DDR3 Memory、 PSRAM Memory、 SPI-FlashMemory、 AHB Master [1-6];
APB 总线上: UART0、 UART1、 Timer0、 Timer1、Watch Dog、 RTC、 DualTimer、 TRNG、 I2C Master、 SPI Master、 SD-CardAPB Master [1-16]。双击进入 GPIO 配置界面,如下图所示:
如果选择 Enable GPIO ,则 Gowin_EMPU_M1 支持 GPIO,默认关闭,在选择 Enable GPIO,则可以配置 GPIO 端口类型后则可以配置 GPIO 端口类型,支持IN、OUT、EN 端口类型,默认支持 INOUT 端口类型。
GPIO 配置完后,点击 OK,如下图所示:
其余我们这里就不在讲解了,感兴趣的去看看官网文档:Gowin-M1 IP核介绍
配置完毕之后,我们可以看到,GPIO 框已经变绿了,表示外设配置成功,如下图所示,然后点击 OK, Gowin_EMPU_M1 IP 配置就完成。
点击 OK 再点击Cortex-M1 界面 的 OK ,之后会弹出是否添加此文件在工程里面,选中 OK 即可。如下图所示:
3、引脚分配
接下来就该编译文件了,在过程管理窗口 Process -> Synthesize 双击,如下图所示:
分配 FPGA 的 LED 的 I/O 引脚,工具栏找到可以找到 FloorPlanner 图标,如下图所示:
点击 FloorPlanner 后会转跳到如下图所示界面。如果没有创建 CST 文件,会提示创建,这里选择 OK 按钮:
接下来跳转到 FloorPlanner 选项卡,进行引脚分配。如下图所示:
注:如果对时钟有要求,需要对时钟进行约束,这里只用按键控制 led 则没有进行约束。
接下来在过程管理窗口 Process > Place & Route 双击,来对代码布局布线进行综合,如下图所示:
实物连接,如下图所示:
接下来我们该固化到 FPGA 的外部 FLASH 里面,如下图所示:
到此我们的 FPGA 搭建环境就告一段落了。
2、MDK 开发
接下来我们该用 keil5 进 MDK 开发。这里是官方提供MDK 设计步骤 逻辑派FPGA-G1 MDK开发
这里我们直接下载官方测试 demo ,逻辑派FPGA-G1 配套程序
下载完成之后,根据路径打开此文件(Gowin_EMPU_M1_V2.1\ref_design\MCU_RefDesign\MDK_RefDesign\cm1_demo\project\led\mdk_v5
)即可。如下图所示:
首先我们需要配置编译器,不然编译会报错的,如下图所示:
首先我们把IROM1 的启始地址设置为 0x00 即可,接下来,我们点击 User 界面,配置编译工具(这个路径就在你们 keil5 安装包位置:keil5\ARM\ARMCC\bin 注:每人的路径名字不一致,需要自己找一下),如下图所示:
添加完这个编译工具后,需要在后面添加一行命令( D:\keil5\ARM\ARMCC\bin\fromelf.exe --bin -o led.bin .\Objects\led.axf 注:fromelf.exe 前面根据自己的路径修改),这个用于生成一个 bin 文件,如下图所示:
在添加另外一个工具前我们需要再复制一个脚本(路径:Gowin_EMPU_M1_V2.1\tool\make_hex\ref_design\MCU_RefDesign\cm1_demo\project\led\mdk_v5\make_hex)到当前文件夹下(路径:Gowin_EMPU_M1_V2.1\ref_design\MCU_RefDesign\MDK_RefDesign\cm1_demo\project\led\mdk_v5\),如下图所示:
在(Run #2)位置我们还需要添加一个脚本工具(名字:make_hex.exe),添加完成之后 需要在后面添加一句话 led.bin
主要是用来生成一个 bin 文件,添加内容(make_hex.exe led.bin
)点击 OK 即可,如下图所示:
添加完成之后,我们可以点击全编译,编译之后,会看到这里显示的是 0 错误, 0 警告。如下图所示:
如果重新下图错误请检查 Run #1 是否添加正确。
接下来我们修改程序,首先点击 gpio.c 修改驱动,程序和截图如下图所示:
#include "gpio.h"
void gpio_init(void)
{
GPIO_InitTypeDef GPIO_InitType;
//Initializes GPIO pin 0~1 as output
GPIO_InitType.GPIO_Pin = GPIO_Pin_0 |
GPIO_Pin_1; //Pin 0~1
GPIO_InitType.GPIO_Mode = GPIO_Mode_OUT; //As output
GPIO_Init(GPIO0,&GPIO_InitType); //Initialized
//Initializes GPIO pin 2 as input
GPIO_InitType.GPIO_Pin = GPIO_Pin_2;
GPIO_InitType.GPIO_Mode = GPIO_Mode_IN; //As input
GPIO_Init(GPIO0,&GPIO_InitType); //Initialized
//Initializes output value
//on:0; 1:off on some boards
//on:1; 0:off on some boards
//Customized
GPIO_SetBit(GPIO0,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
接下来我们修改程序,首先点击 main.c 修改驱动,程序和截图如下图所示:
#include "delay.h"
#include "gpio.h"
void GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin)
{
assert_param(IS_GPIO_PIN(GPIO_Pin));
if ((GPIOx->DATAOUT & GPIO_Pin) != 0x00u)
{
GPIO0->DATAOUT &= ~GPIO_Pin;
}
else
{
GPIO0->DATAOUT |= GPIO_Pin;
}
}
void GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, uint32_t PinValue)
{
assert_param(IS_GPIO_PIN(GPIO_Pin));
if (!PinValue)
{
GPIO0->DATAOUT &= ~GPIO_Pin;
}
else
{
GPIO0->DATAOUT |= GPIO_Pin;
}
}
//Application entry function
int main(void)
{
SystemInit(); //Initializes system clock
gpio_init(); //Initializes GPIO0
delay_init(); //Initializes delay functions
while(1)
{
GPIO_WritePin(GPIO0,GPIO_Pin_1,(GPIO0->DATA & GPIO_Pin_2)?1:0); //按键按下 LED3 红灯亮起
GPIO_TogglePin(GPIO0,GPIO_Pin_0); //LED2 进入翻转模式
delay_sec(1); //Delay 1 second
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
添加完成之后,我们可以点击全编译,编译之后,会看到这里显示的是 0 错误, 0 警告,后连接实物(我这边使用的一个 DAP-Link 连上~ 引脚:N14-DIO N16-clk),如下图所示:
在 MDK 软件中,首先点击 魔法棒 进入 Debug 选项,找到 Use 选项,选择自己使用的调试器,我们使用的 DAP-Link,这里就需要选择为 CMSIS-DAPDebugger ,如下图所示:
然后点击 Debug 进入调试界面,然后点击运行,让程序开始跑起来,如下图所示:
运行起来,可以看到板载的 LED2 在闪烁,当我们按下 F10 , LED3 处于一致常亮状态,则我们 MDK 开发没有问题,如下图所示:
接下来我们开始添加 bootload (Gowin_EMPU_M1_V2.1\bootload\bootload\SA_0x400000\ITCM_Size_32KB\),将里面的内容复制到我们的 LED 工程里面(路径:Gowin_EMPU_M1_V2.1\ref_design\MCU_RefDesign\MDK_RefDesign\cm1_demo\project\led\mdk_v5),如下图所示:
注:若是文件里面自动添加了则可以不用复制。
在当前文件夹里面(路径::Gowin_EMPU_M1_V2.1\ref_design\MCU_RefDesign\MDK_RefDesign\cm1_demo\project\led\mdk_v5)创建 ITCM 文件用于后面下载在FPGA里面做引导启动,如下图所示:
接下来我们需要再进行编译,如下图所示:
编译成功后我们需要将更新的 itcm0 ~ itcm3 复制到 ITCM 文件夹里面,如下图所示:
3、固化程序
接下来我们回到 Gowin 软件,点击 IP Core Generator 中点击 ,找到之前建立的 Cortex-M1 软核,选中 gowin_empu_m1.ipc 后点击打开,如下图所示:
进入 Cortex-M1 配置界面, 在 Memory 配置界面下,在 initialize ITCM前打钩,再点击 ... 添加文件,如下图所示:
找到 ITCM 初始化文件配置,点击到我们刚刚建立的存放 itcm 文件的文件夹路径,如下图所示:
添加完成后点击 OK 后会自动关闭Cortex-M1 界面,再点击 Gowin EMPU M1 右下角的 OK ,如下图所示:
点击 OK 之后,会弹出是否添加到当前项目中,选中 OK 即可,如下图所示:
IP Core Generator 界面消失之后,重新综合编译,如下图所示:
重新生成新的 fs 文件。然后连接好FPGA下载器,重新下载固化新的 fs 文件即可,如下图所示:
下载完成之后,可以看到逻辑派上的 LED2 开始闪烁,接下来按着 F10 引脚按键,LED3 将会亮起,松开之后灯将会熄灭。