兆易创新GD32f103使用介绍

  • 用GD32的理由
    • 1. 获取资源
    • 2. 创建自己的例程
    • 3. 日志输出
    • 4. 串口

用GD32的理由

GD32和STM32差别不大,如果非要说差别,那大概就是成本了,兆易创新GD32 价格相对于STM32是很便宜的了,而且随着这些年缺芯的影响,再叠加国产化潮流,各类公司都在逐步的替代STM32。接下来我就大概介绍一下我从头开始学习和使用GD32103的过程,如有不足,本人正在学习中。

1. 获取资源

大部分资源都可以从兆易创新官网(http://gd32mcu.com/cn/download)获取,包括固件库、例程以及各类文档:
1.GD32F10x_Demo_Suites_V2.1.0:该文件包含了keil和IAR的固件库、库文件和例程;
2.GD32F10x_Firmware_Library_V2.2.1:该文件包含库文件和例程。

2. 创建自己的例程

直接以官方最基础的打印例程为基础,在此之上进行修改。

3. 日志输出

保留原打印输出函数;增加部分函数 代码如下.

/*!\brief      printf the char and the hex\param[in]  p_title: the char\param[in]  p_mem: the hex\param[in]  size: the size of the hex\param[out] none\retval     none
*/
void mem_printf(const char* p_title, const char* p_mem, int size)
{int i = 0;if (!size) {return;}if ((int)p_mem < 0x20000000) {ERROR_LOG("0x%x is not memory addr.\n", (uint32_t)p_mem);return;}if (p_title) {printf("%s", p_title);}for (; i < size; i++) {printf("%02x ", p_mem[i]);}printf("\n");
}/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{usart_data_transmit(EVAL_COM0, (uint8_t)ch);while (RESET == usart_flag_get(EVAL_COM0, USART_FLAG_TBE));return ch;
}

在.h文件中加入日志错误位置输出函数:

#define ERROR_LOG(fmt, args...)    \do {    \printf("func %s line %d err: ",__func__, __LINE__);      \printf(fmt, ##args);    \} while (0)

4. 串口

GD的串口序号是总0开始的,在本例程中,日志打印占用的串口是USART0。为了便于移植和调用,本文尽可能的进行了API封装,新建了drv_usart.c和drv_usart.h的文件。
1.drv_usart.c内容:

/*!\file    drv_usart.c\brief   firmware functions to manage usart ports\author  Kangkang\version 2021-12-15, V1.0.0
*/#include <stdio.h>
#include "gd32f10x_eval.h"
#include "common_conf.h"
#include "drv_usart.h"/* USART0 parameter definitions */
uint8_t txbufferusart0[] = "\n\rUSART interrupt test\n\r";
uint8_t rxbufferusart0[USART_BUFFER_MAXSIZE] = {0};
uint16_t tx_sizeusart0 = TRANSMIT_SIZE;
uint16_t rx_sizeusart0 = USART_BUFFER_MAXSIZE;
__IO uint16_t txcountusart0 = 0;
__IO uint16_t rxcountusart0 = 0;
uint8_t usart0_receive_flag = 0;
/* USART1 parameter definitions */
uint8_t txbufferusart1[] = "\n\rUSART interrupt test\n\r";
uint8_t rxbufferusart1[USART_BUFFER_MAXSIZE] = {0};
uint16_t tx_sizeusart1 = TRANSMIT_SIZE;
uint16_t rx_sizeusart1 = USART_BUFFER_MAXSIZE;
__IO uint16_t txcountusart1 = 0;
__IO uint16_t rxcountusart1 = 0;
uint8_t usart1_receive_flag = 0;
/* USART2 parameter definitions */
uint8_t txbufferusart2[] = "\n\rUSART interrupt test\n\r";
uint8_t rxbufferusart2[USART_BUFFER_MAXSIZE] = {0};
uint16_t tx_sizeusart2 = TRANSMIT_SIZE;
uint16_t rx_sizeusart2 = USART_BUFFER_MAXSIZE;
__IO uint16_t txcountusart2 = 0;
__IO uint16_t rxcountusart2 = 0;
uint8_t usart2_receive_flag = 0;
/* private variables *//*!\brief      send char by the USARTx\param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)\param[in]  data_len: length of data\param[in]  data_buf: data of transmission\param[out] none\retval     none
*/
void USARTDataSend(uint32_t usart_periph, const void* data_buf, uint16_t data_len)
{uint8_t* buf_pos = (uint8_t*)data_buf;uint16_t len_size = data_len;while (len_size > 0){usart_data_transmit(usart_periph, *buf_pos);while (RESET == usart_flag_get(usart_periph, USART_FLAG_TBE));buf_pos += 1;len_size -=1;}
}/*!\brief      receive char by the USARTx\param[in]  usart_periph: USARTx(x=0,1,2)/UARTx(x=3,4)\param[in]  data_len: data of transmission\param[out] data_buf: receiving data\retval     none
*/
uint16_t USARTDataReceive(uint32_t usart_periph, const void* data_buf, uint16_t data_len)
{uint16_t rxcount = 0;uint8_t* buf_pos = (uint8_t*)data_buf;switch (usart_periph){case USART0 :if (usart0_receive_flag > 0){for (; rxcount < rxcountusart0; rxcount ++){if(rxcount >= data_len){break;}buf_pos[rxcount] = rxbufferusart0[rxcount];}usart0_receive_flag = 0;rxcountusart0 = 0;}break;case USART1 :if (usart1_receive_flag > 0){for (; rxcount < rxcountusart1; rxcount ++){if(rxcount >= data_len){break;}buf_pos[rxcount] = rxbufferusart1[rxcount];}usart1_receive_flag = 0;rxcountusart1 = 0;}break;case USART2 :if (usart2_receive_flag > 0){for (; rxcount < rxcountusart2; rxcount ++){if(rxcount >= data_len){break;}buf_pos[rxcount] = rxbufferusart2[rxcount];}usart2_receive_flag = 0;rxcountusart2 = 0;}break;default:break;}return rxcount;
}
/*!\brief      configure USART0\param[in]  none\param[out] none\retval     none
*/
void ConfigUSART0(void)
{/* USART interrupt configuration */nvic_irq_enable(USART0_IRQn, 0, 0);/* configure COM0 */gd_eval_com_init(EVAL_COM0);/* enable USART TBE interrupt */
//    usart_interrupt_enable(USART0, USART_INT_TBE);/* enable USART RBNE interrupt */usart_interrupt_enable(USART0, USART_INT_RBNE);/* enable USART IDLE interrupt */usart_interrupt_enable(USART0, USART_INT_IDLE);
}
/*!\brief      configure USART1\param[in]  none\param[out] none\retval     none
*/
void ConfigUSART1(void)
{/* USART interrupt configuration */nvic_irq_enable(USART1_IRQn, 0, 0);/* configure USART1 */gd_eval_com_init(EVAL_COM1);/* enable USART TBE interrupt */
//    usart_interrupt_enable(USART1, USART_INT_TBE);/* enable USART RBNE interrupt */usart_interrupt_enable(USART1, USART_INT_RBNE);/* enable USART IDLE interrupt */usart_interrupt_enable(USART1, USART_INT_IDLE);
}
/*!\brief      configure USART2\param[in]  none\param[out] none\retval     none
*/
void ConfigUSART2(void)
{/* USART interrupt configuration */nvic_irq_enable(USART2_IRQn, 0, 0);/* configure USART2 */gd_eval_com_init(USART2);/* enable USART TBE interrupt */
//    usart_interrupt_enable(USART2, USART_INT_TBE);/* enable USART RBNE interrupt */usart_interrupt_enable(USART2, USART_INT_RBNE);/* enable USART IDLE interrupt */usart_interrupt_enable(USART2, USART_INT_IDLE);
}

2.drv_usart.h内容:

/*!\file    drv_usart.h\brief   definitions for usart resources
*/#ifndef DRV_USART_H
#define DRV_USART_H#ifdef cplusplusextern "C" {#endif#include "common_conf.h"/* buffer size definitions */
#define USART_BUFFER_MAXSIZE 1024
#define ARRAYNUM(arr_nanme)      (uint32_t)(sizeof(arr_nanme) / sizeof(*(arr_nanme)))
#define TRANSMIT_SIZE            (ARRAYNUM(txbufferusart0) - 1)/* USART0 count definitions */
extern uint8_t txbufferusart0[];
extern uint8_t rxbufferusart0[USART_BUFFER_MAXSIZE];
extern uint16_t tx_sizeusart0;
extern uint16_t rx_sizeusart0;
extern __IO uint16_t txcountusart0;
extern __IO uint16_t rxcountusart0;
extern uint8_t usart0_receive_flag;
/* USART1 count definitions */
extern uint8_t txbufferusart1[];
extern uint8_t rxbufferusart1[USART_BUFFER_MAXSIZE];
extern uint16_t tx_sizeusart1;
extern uint16_t rx_sizeusart1;
extern __IO uint16_t txcountusart1;
extern __IO uint16_t rxcountusart1;
extern uint8_t usart1_receive_flag;
/* USART2 count definitions */
extern uint8_t txbufferusart2[];
extern uint8_t rxbufferusart2[USART_BUFFER_MAXSIZE];
extern uint16_t tx_sizeusart2;
extern uint16_t rx_sizeusart2;
extern __IO uint16_t txcountusart2;
extern __IO uint16_t rxcountusart2;
extern uint8_t usart2_receive_flag;
/* exported types *//* function declarations */
/* configure USART0 */
void ConfigUSART0(void);
/* configure USART1 */
void ConfigUSART1(void);
/* configure USART2 */
void ConfigUSART2(void);
/* USART data send */
void USARTDataSend(uint32_t usart_periph, const void* data_buf, uint16_t data_len);
/* USART data receive */
uint16_t USARTDataReceive(uint32_t usart_periph, const void* data_buf, uint16_t data_len);
#ifdef cplusplus
}
#endif#endif /* DRV_USART_H */

3.gd32f10x_it.c中需要添加3个串口的中断函数:

/*!\brief      this function handles USART RBNE interrupt request and TBE interrupt request\param[in]  none\param[out] none\retval     none
*/
void USART0_IRQHandler(void)
{if(RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)){/* clear interrupt RBNE flag */usart_interrupt_flag_clear(USART0, USART_INT_FLAG_RBNE);/* receive data */rxbufferusart0[rxcountusart0++] = (uint8_t)usart_data_receive(USART0);if (rxcountusart0 > USART_BUFFER_MAXSIZE){rxcountusart0 = 0;}}if(RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_TBE)){/* transmit data */usart_data_transmit(USART0, txbufferusart0[txcountusart0++]);if(txcountusart0 == tx_sizeusart0){usart_interrupt_disable(USART0, USART_INT_TBE);}}if(RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_IDLE)){/* clear interrupt IDLE flag */usart_interrupt_flag_clear(USART0, USART_INT_FLAG_IDLE);usart_data_receive(USART0);if (rxcountusart0 > 0){usart0_receive_flag = 1;}}
}
void USART1_IRQHandler(void)
{if(RESET != usart_interrupt_flag_get(USART1, USART_INT_FLAG_RBNE)){/* clear interrupt RBNE flag */usart_interrupt_flag_clear(USART1, USART_INT_FLAG_RBNE);/* receive data */rxbufferusart1[rxcountusart1++] = (uint8_t)usart_data_receive(USART1);if (rxcountusart1 > USART_BUFFER_MAXSIZE){rxcountusart1 = 0;}}if(RESET != usart_interrupt_flag_get(USART1, USART_INT_FLAG_TBE)){/* transmit data */usart_data_transmit(USART1, txbufferusart1[txcountusart1++]);if(txcountusart1 == tx_sizeusart1){usart_interrupt_disable(USART1, USART_INT_TBE);}}if(RESET != usart_interrupt_flag_get(USART1, USART_INT_FLAG_IDLE)){/* clear interrupt IDLE flag */usart_interrupt_flag_clear(USART1, USART_INT_FLAG_IDLE);usart_data_receive(USART1);if (rxcountusart1 > 0){usart1_receive_flag = 1;}}
}
void USART2_IRQHandler(void)
{if(RESET != usart_interrupt_flag_get(USART2, USART_INT_FLAG_RBNE)){/* clear interrupt RBNE flag */usart_interrupt_flag_clear(USART2, USART_INT_FLAG_RBNE);/* receive data */rxbufferusart2[rxcountusart2++] = (uint8_t)usart_data_receive(USART2);if (rxcountusart2 > USART_BUFFER_MAXSIZE){rxcountusart2 = 0;}}if(RESET != usart_interrupt_flag_get(USART2, USART_INT_FLAG_TBE)){/* transmit data */usart_data_transmit(USART2, txbufferusart2[txcountusart2++]);if(txcountusart2 == tx_sizeusart2){usart_interrupt_disable(USART2, USART_INT_TBE);}}if(RESET != usart_interrupt_flag_get(USART2, USART_INT_FLAG_IDLE)){/* clear interrupt IDLE flag */usart_interrupt_flag_clear(USART2, USART_INT_FLAG_IDLE);usart_data_receive(USART2);if (rxcountusart2 > 0){usart2_receive_flag = 1;}}
}

别忘了在h文件中添加函数声明。

GD32f103介绍第二章

后续文字将陆续发布!谢谢阅读!多多关照!ps:例程会在介绍完成后发布

GD32f103介绍第一章相关推荐

  1. scratch3.0 二次开发-基本介绍(第一章)

    scratch3.0系列章节列表 scratch3.0 二次开发-基本介绍(第一章) scratch3.0二次开发运行scratch-gui项目并了解工程结构(第二章) scratch3.0二次自定义 ...

  2. tkinter窗口美化功能介绍 第一章 内部美化功能

    今天我教大家做tkinter窗口美化 第一章 · tkinter内部美化功能 窗口透明化 窗口居中 窗口最大最小化 删除窗口标题栏 窗口大小调整的设置 1.窗口透明化 可以通过调整第二个值来设置透明度 ...

  3. Spring框架介绍——第一章

    文章目录 1: Spring的进化 2:Spring的功能 3:Spring模块介绍 在所有的框架体系中,Spring 框架是其中最明亮的一颗星星.Spring框架在Java的发展过程中是不可或缺的, ...

  4. Drupal的介绍----第一章:Drupal的介绍

    本章提供一个什么样的内容管理系统(CMS)是一个基本的概述,Drupal的如何填充作为一个CMS,Drupal的主要组成部分,以及如何作用,创建新的Drupal的网站内容. 内容管理系统 在最简单的形 ...

  5. 《Linux From Scratch》第一部分:介绍 第一章:介绍-1.3. 更新日志

    这是 Linux From Scratch 手册的 7.7-systemd 版本,发布于2015年3月6日.如果距离这个时间已超过 6 个月,那么应该已经有更新和更好的版本了.要获取的话,请访问这个页 ...

  6. 《Linux From Scratch》第一部分:介绍 第一章:介绍- 1.4. 资源

    1.4.1. FAQ 如果在构建 LFS 系统的过程中遇到任何错误,有任何的疑问,或者认为书中存在拼写错误,请先看一下常见问题列表(FAQ) http://www.linuxfromscratch.o ...

  7. SSVEP介绍|第一章 SSVEP的基础应用系统|第二节 SSVEP的信号处理过程(1)

    摘要-- 这一节主要讲解SSVEP的去噪和滤波过程,众所周知,对于一个信号来说,噪声和滤波过程直接决定了信号的可用性.特别是对BCI信号来说,由于脑电信号比较微弱,干扰较大,所以其去噪和滤波的好坏直接 ...

  8. py2neo 创建关系_py2neo详细介绍第一章

    1.1 节点和关系的对象 官网的例子,创建两个节点,并为两个节点创建关系. from py2neo.data import Node, Relationship a = Node("Pers ...

  9. 翁刚c语言,1第一章C语言入门.ppt

    1第一章C语言入门 C 程 序 设 计 | 第 一 章 1.1 C语言入门 第一章 蔼专淬泉寄谚燕娃瓶彪假接又室睁撰炒郸芝载估扳笺安寝屉匡厩翁刚暴镀1第一章C语言入门C语言程序入门 C 程 序 设 计 ...

  10. 统计遗传学:第一章,基因组基础概念

    1. 基因组基础概念 大家好,我是飞哥. 前几天推荐了这本书,可以领取pdf和配套数据代码.这里,我将各个章节介绍一下,总结也是学习的过程. 引文部分是原书的谷歌翻译,正文部分是我的理解. 这本书共有 ...

最新文章

  1. linux开启ftp
  2. opencv + python3 利用ros 的 cv_bridge 传送图像消息的一种替代方法
  3. java stringbuilder appendline_StringBuilder
  4. 摇杆控制方向原理_为工业安全守好”门”!各种方向的控制阀原理图大集合
  5. windows 下的文件对比工具
  6. 从开源自治到微服务云化,用这剂良药提升微服务幸福感
  7. RTL8211E应用(二)之信号输入、输出接口
  8. php电影模板下载,【PHP源码】团啊VIP电影系统V3.7.6源码下载 带自动采集+手机版模板...
  9. 数据结构与算法概念与理解
  10. 群晖linux怎么进入u盘,超级简单,群晖系统的U盘制作和安装指导,实现家庭云...
  11. 小程序获取微信登陆用户
  12. jQuery插件库免下载做法
  13. chrome的APP模式与全屏模式 --app --kiosk
  14. Java锁Synchronized对象锁和类锁区别(搬运)
  15. python画饼图程序_Scribus中的Python脚本:制作饼图
  16. y160.第九章 GitOps从入门到精通 -- Tekton Trigger(九)
  17. Python 中File(文件) 方法?
  18. mybatis中 查询两张表,结果如果用resultMap接收,当两张表字段有重复的时候,如果不对字段加以区分,resultMap出来的值是空的
  19. DotCode二维码基本概念
  20. 使用Windows Live Calendar 订阅“2010南非世界杯赛程”

热门文章

  1. Flash builder 4.6 下载 破解 序列号【你懂的】
  2. 高等代数期末考试题库及答案_高等代数Ⅱ答案期末答案
  3. Docker中部署.NET CORE应用(控制台应用程序篇)
  4. 全国省市区三级JSON 包括地区编码
  5. day53_电力系统_ztree动态生成权限控制
  6. ping C语言实现
  7. 多款免费可商用的微信小程序开源源码推荐(商城类)
  8. 干货流出|腾讯内部几近满分的项目管理课程PPT
  9. 国产操作系统中标麒麟v6
  10. 科技文献检索(十三)——特种文献的检索与利用