翱翔云端的鸟 发表于 2017-6-9 15:35:19

GD32F450--GPIO/UART/TIMER/NVIC

由于之前一直没时间,最近才拿到开始玩,搭建环境不多说了,前面很多人已经弄过了。

参考了官方的Firmware Library重新建立了自己的工程



如图,官方标准驱动库太长没有展开,BSP是我自己写的驱动文件 共包含 GPIO/UART/TIME/NVIC

1.GPIO
bsp_gpio.h   /******************************************************************************
* File       : bsp_gpio.h
* Function   : IO初始化
* Description: None         
* Version    : V1.00
* Author   : WXP
* Date       :
* History    :
*        No.                                        |Date                                                |Author                                        |Description
        1                                        |2017-4-21                                        |WXP                                        |IO初始化
******************************************************************************/
#ifndef __BSP_GPIO_H__
#define __BSP_GPIO_H__

#ifdef __cplusplus
extern "C" {
#endif
       
#include "gd32f4xx.h"
       
#define ON (1)
#define OFF (0)
       
/*
* LED4--PB4
* LED6--PB3
* LED5--PD7
*/       

#define LED4(a)                        if(a)        gpio_bit_set(GPIOB,GPIO_PIN_4); \
                                                                        else                gpio_bit_reset(GPIOB,GPIO_PIN_4);
       
#define LED5(a)                        if(a)        gpio_bit_set(GPIOD,GPIO_PIN_7); \
                                                                        else                gpio_bit_reset(GPIOD,GPIO_PIN_7);

#define LED6(a)                        if(a)        gpio_bit_set(GPIOB,GPIO_PIN_3); \
                                                                        else                gpio_bit_reset(GPIOB,GPIO_PIN_3);

#define LED4_Toggle()                gpio_bit_toggle(GPIOB,GPIO_PIN_4)
#define LED5_Toggle()                gpio_bit_toggle(GPIOD,GPIO_PIN_7)
#define LED6_Toggle()                gpio_bit_toggle(GPIOB,GPIO_PIN_3)

void bsp_led_init(void);//LED初始化       
       
#ifdef __cplusplus
}
#endif
       
#endif       
               

bsp_gpio.c#include "bsp_gpio.h"


/*
* LED4--PB4
* LED6--PB3
* LED5--PD7
*/       


/******************************************************************************
* Name       : void bsp_led_init(void)
* Function   : LED初始化
* Input      : None
* Output:    : None
* Return   : None
* Version    : V1.00
* Author   : WXP
* Date       :
* Description:
******************************************************************************/
void bsp_led_init(void)
{

    rcu_periph_clock_enable(RCU_GPIOB);
        rcu_periph_clock_enable(RCU_GPIOD);

    gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,GPIO_PIN_4);//设为输出
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_4);//推挽
       
        gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,GPIO_PIN_3);//设为输出
    gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_3);//推挽
       
        gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,GPIO_PIN_7);//设为输出
    gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_7);//推挽
       
       
    gpio_bit_reset(GPIOB,GPIO_PIN_4);//输出低电平 灭
        gpio_bit_reset(GPIOB,GPIO_PIN_3);//输出低电平 灭
        gpio_bit_reset(GPIOD,GPIO_PIN_7);//输出低电平 灭
}
GPIO中只有简单的控制3个LED等
PB4--LED4
PD7--LED5
PB3--LED6



2.UART
bsp_uart.h/******************************************************************************
* File       : bsp_usart.h
* Function   : ′??ú?y?ˉí·???t
* Description: None         
* Version    : V1.00
* Author   : WXP
* Date       :
* History    :
*        No.                                        |Date                                                |Author                                        |Description
        1                                        |2017-4-21                                        |WXP                                        |3?′?′′?¨
******************************************************************************/
#ifndef __BSP_USART_H__
#define __BSP_USART_H__

#ifdef __cplusplus
extern "C" {
#endif
       

#include "gd32f4xx.h"
#include "stdio.h"
#include "systick.h"
       
       
#define DEBUG_UART USART2       
       

/*
* USART0   PA9--TXD   PA10--RXD
* USART1   PA2--TXD   PA3---RXD
* USART2   PB10-TXD   PB11--RXD   PD8--TXD   PD9--RXD
* UART3    PC10-TXD   PC11--RXD
* UART4           PC12-TXD   PD2---RXD
* USART5   PC6--TXD   PC7---RXD       
*/       
       
void USART0_Init(uint32_t baud);//用作modbus-485
void USART2_Init(uint32_t baud);//printf       
       




#ifdef __cplusplus
}
#endif
       
#endif       
               

bsp_uart.c#include "bsp_uart.h"


/*
* USART0   PA9--TXD   PA10--RXD
* USART1   PA2--TXD   PA3---RXD
* USART2   PB10-TXD   PB11--RXD   PD8--TXD   PD9--RXD
* UART3    PC10-TXD   PC11--RXD
* UART4           PC12-TXD   PD2---RXD
* USART5   PC6--TXD   PC7---RXD       
*/       


/******************************************************************************
* Name       : void USART0_Init(uint32_t)
* Function   : USART0初始化
* Input      : None
* Output:    : None
* Return   : None
* Version    : V1.00
* Author   : WXP
* Date       :
* Description:
* USART0   PA9--TXD   PA10--RXD
* USART_INTEN_PERRIE: 校验错误中断
* USART_INTEN_TBEIE:发送缓冲区空中断
* USART_INTEN_TCIE:   发送完成中断
* USART_INTEN_RBNEIE: 读接受缓冲区非空或溢出中断
* USART_INTEN_RTIE:   接收超时中断
******************************************************************************/
void USART0_Init(uint32_t baud)
{
        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_50MHZ,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_50MHZ,GPIO_PIN_10);
       
        usart_deinit(USART0);
        usart_baudrate_set(USART0,baud);       
        usart_receive_config(USART0,USART_RECEIVE_ENABLE);
        usart_transmit_config(USART0,USART_TRANSMIT_ENABLE);
        usart_interrupt_enable(USART0,USART_INTEN_RBNEIE);//使能接受中断(读接受缓冲区非空)
        usart_interrupt_disable(USART0,USART_INTEN_TBEIE);//禁止发送缓冲区空中断
        usart_enable(USART0);
}       




/******************************************************************************
* Name       : void USART2_Init(uint32_t)
* Function   : USART2初始化
* Input      : None
* Output:    : None
* Return   : None
* Version    : V1.00
* Author   : WXP
* Date       :
* Description:
* USART0   PD8--TXD   PD9--RXD
* USART_INTEN_PERRIE: 校验错误中断
* USART_INTEN_TBEIE:发送缓冲区空中断
* USART_INTEN_TCIE:   发送完成中断
* USART_INTEN_RBNEIE: 读接受缓冲区非空或溢出中断
* USART_INTEN_RTIE:   接收超时中断
******************************************************************************/
void USART2_Init(uint32_t baud)
{
        rcu_periph_clock_enable(RCU_GPIOD);
        rcu_periph_clock_enable(RCU_USART2);
       
        gpio_af_set(GPIOD,GPIO_AF_7,GPIO_PIN_8);//GPIO_AF_7: USART0, USART1, USART2
        gpio_af_set(GPIOD,GPIO_AF_7,GPIO_PIN_9);
       
        gpio_mode_set(GPIOD,GPIO_MODE_AF,GPIO_PUPD_PULLUP,GPIO_PIN_8);
        gpio_output_options_set(GPIOD,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_8);
       
        gpio_mode_set(GPIOD,GPIO_MODE_AF,GPIO_PUPD_PULLUP,GPIO_PIN_9);
        gpio_output_options_set(GPIOD,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_9);
       
        usart_deinit(USART2);
        usart_baudrate_set(USART2,baud);       
        usart_receive_config(USART2,USART_RECEIVE_ENABLE);
        usart_transmit_config(USART2,USART_TRANSMIT_ENABLE);
        usart_interrupt_enable(USART2,USART_INTEN_RBNEIE);//使能接受中断(读接受缓冲区非空)
        usart_interrupt_disable(USART2,USART_INTEN_TBEIE);//禁止发送缓冲区空中断
        usart_enable(USART2);
}       
       

int fputc(int ch, FILE *f)
{
        usart_data_transmit(DEBUG_UART,(uint8_t)ch);
        while(RESET == usart_flag_get(DEBUG_UART,USART_FLAG_TBE));//等待发送完成
        return ch;
       
}
这里用了两个uart,一个用作debug(printf),一个预备当做modbus-485接口


3.TIMER
bsp_time.h/******************************************************************************
* File       : bsp_time.h
* Function   : 定时器驱动头文件
* Description: 包含全部的BSP驱动         
* Version    : V1.00
* Author   : WXP
* Date       :
* History    :
*        No.                                        |Date                                                |Author                                        |Description
        1                                        |2017-4-26                                        |WXP                                        |初次创建
******************************************************************************/
#ifndef __BSP_TIME_H__
#define __BSP_TIME_H__

#ifdef __cplusplus
extern "C" {
#endif


#include "gd32f4xx.h"

/*
TIM0/TIM7                                   高级定时器
TIM1/TIM2/TIM3/TI***                       通用定时器L0
TIM8/TIM11                                        通用定时器L1
TIM9/TIM10/TIM12/TIM13          通用定时器L2
TIM5/TIM6                                        基本定时器
       
定时器                TIM0/7                TIM1-4                TIM8/11                TIM9-13                TIM5/6
类型                高级                通用(L0)        通用(L1)        通用(L2)        基本
预分频器        16位                16位                16位                16位                16位
计时器                16位                16位(2/3)        16位                16位                16位
                                                32位(1/4)
计数模式        向上                向上                向上                向上                向上
                        向下                向下
                        中央对齐        中央对齐
捕获/比较        4                        4                        2                        1                        0
可重复性        Y                        N                        N                        N                        N
互补死区        Y                        N                        N                        N                        N
中止输入        Y                        N                        N                        N                        N
单脉冲                Y                        Y                        Y                        N                        Y
正交解码        Y                        Y                        N                        N                        N
从设备控制        Y                        Y                        Y                        N                        N
*/       
       
       
       
void TIM6_Init(uint16_t arr,uint16_t psc);
       

#ifdef __cplusplus
}
#endif       
       
#endif       
bsp_time.c/******************************************************************************
* File       : bsp_time.c
* Function   : 定时器驱动源文件
* Description: None         
* Version    : V1.00
* Author   : WXP
* Date       :
* History    :
*        No.                                        |Date                                                |Author                                        |Description
        1                                        |2017-4-26                                        |WXP                                        |初次创建
******************************************************************************/

#include "bsp_time.h"
#include "bsp_nvic.h"
#include "bsp_uart.h"
#include "bsp_gpio.h"




/******************************************************************************
* Name       : void TIM6_Init(uint16_t arr,uint16_t psc)
* Function   : 定时器6初始化
* Input      : u16 arr 重装载值   psc预分频值
* Output:    : None
* Return   : None
* Version    : V1.00
* Author   : WXP
* Date       : 2017-6-9
* Description: T=(((arr+1)/120000000)/psc)秒
******************************************************************************/
void TIM6_Init(uint16_t arr,uint16_t psc)
{
        timer_parameter_struct timer_initpara;
       
        rcu_periph_clock_enable(RCU_TIMER6);
       
        rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);
       
        timer_deinit(TIMER6);
       
        timer_initpara.prescaler = psc;//预分频值120M/(11999+1)=0.01M
        timer_initpara.alignedmode         = TIMER_COUNTER_EDGE;//TIMER_COUNTER_CENTER_UP
        timer_initpara.counterdirection = TIMER_COUNTER_UP;
        timer_initpara.period = arr;//1M/(9999+1)=10000 10000/0.01M=1s中断一次
        timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
        timer_initpara.repetitioncounter = 0;
        timer_init(TIMER6,&timer_initpara);
       
        timer_auto_reload_shadow_enable(TIMER6);//使能预装载
        timer_flag_clear(TIMER6,TIMER_FLAG_UP);//清除更新标志位
        timer_interrupt_enable(TIMER6,TIMER_INT_UP);//使能更新中断
        timer_enable(TIMER6);
       
}


void TIMER6_IRQHandler(void)
{
        if(RESET != timer_interrupt_flag_get(TIMER6,TIMER_INT_UP))
        {
                printf("TIM6 Runing\r\n");
                LED4_Toggle();
                timer_interrupt_flag_clear(TIMER6,TIMER_INT_UP);
        }
}

这里只简单的用了一个基本定时器TIMER6,1S打印1句话,然后翻转LED4



4.NVIC
bsp_nvic.h/******************************************************************************
* File       : bsp_nvic.h
* Function   : 中断配置头文件
* Description: None         
* Version    : V1.00
* Author   : WXP
* Date       :
* History    :
*        No.                                        |Date                                                |Author                                        |Description
        1                                        |2017-4-26                                        |WXP                                        |初次创建
******************************************************************************/
#ifndef __BSP_NVIC_H__
#define __BSP_NVIC_H__

#ifdef __cplusplus
extern "C" {
#endif
       
#include "gd32f4xx.h"


void NVIC_Config(void);                       
       
       
#ifdef __cplusplus
}
#endif
       
#endif       
bsp_nvic.c/******************************************************************************
* File       : bsp_nvic.h
* Function   : 中断配置源文件
* Description: None         
* Version    : V1.00
* Author   : WXP
* Date       :
* History    :
*        No.                                        |Date                                                |Author                                        |Description
        1                                        |2017-4-21                                        |WXP                                        |初次创建
******************************************************************************/
#include "bsp_nvic.h"
/*
中断分配说明,优先级由高向低排
顺序       类型            作用                   抢占优先级      响应优先级

*/



void NVIC_Config(void)
{

        /* 配置中断使用组合抢占式3位(0-7),响应式1位(0-1) */
        nvic_priority_group_set(NVIC_PRIGROUP_PRE3_SUB1);
       

        nvic_irq_enable(USART0_IRQn,1,1);

        nvic_irq_enable(TIMER6_IRQn,2,1);

        nvic_irq_enable(USART2_IRQn,3,1);
}

nvic用来分配中断优先级

5.bsp#include "bsp.h"


/******************************************************************************
* Name       : void Bsp_Init(void)
* Function   : BSP初始化
* Input      : None
* Output:    : None
* Return   : None
* Version    : V1.00
* Author   : WXP
* Date       :
* Description:
******************************************************************************/
void Bsp_Init(void)
{
        NVIC_Config();                                //中断初始化分配优先级
       
        systick_config();                        //SYSTICK 初始化
       
        bsp_led_init();                                //LED初始化
       
        USART0_Init(115200);                //UART0初始化PA9--TXDPA10--RXD

        USART2_Init(115200);                //USART2初始化 PD8--TXDPD9--RXDDEBUG_UART
       
        TIM6_Init(9999,11999);                //TIMER6初始化   1S中断一次
       
}
       
最后main函数如下#include "gd32f4xx.h"
#include "gd32f4xx_eval.h"
#include "bsp.h"




int main(void)
{

        Bsp_Init();
       
        printf("This is a GD32F450 demo\n");

    while(1)
        {
                LED5_Toggle();
                delay_1ms(300);   
        }
}
运行的效果就是LED4每一秒闪烁一次,LED5每300ms闪烁一次,然后每一秒打印一句话



最后上传我的Demo







jinglixixi 发表于 2017-6-12 11:42:37

感谢分享!
页: [1]
查看完整版本: GD32F450--GPIO/UART/TIMER/NVIC