GD32学习

关于ARM

ARM公司设计的处理器内核有很多种,根据不同的应用场景和性能需求,可以选择不同的内核进行设计。以下是一些常见的ARM内核:

  1. Cortex-A系列:面向高性能应用领域的内核,主要用于移动设备、智能终端、高端嵌入式系统等领域。Cortex-A系列内核具有高性能、高可扩展性、丰富的外设接口和低功耗等优点。
  2. Cortex-R系列:面向实时应用领域的内核,主要用于工业控制、汽车电子、航空航天等领域。Cortex-R系列内核具有高可靠性、低延迟、强实时性和硬件保护等特点。
  3. Cortex-M系列:面向低功耗嵌入式系统的内核,主要用于智能传感器、便携式设备、家用电器等领域。Cortex-M系列内核具有低功耗、低成本、高效能、易于开发等特点。
  4. ARM7系列:面向嵌入式系统领域的内核,主要用于控制器、存储设备、安全芯片等领域。ARM7系列内核具有低成本、低功耗、高集成度、易于开发等特点。
  5. ARM9系列:面向嵌入式系统领域的内核,主要用于数字音视频、通信、网络设备等领域。ARM9系列内核具有高性能、多媒体处理能力、丰富的外设接口和易于扩展等特点。

Cortex-M系列是ARM公司推出的一种面向低功耗嵌入式系统的处理器内核,主要用于智能传感器、便携式设备、家用电器等领域。Cortex-M系列内核具有低功耗、低成本、高效能、易于开发等特点,是目前嵌入式系统领域最受欢迎的处理器内核之一。根据不同的性能和功耗需求,Cortex-M系列内核又分为以下几类:

  1. Cortex-M0系列🌟:面向低功耗、成本敏感型应用,适用于智能传感器、安全芯片、家用电器等领域。Cortex-M0系列内核的主频通常在10MHz-50MHz之间,具有低功耗、低成本、易于开发等特点。
  2. Cortex-M3系列:面向高性能、实时应用,适用于工业控制、汽车电子、医疗设备等领域。Cortex-M3系列内核的主频通常在50MHz-120MHz之间,具有高性能、强实时性和硬件保护等特点。
  3. Cortex-M4系列🌟:基于Cortex-M3系列内核,增加了DSP和浮点运算单元,适用于音视频处理、图像处理、控制算法等领域。Cortex-M4系列内核的主频通常在80MHz-240MHz之间,具有高性能、DSP(Digital Signal Processing)和浮点运算能力等特点。
  4. Cortex-M7系列:基于Cortex-M4系列内核,增加了双精度浮点运算单元和指令预取器等特性,适用于音视频编解码、高速通信等领域。Cortex-M7系列内核的主频通常在200MHz-400MHz之间,具有高性能、低延迟和高精度的浮点运算能力等特点。

GD32的产品系列

  • L系列:基于Cortex-M3内核,主要特点是低功耗和低成本,适用于高端家电、消费电子、医疗设备、工业控制等领域。
  • F系列:基于Cortex-M4内核,主要特点是高性能和丰富的外设资源,适用于高端消费电子、医疗设备、工业控制、安防监控等领域。
  • E系列:基于Cortex-M0+内核,主要特点是超低功耗和小尺寸,适用于物联网、可穿戴设备、智能家居等领域。
  • V系列:基于Cortex-M0内核,主要特点是低功耗和高性价比,适用于低端家电、消费电子、LED灯等领域。
  • C系列:基于Cortex-M4内核,主要特点是高性能和低功耗,适用于智能家居、安防监控、工业控制等领域。
  • W系列:基于Cortex-M3内核,主要特点是超低功耗和高性价比,适用于物联网、可穿戴设备等领域。
  • A系列:基于Cortex-A7内核,主要特点是高性能和丰富的外设资源,适用于高端工业控制、嵌入式计算机等领域。

 GD32F470ZG

gpio

推挽输出

rcu_periph_clock_enable(RCU_GPIOx);
gpio_mode_set(GPIOx, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_x);
gpio_output_options_set(GPIOx, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, GPIO_PIN_x);

开漏输出

rcu_periph_clock_enable(RCU_GPIOx);
gpio_mode_set(GPIOx, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_x);
gpio_output_options_set(GPIOx, GPIO_OTYPE_OD, GPIO_OSPEED_MAX, GPIO_PIN_x);

开漏上拉输出

rcu_periph_clock_enable(RCU_GPIOx);
gpio_mode_set(GPIOx, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO_PIN_x);
gpio_output_options_set(GPIOx, GPIO_OTYPE_OD, GPIO_OSPEED_MAX, GPIO_PIN_x);

上拉输入

rcu_periph_clock_enable(RCU_GPIOx);
gpio_mode_set(GPIOx, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, GPIO_PIN_x);

下拉输入

rcu_periph_clock_enable(RCU_GPIOx);
gpio_mode_set(GPIOx, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO_PIN_x);

电平读取

FlagStatus state = gpio_input_bit_get(GPIOx, GPIO_PIN_x);

串口

Usart0.h

#ifndef __USART0_H__
#define __USART0_H__

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

#define USART0_RX_ENABLE	1

void Usart0_init();
void Usart0_send_byte(uint8_t data);
void Usart0_send_string(char* data);

#if USART0_RX_ENABLE
extern void Usart0_recv(uint8_t* data, uint32_t len);
#endif

#endif
Usart.c

#include "Usart0.h"

#if USART0_RX_ENABLE
#define USART_RECEIVE_LENGTH  1024
//串口接收缓冲区大小
uint8_t g_recv_buff[USART_RECEIVE_LENGTH];   // 接收缓冲区
//接收到字符存放的位置
uint32_t g_recv_length = 0;
#endif

//1. 初始化
void Usart0_init() {
    // 哪个串口
    uint32_t usartx = USART0;
    uint32_t usartx_rcu = RCU_USART0;
    uint32_t usartx_irq = USART0_IRQn;

    // 波特率
    uint32_t usartx_p_baudrate = 115200;

    // tx和rx,用了哪个引脚
    uint32_t usartx_tx_port_rcu = RCU_GPIOA;
    uint32_t usartx_tx_port = GPIOA;
    uint32_t usartx_tx_pin = GPIO_PIN_9;
    // 复用功能编号
    uint32_t usartx_tx_af = GPIO_AF_7;

    // tx和rx,用了哪个引脚
    uint32_t usartx_rx_port_rcu = RCU_GPIOA;
    uint32_t usartx_rx_port = GPIOA;
    uint32_t usartx_rx_pin = GPIO_PIN_10;
    // 复用功能编号
    uint32_t usartx_rx_af = GPIO_AF_7;


    /*************** gpio *****************/
    // TX
    // 配置时钟
    rcu_periph_clock_enable(usartx_tx_port_rcu);
    // 配置模式: 复用功能
    gpio_mode_set(usartx_tx_port, GPIO_MODE_AF, GPIO_PUPD_NONE, usartx_tx_pin);
    // 配置复用功能
    gpio_af_set(usartx_tx_port, usartx_tx_af, usartx_tx_pin);
    gpio_output_options_set(usartx_tx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, usartx_tx_pin);

    // RX
    // 配置时钟
    rcu_periph_clock_enable(usartx_rx_port_rcu);
    gpio_mode_set(usartx_rx_port, GPIO_MODE_AF, GPIO_PUPD_NONE, usartx_rx_pin);
    gpio_af_set(usartx_rx_port, usartx_rx_af, usartx_rx_pin);
    // 配置输出参数
    gpio_output_options_set(usartx_rx_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, usartx_rx_pin);

    /*************** usart ****************/
    // 串口时钟
    rcu_periph_clock_enable(usartx_rcu);
    // USART复位
    usart_deinit(usartx);

    // 波特率
    usart_baudrate_set(usartx, usartx_p_baudrate);
    // 校验位
    usart_parity_config(usartx, USART_PM_NONE);
    // 数据位数
    usart_word_length_set(usartx, USART_WL_8BIT);
    // 停止位
    usart_stop_bit_set(usartx, USART_STB_1BIT);
    // 先发送高位还是低位
    usart_data_first_config(usartx, USART_MSBF_LSB);

    // 发送功能配置
    usart_transmit_config(usartx, USART_TRANSMIT_ENABLE);

    #if USART0_RX_ENABLE
    // 接收功能配置
    usart_receive_config(usartx, USART_RECEIVE_ENABLE);
    // 接收中断配置
    nvic_irq_enable(usartx_irq, 2, 2);
    // usart int rbne
    usart_interrupt_enable(usartx, USART_INT_RBNE);
    usart_interrupt_enable(usartx, USART_INT_IDLE);
    #endif

    // 使能串口
    usart_enable(usartx);
}

//2. 发送
void Usart0_send_byte(uint8_t data) {
    //通过USART发送
    usart_data_transmit(USART0, data);

    //判断缓冲区是否已经空了
    //FlagStatus state = usart_flag_get(USART_NUM,USART_FLAG_TBE);
    while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
}
void Usart0_send_string(char* data) {

    while(data && *data) {
        Usart0_send_byte((uint8_t)(*data));
        data++;
    }
}

// printf打印功能
int fputc(int ch, FILE *f){
    Usart0_send_byte((uint8_t)ch);
    return ch;
}


#if USART0_RX_ENABLE
// 名称不能随意改,串口0的中断,就是这个名字
void USART0_IRQHandler(void) {
    if ((usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)) == SET) {
        uint16_t value = usart_data_receive(USART0);
        g_recv_buff[g_recv_length] = value;		
        g_recv_length++;
    }
    if (usart_interrupt_flag_get(USART0, USART_INT_FLAG_IDLE) == SET) {
        //读取缓冲区,清空缓冲区
        usart_data_receive(USART0);
        g_recv_buff[g_recv_length] = '\0';

        // TODO: g_recv_buff为接收的数据,g_recv_length为接收的长度
        // printf("recv: %s\r\n", g_recv_buff);
        Usart0_recv(g_recv_buff, g_recv_length);


        g_recv_length = 0;
    }
}
#endif

外部中断

硬件中断

static void EXTI_config() {
    uint32_t extix = EXTI_0;
    uint32_t extix_irq = EXTI0_IRQn;
    uint32_t extix_irq_pre = 1;
    uint32_t extix_irq_sub = 1;

    uint32_t extix_trig = EXTI_TRIG_BOTH;

    uint32_t extix_rcu = RCU_GPIOA;
    uint32_t extix_port = GPIOA;
    uint32_t extix_pin = GPIO_PIN_0;
    uint32_t extix_pupd = GPIO_PUPD_NONE;
    uint32_t extix_src_port = EXTI_SOURCE_GPIOA;
    uint32_t extix_src_pin = EXTI_SOURCE_PIN0;

    /*************** gpio ****************/
    // PA0,
    // 时钟初始化
    rcu_periph_clock_enable(extix_rcu);
    // 配置GPIO模式
    gpio_mode_set(extix_port, GPIO_MODE_INPUT, extix_pupd, extix_pin);

    /*************** exti ****************/
    // 时钟配置
    rcu_periph_clock_enable(RCU_SYSCFG);
    // 配置中断源
    syscfg_exti_line_config(extix_src_port, extix_src_pin);
    // 中断初始化
    exti_init(extix, EXTI_INTERRUPT, extix_trig);

    // 配置中断优先级
    nvic_irq_enable(extix_irq, extix_irq_pre, extix_irq_sub);
    // 使能中断
    exti_interrupt_enable(extix);
    // 清除中断标志位
    exti_interrupt_flag_clear(extix);
}

软件中断

static void EXTI_config() {
    uint32_t extix = EXTI_0;
    uint32_t extix_irq = EXTI0_IRQn;
    uint32_t extix_irq_pre = 1;
    uint32_t extix_irq_sub = 1;

    uint32_t extix_trig = EXTI_TRIG_BOTH;

    uint32_t extix_rcu = RCU_GPIOA;
    uint32_t extix_port = GPIOA;
    uint32_t extix_pin = GPIO_PIN_0;
    uint32_t extix_pupd = GPIO_PUPD_NONE;
    uint32_t extix_src_port = EXTI_SOURCE_GPIOA;
    uint32_t extix_src_pin = EXTI_SOURCE_PIN0;

    /*************** gpio ****************/
    // PA0,
    // 时钟初始化
    rcu_periph_clock_enable(extix_rcu);
    // 配置GPIO模式
    gpio_mode_set(extix_port, GPIO_MODE_INPUT, extix_pupd, extix_pin);

    /*************** exti ****************/
    // 时钟配置
    rcu_periph_clock_enable(RCU_SYSCFG);
    // 配置中断源
    syscfg_exti_line_config(extix_src_port, extix_src_pin);
    // 中断初始化
    exti_init(extix, EXTI_INTERRUPT, extix_trig);

    // 配置中断优先级
    nvic_irq_enable(extix_irq, extix_irq_pre, extix_irq_sub);
    // 使能中断
    exti_interrupt_enable(extix);
    // 清除中断标志位
    exti_interrupt_flag_clear(extix);
}

GD32F4中断线编号

GD32F4复用功能查询

PA

PB

PC

PD

PE

PF

PG

PH

PI

GD32F4串口引脚查询

GD32F4时钟树查询

架构图

时钟树

GD32F4定时器查询

类型

编号

引脚

计数模式

互补和死区

正极性

负极性

高级
(4通道)

定时器0

复用AF1
倍频2

CH0

PA7 ON,PA8,PB13 ON
,PE8 ON, PE9

向上
向下
中央对齐

PA8
PE9

PA7 ONPB13 ON
PE8 ON

CH1

PA9,PB0 ON,PB14 ON,
PE1 ON,PE10 ON,PE11

PA9
PE11

PB0 ONPB14 ON
PE1 ONPE10 ON

CH2

PA10,PB1 ON,PB15 ON
PE12 ON,PE13

PA10
PE13

PB1 ONPB15 ON
PE12 ON

CH3

PA11,PE14

BRKIN

PA06,PB12,PE15

ETI

PE7

定时器7

复用AF3
倍频2

CH0

PA5 ON,PA7 ON,PC6
,PH13 ON,PI5

向上
向下
中央对齐

PC6
PI15

PA5 ONPA7 ON
PH13 ON

CH1

PB0 ON,PB14 ON,PC7,
PH14 ON,PI6

PC7
PI6

PB0 ONPB14 ON
PH14 ON

CH2

PB1 ON,PB15 ON,PC8,
PH15 ON,PI7

PC8
PI7

PB1 ONPB15 ON
PH15 ON

CH3

PC9,PI2

NONE

BRKIN

PA6,PI4

ETI

PA0,PI3

通用(L0)
(4通道)

定时器1

复用AF1
倍频4
 

CH0

PA0,PA5,PA15,PB8

向上
向下
中央对齐

CH1

PA1,PB3,PB9

CH2

PA2,PB10

CH3

PA3,PB2,PB11

ETI

PB8

定时器2

复用AF2
倍频4

CH0

PA6,PB4,PC6

向上
向下
中央对齐

CH1

PA7,PB5,PC7

CH2

PB0,PC8

CH3

PB1,PC9

ETI

PD2

定时器3

复用AF2
倍频4

CH0

PB6,PD12

向上
向下
中央对齐

CH1

PB7,PD13

CH2

PB8,PD14

CH3

PB9,PD15

ETI

PE0

定时器4

复用AF2
倍频4

CH0

PA0,PH10

向上
向下
中央对齐

CH1

PA1,PH11

CH2

PA2,PH12

CH3

PA3,PI0

通用(L1)
(2通道)

定时器8

复用AF3
倍频2

CH0

PA2,PE5

向上

CH1

PA3,PE6

定时器11

复用AF9
倍频4

CH0

PB14,PH6

向上

CH1

PB15,PH7

通用(L2)
(1通道)

定时器9

复用AF3
倍频2

CH0

PB8,PF6

向上

定时器10

复用AF3
倍频2

CH0

PB9,PF7

向上

定时器12

复用AF9
倍频4

CH0

PA6,PF8

向上

定时器13

复用AF9
倍频4

CH0

PA7,PF9

向上

基本
(0通道)

定时器5

倍频4

NONE

向上

定时器6

倍频4

向上

GD32F4 DMA功能查询

DMA0

DMA1

GD32F4的I2C查询

SCL

SDA

TXFRAME

SMBA

PB6,PB8

PB7,PB9

PB4

PB5

PB10,PF1,PH4

PF0,PH5,PB11,PC12,PB3

PF3,PH3,PB13

PF2,PH6,PB12

PA8,PH7

PH8,PC9,PB4

PA10,PH10

PA9,PH9

GD32F4之ADC查询

  

通道

ADC0

ADC1

ADC2

外部通道
(16路)

IN0

PA0

PA0

PA0

IN1

PA1

PA1

PA1

IN2

PA2

PA2

PA2

IN3

PA3

PA3

PA3

IN4

PA4

PA4

PF6

IN5

PA5

PA5

PF7

IN6

PA6

PA6

PF8

IN7

PA7

PA7

PF9

IN8

PB0

PB0

PF10

IN9

PB1

PB1

PF3

IN10

PC0

PC0

PC0

IN11

PC1

PC1

PC1

IN12

PC2

PC2

PC2

IN13

PC3

PC3

PC3

IN14

PC4

PC4

PF4

IN15

PC5

PC5

PF5

内部通道
(2路)

IN16

温度

IN17

Vref

电池电压通道

IN18

VBAT

GD32F4之SPI查询

MOSI

MISO

SCK

NSS

SPI0

PA7

PA6

PA5

PA4

PB5

PB4

PB3

PA15

SPI1

PB15

PB14

PA9

PB9

PC1

PC2

PB10

PB12

PC3

PI2

PB13

PD1

PI3

PC7

PI0

PD3

PI1

SPI2

PB0

PB4

PB3

PA4

PB2

PC11

PC10

PA15

PB5

PC1

PC12

PD0

PD6

SPI3

PA1

PA11

PB13

PB12

PE6

PD0

PE2

PE4

PE14

PE5

PE12

PE11

PG13

PE13

PG11

PG14

PG12

SPI4

PA10

PA12

PB0

PB1

PB8

PE13

PE12

PE11

PE14

PF8

PF7

PF6

PF9

PH7

PH6

PH5

PF11

SPI5

PG14

PG12

PG13

PG8

SPI5_IO2: PG10

SPI5_IO3: PG11

独立看门狗


#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>
#include "main.h"
#include "Usart0.h"


void Usart0_on_recv(uint8_t* data, uint32_t len) {
    printf("recv: %s\r\n", data);
}

static void wtd_config() {
    fwdgt_config(2 * 500, FWDGT_PSC_DIV64);
    fwdgt_enable();
}

int main(void)
{
    systick_config();
    Usart0_init();

    wtd_config();

    printf("start\r\n");
    while(1) {

        delay_1ms(960);
        /* reed dog */
        fwdgt_counter_reload();
    }
}

窗口看门狗


#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>
#include "main.h"
#include "Usart0.h"

void Usart0_on_recv(uint8_t* data, uint32_t len) {
    printf("recv: %s\r\n", data);
}

static void wtd_config() {
    rcu_periph_clock_enable(RCU_WWDGT);
    /*
     *  System clock up to 240Mhz, PCLK1=60MHz 
     *  set WWDGT clock = (PCLK1 (60MHz)/4096)/4 = 3662Hz (~273 us)   
     *  set counter value to 127
     *  set window value to 80
     *  refresh window is: ~273 * (127-80)= 5.9ms < refresh window < ~273 * (127-0x3F) =17.5ms.
     */
    wwdgt_config(127, 80, WWDGT_CFG_PSC_DIV4);
    wwdgt_enable();
}

int main(void)
{
    systick_config();
    Usart0_init();

    wtd_config();

    printf("start\r\n");
    while(1) {
        delay_1ms(13);
        /* update WWDGT counter */
        wwdgt_counter_update(127);
    }
}

  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值