58|1

208

帖子

0

TA的资源

纯净的硅(初级)

楼主
 

[兆易GD32H759I-EVAL]1.熟悉开发环境、熟悉开发资料、搭建基础工程 [复制链接]

 

1.简介——(摘录于GD官网,从了解MCU开始)

        兆易创新于2023.5.11推出了GD32H737/757/759系列超高性能MCU,该系列MCU采用基于Armv7E-M架构的600MHz Arm® Cortex®-M7高性能内核,凭借支持分支预测的6级超标量流水线架构,以及支持高带宽的AXI和AHB总线接口,可实现更高的处理性能。内置了高级DSP硬件加速器和双精度浮点单元(FPU),以及硬件三角函数加速器(TMU)和滤波算法加速器(FAC),大幅减轻了内核的负担并有助于提升处理效率。GD32H7系列MCU最高主频下的工作性能可达1552 DMIPS,CoreMark®测试取得了2888分的出色表现,同主频下的代码执行效率相比市场同类产品提升约10%,相比Cortex®-M4产品的性能提升超过40%。

        GD32H7系列MCU配备了1024KB到3840KB的片上Flash及1024KB的SRAM,其中包含512KB可配置超大紧耦合内存(ITCM, DTCM),可确保关键指令与数据的零等待执行;还配备了64KB L1-Cache高速缓存(I-Cache, D-Cache),有效提升CPU处理效率和实时性。外部总线扩展(EXMC)支持访问SDRAM、SRAM、ROM、NOR Flash和NAND Flash等多种片外存储器。GD32H7内置了可实时跟踪指令和数据的宏单元ETM(Embedded Trace Macrocell),提供在不干扰CPU正常运行情况下的高级调试功能。GD32H7内置的大容量存储空间能够支持复杂操作系统及嵌入式AI、机器学习(ML)等多种高级算法,实现兼具高性能和低延迟的实时控制。

        GD32H7系列MCU新增了大量通用外设资源,包含8个USART、4个I2C、6个SPI、4个I2S、2个SDIO以及2个八线制OSPI(可向下兼容四线制QSPI)等。配备了2个USB2.0 OTG接口,支持全速(Full Speed)和高速(High Speed)模式。还集成了3路CAN-FD控制器和2路以太网,满足高速互联应用所需。

        GD32H7系列MCU提供了出色的图形显示和音视频连接方案。芯片内置了TFT LCD液晶驱动器和图形处理加速器IPA (Image Processing Accelerator), 支持2D图像叠加、旋转、缩放及多种颜色格式转换等功能。还集成了串行音频接口(SAI)和SPDIF音频接口,以及8位至14位的数字摄像头接口,便于视频图像的采集与传输。

        GD32H7系列MCU采用1.71V~3.6V供电,支持高级电源管理并提供了三种供电模式(LDO/SMPS/直接供电)和五种低功耗模式,可实施灵活的供电策略以兼顾整体能耗平衡。配备了4个32位通用定时器、12个16位通用定时器、4个64位/32位基本定时器、2个PWM高级定时器。2个14位ADC采样速率可达4MSPS,1个12位ADC采样速率高达5.3MSPS,还集成了快速比较器(COMP)、DAC等高精度模拟外设以支持各类电机控制场景。

        GD32H7产品系列支持多种安全机制,为通信过程的数据安全提供保障。内置的硬件加解密支持DES、三重DES或AES算法,以及应用于多种场合的哈希(Hash)算法,确保传输信息的完整性。GD32H7系列MCU Flash/SRAM均支持ECC校验,能够有效提升系统运行的可靠性。还集成了RTDEC模块,可以对AXI或AHB总线数据进行实时解密,保护存储在外部SPI NOR Flash设备中只读固件的机密性。

        GD32H7提供了3个全新系列,并与现有产品完美兼容。按资源配置不同,GD32H737系列支持3路CAN 2.0B,GD32H757/GD32H759系列支持3路高速CAN-FD。按管脚封装不同,GD32H757系列具备BGA100和LQFP144/100三种封装选项;GD32H759系列具备BGA176 和LQFP176封装选项,以满足差异化开发需求。

        GD32H7可广泛用于数字信号处理、电机变频、电源、储能系统、无人机、音频视频、图形图像等各类应用。得益于超高主频以及大存储容量,该系列MCU也适用于机器学习和人工智能等诸多高端创新场景。

 

2.GD32H759I-EVAL全功能评估板

        GD32H759I-EVAL 评估板使用 GD32H759IMK6 作为主控制器。评估板使用 GD-Link Mini USB接口或者 DC-005 连接器提供 5V 电源。提供包括扩展引脚在内的及 Reset, Boot, Wakeup KEY, Tamper KEY, User KEY, LED, ADC, DAC, CAN, DCI, ETHNET, HPDF, SAI, I2S, I2C_SMbus, OSPI, SPI_LCD, SDIO, SDRAM, TLI_LCD, USB, USART 转 USB 接口等外设资源。(摘录于GD32H759I-EVAL评估板使用指南_Rev2.1)

 

3.准备开发资料及开发环境

        在GD32官网(https://www.gd32mcu.com/cn/download)下载一栏,找到GD32H7 MCU系列,然后在数据手册、用户手册、应用笔记、应用软件以及开发板资料下载相应的资料,如下图所示:

        我使用的是KEIL MDK-ARM集成开发环境,在使用之前需要安装刚刚下载的GD32H7xx AddOn软件,部署KEIL的PACK包;在GD32H7xx Firmware Library中提供了GD32H7xx标准固件库和外设示例程序,我们可以基于官方的驱动库,参考这些示例程序来开发我们的项目应用程序。

        GD32H759I-EVAL全功能开发板的资料在GD32H7xx_Demo_Suites_V2.0.1.7z\GD32H7xx_Demo_Suites_V2.0.1\GD32H759I_EVAL_Demo_Suites目录下,包含了使用指南、原理图、基于开发板的示例程序等等。

 

4.搭建基础工程

        为了尽快的熟悉和掌握MCU的使用,我们基于官方提供的驱动库,自己创建KEIL工程,基于板载的资源去定义一些硬件驱动程序,结合上层的应用来达到演示的效果;基础工程也是后面所有程序的一个基础,本着从易到难的学习过程,在基础工程中,我们先对开发板的资源做一个了解,然后实现LED显示驱动、用户按键操作驱动、日志打印这几个功能;

        按键的应用层,我们基于第三方的开源代码MultiButton来实现对按键的扫描检测和触发事件的处理,通过如下原理图,我们通过Wakeup按键和Tamper按键实现对LED1和LED2翻转显示操作,通过User Key按键来实现熄灭LED1和LED2的操作。

4.1.LED驱动程序

#include "bsp_led.h"

void bsp_LedInit(void)
{
    rcu_periph_clock_enable(RCU_GPIOF);
    gpio_mode_set(GPIOF, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_10);
    gpio_output_options_set(GPIOF, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_10);
    gpio_bit_reset(GPIOF, GPIO_PIN_10);

    rcu_periph_clock_enable(RCU_GPIOA);
    gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_6);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_60MHZ, GPIO_PIN_6);
    gpio_bit_reset(GPIOA, GPIO_PIN_6);
}

void bsp_Led1On(void)
{
    gpio_bit_set(GPIOF, GPIO_PIN_10);
}

void bsp_Led1Off(void)
{
    gpio_bit_reset(GPIOF, GPIO_PIN_10);
}

void bsp_Led1Toggle(void)
{
    if (gpio_output_bit_get(GPIOF, GPIO_PIN_10) == RESET)
    {
        gpio_bit_set(GPIOF, GPIO_PIN_10);
    }
    else
    {
        gpio_bit_reset(GPIOF, GPIO_PIN_10);
    }
}

void bsp_Led2On(void)
{
    gpio_bit_set(GPIOA, GPIO_PIN_6);
}

void bsp_Led2Off(void)
{
    gpio_bit_reset(GPIOA, GPIO_PIN_6);
}

void bsp_Led2Toggle(void)
{
    if (gpio_output_bit_get(GPIOA, GPIO_PIN_6) == RESET)
    {
        gpio_bit_set(GPIOA, GPIO_PIN_6);
    }
    else
    {
        gpio_bit_reset(GPIOA, GPIO_PIN_6);
    }
}

4.2.KEY驱动程序

#include "bsp_key.h"

void bsp_KeyInit(void)
{
    rcu_periph_clock_enable(RCU_GPIOA);
    gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_0);

    rcu_periph_clock_enable(RCU_GPIOC);
    gpio_mode_set(GPIOC, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_13);

    rcu_periph_clock_enable(RCU_GPIOF);
    gpio_mode_set(GPIOF, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_8);
}

uint8_t bsp_KeyReadPinLevel(uint8_t Index)
{
    uint8_t PinLevel = 0;

    switch (Index)
    {
        case 0:
            PinLevel = gpio_input_bit_get(GPIOA, GPIO_PIN_0);
            break;

        case 1:
            PinLevel = gpio_input_bit_get(GPIOC, GPIO_PIN_13);
            break;

        case 2:
            PinLevel = gpio_input_bit_get(GPIOF, GPIO_PIN_8);
            break;

        default:
            break;
    }

    return (PinLevel);
}

4.3.KEY应用程序

#include "key.h"
#include "bsp_key.h"
#include "bsp_led.h"
#include "multi_button.h"

struct Button keyWakeup;
struct Button keyTamper;
struct Button keyUser;

volatile uint8_t KeyRegisterFlag = 0;

void KEY_WakeupHandler(void *btn)
{
    struct Button *handle = (struct Button *)btn;

    if (handle->button_id == 0)
    {
        bsp_Led1Toggle();
    }
}

void KEY_TamperHandler(void *btn)
{
    struct Button *handle = (struct Button *)btn;

    if (handle->button_id == 1)
    {
        bsp_Led2Toggle();
    }
}

void KEY_UserHandler(void *btn)
{
    struct Button *handle = (struct Button *)btn;

    if (handle->button_id == 2)
    {
        bsp_Led1Off();
        bsp_Led2Off();
    }
}

void KEY_Init(void)
{
    button_init(&keyWakeup, bsp_KeyReadPinLevel, RESET, 0);
    button_init(&keyTamper, bsp_KeyReadPinLevel, RESET, 1);
    button_init(&keyUser,   bsp_KeyReadPinLevel, RESET, 2);

    button_attach(&keyWakeup, PRESS_DOWN, KEY_WakeupHandler);
    button_attach(&keyTamper, PRESS_DOWN, KEY_TamperHandler);
    button_attach(&keyUser,   PRESS_DOWN, KEY_UserHandler);

    button_start(&keyWakeup);
    button_start(&keyTamper);
    button_start(&keyUser);

    KeyRegisterFlag = 1;
}

4.4.系统初始化及日志功能实现

#include "platform.h"

volatile uint32_t PLATFORM_DelayTick = 0;

void PLATFORM_InitCache(void)
{
    SCB_EnableICache();
    SCB_EnableDCache();
}

void PLATFORM_InitSysTick(void)
{
    if (SysTick_Config(SystemCoreClock / 1000U))
    {
        while (1)
        {
        }
    }

    NVIC_SetPriority(SysTick_IRQn, 0x00U);
}

void PLATFORM_ConfigDelay(void)
{
    /* -----------------------------------------------------------------------
       TIMER50 configuration:
       TIMER50CLK = 300MHz/300 = 1MHz, the period is 1ms(1MHz/1000 = 1ms).
       ----------------------------------------------------------------------- */
    timer_parameter_struct timer_initpara;

    rcu_periph_clock_enable(RCU_TIMER50);

    timer_deinit(TIMER50);

    timer_struct_para_init(&timer_initpara);
    timer_initpara.prescaler         = 300 - 1;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.period            = 1000 - 1;
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
    timer_initpara.repetitioncounter = 0;
    timer_init(TIMER50, &timer_initpara);

    nvic_irq_enable(TIMER50_IRQn, 0, 0);

    timer_interrupt_flag_clear(TIMER50, TIMER_INT_FLAG_UP);
    timer_interrupt_enable(TIMER50, TIMER_INT_UP);

    timer_enable(TIMER50);
}

void PLATFORM_DelayMs(uint32_t Tick)
{
    PLATFORM_DelayTick = Tick;

    while (PLATFORM_DelayTick)
    {
    }
}

void PLATFORM_InitConsole(void)
{
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_USART0);

    gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_9);
    gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_10);

    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_9);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_9);

    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_10);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_100_220MHZ, GPIO_PIN_10);

    usart_deinit(USART0);
    usart_word_length_set(USART0, USART_WL_8BIT);
    usart_stop_bit_set(USART0, USART_STB_1BIT);
    usart_parity_config(USART0, USART_PM_NONE);
    usart_baudrate_set(USART0, 115200U);
    usart_receive_config(USART0, USART_RECEIVE_ENABLE);
    usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);

    nvic_irq_enable(USART0_IRQn, 0, 0);
    usart_interrupt_flag_clear(USART0, USART_INT_FLAG_RBNE);
    usart_interrupt_enable(USART0, USART_INT_RBNE);

    usart_enable(USART0);
}

int fputc(int ch, FILE *f)
{
    usart_data_transmit(USART0, (uint8_t)ch);

    while (RESET == usart_flag_get(USART0, USART_FLAG_TBE))
    {
    }

    return (ch);
}

void PLATFORM_PrintClocks(void)
{
    printf("\r\nGD32H759 %s %s", __DATE__, __TIME__);

    printf("\r\n");
    printf("\r\nCK_SYS  Frequency : %7.3f MHz", (double)rcu_clock_freq_get(CK_SYS)  / (double)1000000.0);
    printf("\r\nCK_AHB  Frequency : %7.3f MHz", (double)rcu_clock_freq_get(CK_AHB)  / (double)1000000.0);
    printf("\r\nCK_APB1 Frequency : %7.3f MHz", (double)rcu_clock_freq_get(CK_APB1) / (double)1000000.0);
    printf("\r\nCK_APB2 Frequency : %7.3f MHz", (double)rcu_clock_freq_get(CK_APB2) / (double)1000000.0);
    printf("\r\nCK_APB3 Frequency : %7.3f MHz", (double)rcu_clock_freq_get(CK_APB3) / (double)1000000.0);
    printf("\r\nCK_APB4 Frequency : %7.3f MHz", (double)rcu_clock_freq_get(CK_APB4) / (double)1000000.0);
    printf("\r\n");
}

void PLATFORM_Init(void)
{
    PLATFORM_InitCache();

    PLATFORM_InitSysTick();

    PLATFORM_ConfigDelay();

    PLATFORM_InitConsole();

    PLATFORM_PrintClocks();
}

4.5.相关中断处理

#include "gd32h7xx_it.h"
#include "key.h"
#include "platform.h"
#include "multi_button.h"

void NMI_Handler(void)
{
    while (1)
    {
    }
}

void HardFault_Handler(void)
{
    while (1)
    {
    }
}

void MemManage_Handler(void)
{
    while (1)
    {
    }
}

void BusFault_Handler(void)
{
    while (1)
    {
    }
}

void UsageFault_Handler(void)
{
    while (1)
    {
    }
}

void DebugMon_Handler(void)
{
    while (1)
    {
    }
}

void SVC_Handler(void)
{
    while (1)
    {
    }
}

void PendSV_Handler(void)
{
    while (1)
    {
    }
}

void SysTick_Handler(void)
{
    if (KeyRegisterFlag)
    {
        button_ticks();
    }
}

void TIMER50_IRQHandler(void)
{
    if (RESET != timer_interrupt_flag_get(TIMER50, TIMER_INT_FLAG_UP))
    {
        if (PLATFORM_DelayTick)
        {
            PLATFORM_DelayTick--;
        }

        timer_interrupt_flag_clear(TIMER50, TIMER_INT_FLAG_UP);
    }
}

void USART0_IRQHandler(void)
{
    if (RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE))
    {
        printf("%c", (uint8_t)usart_data_receive(USART0));
    }
}

 

5.注意事项及建议

5.1.LED的功能与TLI和USB有复用,User Key的功能与TLI有复用,所以在进行LED和KEY功能实现时,需要设置跳帽,和不与冲突的功能同时使用;

5.2.板载有调试器和CH340实现的USB转TTL接口;板载调试器只是实现了调试功能,没有虚拟串口功能,可以给整个单板供电;CH340部分需要通过跳帽选择USART功能,而且CH340部分的USB接口不能对单板进行供电,所以在调试打印日志的时候,需要接2个USB线;感觉比较麻烦,如果板载调试接口可以实现虚拟串口功能,那既省了CH340电路,又可以一根USB接线工作了;

 

6.运行结果

11

 

7.附件:

软件工程源代码: Project_20240122.zip (864.1 KB, 下载次数: 0)

最新回复

每天学习一点,提升一些。   详情 回复 发表于 2 小时前
点赞(1) 关注
个人签名We are a team and we work as a team !
 
 

回复
举报

16

帖子

0

TA的资源

一粒金砂(中级)

沙发
 

每天学习一点,提升一些。

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表