高云FPGA系列教程(5):ARM点灯工程设计

news2024/11/19 22:45:41

文章目录

    • @[toc]
      • 1. ARM核定制
      • 2. ARM核程序设计
      • 3. ARM程序烧写
      • 4. 工程下载

本文是高云FPGA系列教程的第5篇文章。

前面几篇笔记都是介绍的高云GW1NSR-4C FPGA部分的使用,本篇文章介绍片上ARM Cortex-M3硬核处理器的使用,演示如何定制一颗ARM处理器硬件,ARM核程序设计及下载。

关于在FPGA上实现硬核和软核处理器,感兴趣的朋友可以查看之前写的几篇文章:

  • FPGA硬核和软核处理器的区别
    https://mp.weixin.qq.com/s/Y2cHZ6VYFngVPwO9upr69g

  • 有哪些内嵌ARM硬核的FPGA?
    https://mp.weixin.qq.com/s/C7y9y5XCid3HxK6yKdYVwg

  • 手把手教你在FPGA上定制一颗ARM处理器
    https://mp.weixin.qq.com/s/ZbNZCf-NW00vxuHSFvAoow

1. ARM核定制

高云GW1NSR-4C硬核处理器,基于ARM Cortex-M3 32Bit RISC内核,ARM3v7M 架构,最高80MHz工作频率,STM32单片机一般最高是72MHz,而Xilinx Microblaze处理器最高可跑到上百兆,而Microchip的ARM硬核也能跑到100多兆,GW1NSR-4C处理器的主频算是一般速度,不过足够应付一般的应用场景了。

首先打开一个基本的FPGA工程,比如LED点灯工程,打开IP核生成工具,选择IP核保存的路径,模块名称。

双击框图中的GPIO模块,使能GPIO

使能串口0

生成的例化模板:

Gowin_EMPU_Top your_instance_name(
    .sys_clk(sys_clk_i), //input sys_clk
    .gpioin(gpioin_i), //input [15:0] gpioin
    .gpioout(gpioout_o), //output [15:0] gpioout
    .gpioouten(gpioouten_o), //output [15:0] gpioouten
    .uart0_rxd(uart0_rxd_i), //input uart0_rxd
    .uart0_txd(uart0_txd_o), //output uart0_txd
    .reset_n(reset_n_i) //input reset_n
);

例化到顶层模块中:

/***************************************************************
 * Copyright(C), 2010-2022, WeChat:MCU149.
 * ModuleName : top_hdl.v 
 * Date       : 2022年9月27日
 * Time       : 20:19:39
 * Author     : WeChat:MCU149
 * Function   : gw1nsr-4c led driver demo
 * Version    : v1.0
 *      Version | Modify
 *      ----------------------------------
 *       v1.0    .....
 ***************************************************************/

module top_hdl(
    //Inputs
    input gclk,      // 27MHz
    input gresetn,    
    input key,
    input uart_rxd,

    //Outputs
    output uart_txd,
    output led
);

wire clk_60m;

wire arm_clk = clk_60m;
wire arm_resetn = gresetn;

wire arm_uart0_rxd = uart_rxd;
wire arm_uart0_txd;
wire [15:0] arm_gpio_in;
wire [15:0] arm_gpio_out;
wire [15:0] arm_gpio_outen;

assign uart_txd = arm_uart0_txd;
assign led = (arm_gpio_out[15:0] == 16'haaaa);
assign arm_gpio_in[15:0] = {16{key}};

Gowin_PLLVR pll_ut0(
    .clkout(clk_60m), //output clkout
    .clkin(gclk) //input clkin
);

Gowin_EMPU_Top arm_cortex_m3_core(
    //Inputs
    .sys_clk(arm_clk),
    .reset_n(arm_resetn),
    .uart0_rxd(arm_uart0_rxd), 
    .gpioin(arm_gpio_in[15:0]),

    //Outputs
    .uart0_txd(arm_uart0_txd),
    .gpioout(arm_gpio_out[15:0]),
    .gpioouten(arm_gpio_outen[15:0])
);

endmodule   //top_hdl end

模块的功能为,将按键状态连接到GPIO输入,GPIO输出连接到led,ARM核的主频为60MHz,来自PLL。

2. ARM核程序设计

GW1NSR-4C ARM核程序支持高云官方GMD环境,基于Eclipse开源框架,配合arm-gcc编译器来完成ARM核程序编写、编译、调试、下载等。还支持常用的单片机开发环境Keil-MDK,芯片型号选择通用的ARM-CM3处理器。

官方提供了非常不错的参考设计,包括FPGA工程,GMD工程,Keil工程,

下载地址:Gowin_EMPU_V1.0.zip

http://cdn.gowinsemi.com.cn/Gowin_EMPU_V1.0.zip

还有非常详细的IDE软件使用手册:IPUG928-1.1_Gowin_EMPU(GW1NS-4C)_IDE软件参考手册.pdf

http://cdn.gowinsemi.com.cn/IPUG928-1.1_Gowin_EMPU(GW1NS-4C)_IDE%E8%BD%AF%E4%BB%B6%E5%8F%82%E8%80%83%E6%89%8B%E5%86%8C.pdf

官方的参考设计基于DK-START开发板,包括FPGA工程和ARM工程(Keil+GMD),涵盖了所有外设的实例,包括固件库,参考设计,AHB2,APB2,I2C,SPI,UART,TIMER,INTC,WDOG,RTC,FreeRTOS,UCOS_II等等

文末有本次示例的工程下载地址,配套TangNano 4K开发板。

首先修改ARM程序中的系统主频,位于system_gw1ns4c.c文件中,


/*----------------------------------------------------------------------------
  Define clocks
 *----------------------------------------------------------------------------*/
#define __XTAL            (120000000UL)    /* Oscillator frequency */

#define __SYSTEM_CLOCK    (__XTAL / 2)	   /* 60MHz */

和FPGA工程中给定的时钟频率保持一致,否则延时时间不准确,串口输出为乱码。

下面来介绍几个函数的实现。

首先是延时函数实现,基于系统SysTick定时器实现。

需要在gw1ns4c_it.c文件中将SysTick_Handler函数删除,或者添加弱定义关键字,以免和用户的中断函数冲突。


/**
  * @brief  This function handles SysTick Handler.
  * @param  none
  * @retval none
  */
__weak void SysTick_Handler(void)
{
}

delay.h文件内容

#include "gw1ns4c.h"

void delay_init(void);
void SysTick_Handler(void);
void delay_us(uint32_t nus);
void delay_ms(uint32_t nms);

delay.c文件内容

#include "drv_timer.h"

uint32_t fac_us=0;							//us延时倍乘数
uint32_t fac_ms=0;							//ms延时倍乘数,在ucos下,代表每个节拍的ms数

void delay_init(void)
{
	SystemInit();
	SystemCoreClockUpdate();        //可以省略
}

void SysTick_Handler(void)
{
	if(fac_us) fac_us--;
	if(fac_ms) fac_ms--;
}

void delay_us(uint32_t nus)
{
	SysTick_Config(SystemCoreClock / 1000000);  //定时1us
	fac_us = nus;
	while(fac_us != 0);
}

void delay_ms(uint32_t nms)
{
	SysTick_Config(SystemCoreClock / 1000);     //定时1ms
	fac_ms = nms;
	while(fac_ms != 0);
}

printf重定向到串口。

Keil环境下:

#include "gw1ns4c.h"
#include <stdio.h>

int fputc(int ch, FILE *f)
{
    UART_SendChar(UART0, (unsigned char) ch);
    while(UART0->STATE & UART_STATE_TXBF);//UART0
    
    return (ch);
}

int fgetc(FILE *f)
{
	while(!(UART0->STATE & UART_STATE_RXBF));//UART0
	
	return (int)UART_ReceiveChar(UART0);
}

需要同时勾选使用MicroLib,就可以使用printf函数了。

高云官方GMD环境:

#include "gw1ns4c.h"
#include <stdio.h>
#include <sys/stat.h>

__attribute__ ((used))  int _write (int fd, char *ptr, int len)
{
  size_t i;

  for (i=0; i<len; i++)
  {
    UART_SendChar(UART0,ptr[i]); // call character output function
  }

  return len;
}

最后主函数设计:

#include "main.h"

int main(void)
{
	uint16_t rd = 0;
	uint16_t period = 100;

	delay_init();
	uart0_init(115200);

	printf("SystemCoreClock = %d\r\n", SystemCoreClock);
	printf("Hello GW1NSR-4C SoC(ARM Cortex-M3)\r\n");

//	GPIO_SetOutEnable(GPIO0, 0xffff); //0=in, 1=out

	while(1)
	{

		gpio_read(&rd);		//read gpio0

//		if(((rd >> 8) & 1) == 0)//key press
		if(rd == 0)//key press
		{
			printf("press: ");
			period = 100;
		}
		else if(rd == 0xffff) //key release
		{
			printf("release: ");
			period = 500;
		}
        printf("GW1NSR-4C ARM Cortex-M3 (Keil-MDK)\r\n");

		gpio_write(0xaaaa);
		delay_ms(period);

		gpio_write(0x0000);
		delay_ms(period);
	}
}

主函数的功能为,当按键未按下时,板载LED 500ms翻转一次,同时串口输出Release字符串,按键按下时,板载LED 100ms翻转一次,同时输出press字符串。

编程生成bin格式固件,GMD环境生成路径为:

在这里插入图片描述

Keil环境下,需要添加编译后执行fromelf命令,将axf文件转换为bin文件。

fromelf --bin -o "$L@L.bin" "#L"

配置如下图:

3. ARM程序烧写

ARM程序的烧写也比较简单,可以使用FPGA的编程工具,配置如下图所示:

fs文件选择对应的FPGA工程生成的比特流文件,bin文件为ARM核程序。

4. 工程下载

TangNano 4K配套工程下载

  • gw1nsr_4c_mcu_demo.rar

本文是高云FPGA系列教程的第5篇文章。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/510.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大数据电信客服-数据采集/消费(二)

目录 一、数据采集/消费(存储) 二、数据采集 三、数据消费 四、编写代码 在project-ct.pom 在ct.consume下 在ct.consumer.bean 在ct.consumer.dao 在ct-consumer的resources 在ct-common.pom 在ct.common.api 在ct.common.bean 在ct.common.constant 在ct-common的…

LQ0123 小朋友崇拜圈【DFS】

题目来源&#xff1a;蓝桥杯2018初赛 C C组G题 题目描述 班里N个小朋友&#xff0c;每个人都有自己最崇拜的一个小朋友&#xff08;也可以是自己&#xff09;。 在一个游戏中&#xff0c;需要小朋友坐一个圈&#xff0c; 每个小朋友都有自己最崇拜的小朋友在他的右手边。 求满…

vue06安装vue-cli+使用vue-cli搭建项目+什么是*.vue文件+开发示例+必问面试知识点

目录 1. vue-cli安装 1.1 安装前提 1.2 什么是vue-cli 1.3 安装vue-cli 2. 使用vue-cli构建项目 2.1 使用脚手架创建项目骨架 2.2 到新建项目目录&#xff0c;安装需要的模块 2.3 如何修改端口号 2.4 添加element-ui模块 2.5 package.json详解 3. install命令中的-g…

腾讯云~ zookeeper集群安装、配置、验证

文章目录一、 预备工作1. 下载2. 解压3. 创建目录4. myid 文件5. 验证6. 效果图二、配置管理2.1. zoo1.cfg2.2. zoo2.cfg2.3. zoo3.cfg2.4. 防火墙2.5. 启动zk2.6. 运行状态一、 预备工作 1. 下载 cd /app wget https://archive.apache.org/dist/zookeeper/zookeeper-3.4.12/…

GitLab API 的使用教程

1 简介 GitLab 作为一个开源、强大的分布式版本控制系统&#xff0c;已经成为互联网公司、软件开发公司的主流版本管理工具。使用过 GitLab 的都知道&#xff0c;想要提交一段代码&#xff0c;可以通过 git push 提交到远程仓库&#xff0c;也可以直接在 GitLab 平台上修改提交…

基于华为云IOT平台实现多节点温度采集(STM32+NBIOT)

一、前言 当前的场景是&#xff0c;在高速公路上部署温度采集设备&#xff0c;在高速路地表安装温度检测传感器&#xff0c;检测当前路段的路面实际温度。一段高速路上有多个地点需要采集温度数据。 采集温度数据需要上传到云平台进行数据存储&#xff0c;并且通过可视化界面展…

七万字整理SpringCloud + CloudAlibaba知识点总结笔记

各位小伙伴们大家好&#xff0c;欢迎来到这个小扎扎的spring cloud专栏&#xff0c;在这个系列专栏中我对B站尚硅谷阳哥的spring cloud教程进行一个总结&#xff0c;鉴于 看到就是学到、学到就是赚到 精神&#xff0c;这波依然是血赚 ┗|&#xff40;O′|┛ SpringCloud Clou…

Linux文件系统inode的作用

目录 前言 简介 inode与block 1、查看文件的inode信息 2、查看分区中的inode节点数 前言 前面学习了磁盘管理中的磁盘分区&#xff0c;以及逻辑卷&#xff0c;交换分区的创建&#xff0c;这篇文章将介绍一下我们在分区以及格式化时候用到的ext4文件系统&#xff0c;本盘文…

【云原生之Docker实战】使用Docker部署ShowDoc文档工具

【云原生之Docker实战】使用Docker部署ShowDoc文档工具一、ShowDoc介绍1.ShowDoc简介2.ShowDoc功能二、检查docker版本三、检查docker状态四、下载ShowDoc镜像五、创建ShowDoc容器1.创建数据目录2目录授权3.运行ShowDoc容器4.查看ShowDoc容器状态5.查看容器运行日志六、ShowDoc…

【精通Java篇 | IO流】详讲字节流与常用方法

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大二在校生&#xff0c;喜欢编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;小新爱学习. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc…

Java流式编程stream

文章目录一、简介二、创建Stream三、常用操作四、其他操作一、简介 流式 API 从 Java8 开始引入&#xff0c;支持链式书写。 流只能消费一次&#xff0c;不能被两次消费&#xff08;两次最终操作&#xff09; 流在管道中流通&#xff0c;在节点被处理。 流【无存储】&#x…

vim如何进行批量化注释及取消,也在1024表明自己算十分之一的程序员

前言 &#x1f47b;作者&#xff1a;龟龟不断向前 &#x1f47b;简介&#xff1a;宁愿做一只不停跑的慢乌龟&#xff0c;也不想当一只三分钟热度的兔子。 &#x1f47b;专栏&#xff1a;C初阶知识点 &#x1f47b;工具分享&#xff1a; 刷题&#xff1a; 牛客网 leetcode笔记软…

人家网站都免费了,你还用Python去爬?

文章目录⛳️ 实战场景⛳️ 实战编码⛳️ 实战场景 这次实战的目标是一个叫做猫肯的字体站点&#xff0c;该站点所有的字体都是免费可商用的&#xff0c;所以为什么还要去下载呢&#xff1f; 答案是练手&#xff0c;借免费站点学习爬虫&#xff0c;&#x1f30b; 目标站点地址…

Python爬虫技术系列-05字符验证码识别

Python爬虫技术系列-05字符验证码识别1. 光学文字识别1.1 OCR概述1.2 OCR识别库Tesseract下载安装1.3 生成验证码图片1.4 字符验证码识别1.安装python识别验证码库&#xff1a;2.验证码识别&#xff1a;1.5 使用打码平台识别验证码1.6 滑动验证码识别1. 光学文字识别 1.1 OCR概…

卡尔曼滤波实例——预测橘子的轨迹

目录 流程 一、采用轮廓的方式检测橘子位置 &#xff08;一&#xff09;滚动条获取阈值 &#xff08;二&#xff09;获取到图像中的包围橘子对应的白色图形的最小矩形框的信息 二、获取橘子检测框的质心 三、将质心送入卡尔曼滤波器&#xff0c;获取下一次的质心位置 四…

Markdown语言的简单学习

Markdown简单语法标题#空格 一级标题##空格 二级标题 以此类推三级标题四级...五级.....引用列表代码块表格分隔线链接强调语法&#xff08;斜体、加粗、下划线&#xff09;标题 #空格 一级标题 ##空格 二级标题 以此类推 三级标题 四级… 五级… … 引用 这是一段引用 …

<人生重开模拟器>——《Python项目实战》

目录 1.模拟实现 "人生重开模拟器" 1.1 问题导引&#xff1a; 1.2 问题分析&#xff1a; 2. 模拟实现分析及步骤&#xff1a; 3.完整源码&#xff1a; 4.写在最后的话&#xff1a; 后记&#xff1a;●由于作者水平有限&#xff0c;文章难免存在谬误之处&…

数据结构与算法----栈和队列(Stack Queue)

文章目录栈栈的操作栈的初始化入栈出栈取栈顶的元素判断栈是否为空求栈中数据元素的个数遍历栈中的所有元素清空栈栈的存储结构顺序存储链式存储顺序栈和链栈的区别栈的实战题目队列队列的操作入队出队遍历队列清空队列队列的存储结构顺序存储循环队列链式存储队列实战题目总结…

快速发布windows上的web项目【免费内网穿透】

快速发布windows上的web项目【免费内网穿透】 文章目录快速发布windows上的web项目【免费内网穿透】什么是cpolar内网穿透&#xff1f;概述1. 搭建一个静态Web站点1.1 下载演示站点1.2 本地运行演示站点1.3 本地浏览测试站点是否正常2. 注册并安装cpolar内网穿透3. 本地web站点…

玩转 CSS 的艺术之美

你将获得 深刻理解各种CSS原理 解构不为人知的CSS技巧 概念、技巧、场景三合一&#xff0c;实现“神奇”效果 强化吸收CSS知识体系&#xff0c;玩转各种神操作骚技巧 作者介绍 JowayYoung&#xff0c;资深前端工程师&#xff0c;目前就职于网易互动娱乐事业群&#xff0c…