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
感谢分享!
页:
[1]