系列文章目录

第一章 GD32学习笔记1(高难度工程,点亮一个LED灯)

文章目录

  • 系列文章目录
  • 前言
  • 一、工作流程
  • 二、新建工程的准备工作
  • 三、新建工程
  • 四、工程目录管理
  • 五、代码实现
    • 1、初始化
    • 2、主函数
  • 总结

GD32学习笔记1(高难度工程,点亮一个LED灯)

前言

GD系列单片机在各行各业使用的比重越来越高,因其较为便宜的价格和对标型号不输ST的性能,使得越来越多的国内企业愿意使用(比如我们公司),作为一个刚上岗的实习工程师,我打算一边学习GD32一边把所学会的东西由易至难的分享给大家,我所使用的芯片是GD32F407VE。

一、工作流程

点亮一个LED灯这种复杂工程,它有一套比较复杂的工作流程:初始化——输出。
初始化即是定义芯片输出的管脚,输出即是控制已被初始化的管脚输出低电平或高电平。

二、新建工程的准备工作

网上给出了很多用ST标准库或者HAL库来开发GD的例子,为了避免潜在的可能不适配的问题(我也不知道可能有哪些问题),最好使用兆易提供的GD32的标准库来进行开发。
打开兆易的官网,下载芯片对应的函数库,在资料下载->应用软件里面能找到这么个东西,直接下载下来然后解压。

你能获得结构如下的东西

而需要加入工程目录的只有CMSIS和GD32F4XX_standard_peripheral。
新建一个工程文件夹,将下载得到的文件夹去除GD32F4XX_usb_library后复制到你的工程文件夹中去,再在这个工程文件夹中新建一个文件夹用来存放工程,你就得到了结构如下的文件夹:

为了方便管理,我们还可以在加入一个文件夹用来存放用户自己编写的东西,如main.c,it.c等等。我们通常把存放c源文件的文件夹命名为Source或src,把存放h头文件的文件夹命名为Include或者inc(大家都是这么做的,虽然我也不知道为什么),当你获得了如下结构的文件夹之后,说明你在新建工程前的准备工作就全部完成了。

三、新建工程

我习惯使用Keil5来进行开发,此后也只用Keil5来进行讲解和演示
在Keil5中选择Project->New μVision Project,将该工程保存到已经建好的文件夹中的Project中,并在Device中选择好对应芯片,就完成了新建工程。

四、工程目录管理

新建好工程之后选择File Extensions(就是那个品字形的按钮)用于管理工程目录,工程目录与工程文件夹下的文件结构是不一样的,为了方便后期开发必须要做好目录管理,将所有的c源文件都按一定逻辑分门别类的放好,我习惯将所有的源文件分为四类,用户文件,系统文件,启动文件,库函数文件,在groups中新建好如上四个分类,并在Flie中添加已有的c源文件:

在GD32F4xx_Peripherals这一分类下添加官方库函数中的gd32f4xx_gpio.c和gd32f4xx_rcu.c这里面有我们今天要使用到的东西,它们在库函数文件夹中的位置为"GD32F4xx_Firmware_Library\GD32F4xx_standard_peripheral\Source;
在CMSIS中添加system_gd32f4xx.c,它在库函数文件夹中的位置为"GD32F4xx_Firmware_Library\CMSIS\GD\GD32F4xx\Source\system_gd32f4xx.c";
在Startup中添加启动文件startup_gd32f407.s,这个文件很特殊,是s文件,用汇编语言编写,这边不建议您以任何形式修改这一文件,它在库函数文件夹中的位置为"GD32F4xx_Firmware_Library\CMSIS\GD\GD32F4xx\Source\ARM\startup_gd32f407.s"
在Application中新建两个c文件,分别命名为main.c、PIN_DE.c,用来写主函数跟初始化(PIN_DE就是管脚定义pin definition的意思,这个取名可以随便)新建完成后保存到User/Source中(就是用来保存用户文件的那个文件夹),再新建一个PIN_DE.h,也即是PIN_DE.c的头文件,保存到User/Include中,这样你的工程文件夹下的用户文件夹结构应该变成这个样子:

你的工程目录变成了这个样子:

自此就完成了工程目录的管理

五、代码实现

1、初始化

单片机点亮一个LED灯的原理就是单片机的某一管脚与LED的一端相连,LED的另一端接VCC或GND,当该管脚抬高或拉低,LED灯的状态就随之变化。我手里的这块板子是PC6连接LED连接GND,那么代码需要实现的就是抬高PC6。初始化的内容就是调用函数库里的函数对这个管脚进行合理的属性设置,而函数库里面的函数绝大多数为接口函数,我们需要用到的函数有:

void rcu_periph_clock_enable(rcu_periph_enum periph)

作用是使能某个外设的通道时钟,它只有一个参数需设置,在这里设置成GPIOC。

/*!\brief      set GPIO mode\param[in]  gpio_periph: GPIO port only one parameter can be selected which is shown as below:\arg        GPIOx(x = A,B,C,D,E,F,G,H,I)\param[in]  mode: GPIO pin mode\arg        GPIO_MODE_INPUT: input mode\arg        GPIO_MODE_OUTPUT: output mode\arg        GPIO_MODE_AF: alternate function mode\arg        GPIO_MODE_ANALOG: analog mode\param[in]  pull_up_down: GPIO pin with pull-up or pull-down resistor\arg        GPIO_PUPD_NONE: floating mode, no pull-up and pull-down resistors\arg        GPIO_PUPD_PULLUP: with pull-up resistor\arg        GPIO_PUPD_PULLDOWN:with pull-down resistor\param[in]  pin: GPIO pinone or more parameters can be selected which are shown as below:\arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL\param[out] none\retval     none
*/
void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pull_up_down, uint32_t pin)

该函数用于设置GPIO的模式,在函数上方有详细的注释,第一个参数gpio_periph可选某一GPIO通道,第二个参数mode可选输入、输出、复用、模拟四种模式,第三个参数可选管脚状态,是否有上拉或下拉电阻,第四个参数选定具体的某个管脚。

/*!\brief      set GPIO output type and speed\param[in]  gpio_periph: GPIO port only one parameter can be selected which is shown as below:\arg        GPIOx(x = A,B,C,D,E,F,G,H,I)\param[in]  otype: GPIO pin output mode\arg        GPIO_OTYPE_PP: push pull mode\arg        GPIO_OTYPE_OD: open drain mode\param[in]  speed: GPIO pin output max speed\arg        GPIO_OSPEED_2MHZ: output max speed 2MHz \arg        GPIO_OSPEED_25MHZ: output max speed 25MHz \arg        GPIO_OSPEED_50MHZ: output max speed 50MHz\arg        GPIO_OSPEED_200MHZ: output max speed 200MHz\param[in]  pin: GPIO pinone or more parameters can be selected which are shown as below:\arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL\param[out] none\retval     none
*/
void gpio_output_options_set(uint32_t gpio_periph, uint8_t otype, uint32_t speed, uint32_t pin)

该函数用于设置GPIO输出类型和速度,第二个参数otype可选推挽输出或开漏输出(这个我先好好理解一下啊,后面找机会再写),第三个参数设置速度,可选2MHz、25MHz、50MHz、200MH这四种。
我们调用这三个函数,选定好合适的参数,一起放到一个初始化函数中去,方便一起调用。

void GPIO_Config(void)
{rcu_periph_clock_enable(RCU_GPIOC);/*LED*/gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_6);gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
}

首先使用rcu_periph_clock_enable使能GPIOC的通道时钟,使用gpio_mode_set设置PC6的模式为输出模式、无上拉或下拉电阻(浮空),gpio_output_options_set设置输出类型为推挽输出、速度为50MHz,自此就完成了管脚定义初始化。

2、主函数

所有的程序都是从int main开始执行的,我们在int main里面要做的就是调用刚刚写好的初始化函数对外设即PC6这一管脚进行初始化,然后再让PC6输出一个高电平。

#include "gd32f4xx.h"
#include <PIN_De.h>
#include <stdio.h>int main(void)
{GPIO_Config();LED_ON;
}

这里有小伙伴突然就懵了,GPIO_Config()这个我知道,刚刚写的初始化函数嘛,代码执行到它就会转去执行那几个初始化有关的函数,完成PC6的初始化,那LED_ON是什么鬼?我让LED开灯就开灯了嘛?
我先把我们写了点另一个文件粘贴出来PIN_De.h,也即是PIN_De.c的头文件:

#ifndef _PIN_DE_H_
#define _PIN_DE_H_#ifndef GLOB_METERCOMM_EXTERN#define GLOB_METERCOMM_EXTERN    extern
#else#define GLOB_METERCOMM_EXTERN
#endifGLOB_METERCOMM_EXTERN void GPIO_Config(void);#define LED_ON  gpio_bit_set(GPIOC, GPIO_PIN_6)   //置位PC6
#define LED_OFF gpio_bit_reset(GPIOC, GPIO_PIN_6) //复位PC6#endif

在这里面对初始化函数GPIO_Config()进行了声明,当需要调用到这个函数的源文件包含该头文件时,这个函数才能被调用,同时我们在这里也写了另外两个宏定义,

#define LED_ON  gpio_bit_set(GPIOC, GPIO_PIN_6)
#define LED_OFF gpio_bit_reset(GPIOC, GPIO_PIN_6)

定义LED_ON 为执行gpio_bit_set(GPIOC, GPIO_PIN_6),也即是抬高PC6,当主函数执行到LED_ON 时,等于执行了gpio_bit_set(GPIOC, GPIO_PIN_6),它的原型:

/*!\brief      set GPIO pin bit\param[in]  gpio_periph: GPIO port only one parameter can be selected which is shown as below:\arg        GPIOx(x = A,B,C,D,E,F,G,H,I)\param[in]  pin: GPIO pinone or more parameters can be selected which are shown as below:\arg        GPIO_PIN_x(x=0..15), GPIO_PIN_ALL\param[out] none\retval     none
*/
void gpio_bit_set(uint32_t gpio_periph, uint32_t pin)

作用是将某一管脚置位,即是抬高,输出高电平,输出为1,反正叫法很多,那直接在main里面调用这个函数不就能点亮了嘛?还要绕一圈写一个宏定义的意义是什么呢?是为了提高代码的可读性,在企业开发嵌入式程序的时候,底层和应用往往是分开的,开发应用的工程师不用去管底层硬件是如何被初始化的,当他们需要点亮一个LED的时候,只需要看对应头文件给他们提供的可用函数或宏定义就行了。
自此就完成了全部的代码编写,接下来需要把所有的头文件都包含进工程里面来,在C/C++中将所有头文件的文件夹选定。

点击Options Target,在Output里面勾选如下选项后进行编译,就可以连接板子下载程序了:
板子上电后复位,现象如图

总结

以上就是使用GD32F407点亮一个LED灯,GD的官方库其实比较谜,不同型号的芯片库函数有较大区别,互相移植会比较麻烦,更新速度还可以接收,到目前F4的库就更新了几个版本。

GD32学习笔记1(高难度工程,点亮一个LED灯)相关推荐

  1. 【STC8学习笔记】STC8A8K64S4A12 程序烧录及使一个LED闪烁

    将STC8芯片型号添加到keil中 新建keil工程选择对应的芯片 我这里已我的STC8A8K64S4A12芯片为例 编写程序一个LED闪烁的程序 #include <STC8.h>sbi ...

  2. STM32学习笔记——EXTI外部中断,光敏传感器控制LED灯

    中断系统 中断:在主程序运行过程中,当出现了特定的中断触发条件,CPU就可以暂停当前正在运行的程序去处理中断程序,并把当前程序的地址压入堆栈,中断程序处理完成后把地址弹出堆栈,回到刚刚暂停的位置继续执 ...

  3. STM32CubeMX学习之旅1:点亮一个LED灯

    本学习采用"STM32CubeMX + MDK-ARM"的开发工具组,内部利用ST主推的HAL(Hardware Abstraction Layer,硬件抽象层)库,对新大陆的M3 ...

  4. 【树莓派学习笔记】三、点亮一个LED灯(C语言 - WiringPi、Python - RPi.GPIO/GPIO Zero、bash脚本)

    目录 C语言 WiringPi Python RPi.GPIO GPIO Zero bash脚本 平台:树莓派3B 版本: 2021-05-07-raspios-buster-armhf 若GPIO输 ...

  5. Linux驱动开发学习笔记【12】:Linux自带LED灯驱动

    目录 一.内核自带LED驱动使能 二.内核自带LED驱动分析 三.内核自带LED驱动使用 一.内核自带LED驱动使能 在Linux内核中,已经自带了LED灯的驱动程序,使用的就是platform平台驱 ...

  6. 学习单片机编程第一天——点亮一个LED灯

    必要的一点说明:使用keil5编写程序,在STM32F103C8T6单片机上运行. 跳过无聊的新建工程文件等步骤,此次项目我们只针对三个文件进行操作,分别是: main.c         led.c ...

  7. 点亮一个LED及原理笔记

    本实验主要学习内容: 1.发光二极管介绍,硬件的介绍. 2.单片机IO口的介绍. 3.完成"点亮一个led灯"程序的编写和编译. 4.进行程序烧写. LED的介绍:它是半导体二极管 ...

  8. 为什么大型高难度工程的首选支模架是盘扣架?

    今天我们就来看看到底是什么原因,让大型高难度工程选择使用盘扣式脚手架呢? 01构架结构稳定 构架单元是稳定的构造形式;架体按规定设置斜杆.剪力撑.连墙杆或撑.拉件.通过插头及插销与立杆轮盘扣接,形成空 ...

  9. 区块链学习笔记19——ETH难度调整

    区块链学习笔记19--ETH难度调整 学习视频:北京大学肖臻老师<区块链技术与应用> 笔记参考:北京大学肖臻老师<区块链技术与应用>公开课系列笔记--目录导航页 前面学过,比特 ...

最新文章

  1. ODBC更新记录集提示”记录集为只读“
  2. 中国航发9名劳模工匠变身“高级制造工程师”
  3. 微信运动:抓住用户的小九九,一个都别跑
  4. UPYUN CDN 高可用架构实践
  5. LeetCode 1942. 最小未被占据椅子的编号(set)
  6. C++设计模式-适配器模式
  7. 高效神器!小目标检测迎来曙光!SSPNet金字塔网络!川大出品
  8. python内置类型方法_python基础(一)内置类型及方法
  9. html 音乐能连续播放吗,音乐在不同HTML页面的连续播放问题
  10. 【MATLAB】设定坐标的轴的范围
  11. 【答题卡识别】基于matlab Hough变换答题卡识别【含Matlab源码 250期】
  12. 无限浏览器代理服务器,老司机浏览器无限版
  13. windows10安装Erlang和RabbitMQ
  14. Cisco Packet Tracer 命令大全 【思科交换机模拟器命令大全】
  15. 【2023秋招】9月美团校招C++岗题目
  16. 金融投资大数据(1)-马科维茨资产组合基于excel
  17. POS机刷卡跨行交易的清算方式
  18. 语音专题第一讲,麦克风阵列的语音信号处理技术
  19. React组件间信息传递方式
  20. 一加7t人脸识别_一加7T深度测评:它体现了最佳的技术价值吗?

热门文章

  1. 利用批处理bat批量处理word文档属性
  2. Matlab处理气象数据(十一)数据的异常值计算
  3. 植物大战僵尸beta贝塔版
  4. #创新应用#图吧导航:高品质的导航类应用!
  5. 【正则表达式】判断是否为名字
  6. 适合计算机社团活动的游戏,大学课外社团活动游戏大全
  7. android studio开发笔记
  8. win10 gtx1660ti 配置vs opencv cuda加速
  9. 有感于2004雅典奥运会
  10. java程序员的日常小感悟