小熊派GD32开发(2)— 第一个Hello world程序
一、硬件连接
通过查看原理图我们可以看到,当【UART通信选择开关】拨向【AT-MCU】时,USB虚拟串口连接到MCU的UART0,我们只需要将开关拨到【AT-MCU】。
二、编写USART驱动程序
在上一个工程:小熊派GD32开发(1)— 开发环境的搭建及点亮第一个LED灯的基础上,新增Devices
文件夹,并添加usart.c
和usart.h
两个文件。
在usart.h
定义一个串口初始化函数:
#ifndef __USART_H
#define __USART_H
#include <stdio.h>
#include "gd32f30x.h"
/* 串口初始化,参数为波特率 */
void uart_init(uint32_t bound);
#endif
然后我们在usart.c
中实现串口初始化函数
/* USART0串口初始化函数
* 参数:波特率
* 返回值:无 */
void uart_init(uint32_t bound)
{
/* 使能 GPIOA 时钟 */
rcu_periph_clock_enable(RCU_GPIOA);
/* 使能 USART0 时钟 */
rcu_periph_clock_enable(RCU_USART0);
/* PA9 复用为 USART0_Tx */
gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_9);
/* PA10 复用为 USARTx_Rx */
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ,GPIO_PIN_10);
/* USART0 初始化配置 */
usart_deinit(USART0);
usart_baudrate_set(USART0, bound); /* 设置波特率 */
usart_receive_config(USART0, USART_RECEIVE_DISABLE); /* 禁止接收 */
usart_transmit_config(USART0, USART_TRANSMIT_ENABLE); /* 使能发送 */
usart_enable(USART0);
}
接下来将C库的printf函数重定向到USART0
/* 加入以下代码,支持printf函数,而不需要选择use MicroLIB */
#if 1
#pragma import(__use_no_semihosting)
/* 标准库需要的支持函数 */
struct __FILE
{
int handle;
};
FILE __stdout;
/* 定义_sys_exit()以避免使用半主机模式 */
void _sys_exit(int x)
{
x = x;
}
/* 重定义fputc函数 */
int fputc(int ch, FILE *f)
{
while (RESET == usart_flag_get(USART0, USART_FLAG_TBE))
;
usart_data_transmit(USART0, (uint8_t)ch);
return ch;
}
#endif
这样`usart.c就编写好了
三、打印Hello world!
接下来我们在main.c
中添加usart.h
头文件包含,然后初始化USART0,每隔两秒中打印一次Hello world!,
#include "gd32f30x.h"
#include "systick.h"
#include "usart.h"
int main(void)
{
/* 配置系统时钟 */
systick_config();
/* 使能LED所使用的GPIOB时钟 */
rcu_periph_clock_enable(RCU_GPIOB);
/* 配置LED使用的引脚为推挽输出 */
gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0);
/* reset LED GPIO pin */
gpio_bit_reset(GPIOB, GPIO_PIN_0);
/* 初始化USART0 */
uart_init(115200);
while(1)
{
printf("Hello world! \r\n");
/* turn on LED */
gpio_bit_set(GPIOB, GPIO_PIN_0);
delay_1ms(1000);
/* turn off LED */
gpio_bit_reset(GPIOB, GPIO_PIN_0);
delay_1ms(1000);
}
}
另外,我们需要注意的时,要把usart的固件库文件添加进来:
接下来编译,烧录到开发板,在串口调试助手可以看到,成功打印Hello world!
四、优化
我们可以将有关LED的代码存放在新建的led.c
和led.h
文件中,
led.h
如下:
#ifndef __LED_H
#define __LED_H
#include "gd32f30x.h"
#define LED(n) (n?gpio_bit_set(GPIOB, GPIO_PIN_0):gpio_bit_reset(GPIOB, GPIO_PIN_0))
/* 定义LED初始化函数 */
void LED_init(void);
#endif
led.c
如下:
#include "led.h"
/* LED初始化函数 */
void LED_init()
{
/* 使能LED所使用的GPIOB时钟 */
rcu_periph_clock_enable(RCU_GPIOB);
/* 配置LED使用的引脚为推挽输出 */
gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0);
/* reset LED GPIO pin */
gpio_bit_reset(GPIOB, GPIO_PIN_0);
}
五、代码
完整代码我存放在码云,可以查看:https://gitee.com/william_william/GD32.git