开发环境:
mdk:keil 5.30
开发板:gd32f207i-eval
mcu:gd32f207ik
1 gpio工作原理熟悉单片机的朋友都知道,学习的第一个例程就是流水灯,要想实现流水灯,首先必须了解gpio的工作原理。gpio的基本结构如下图所示。
gd32 的 io 口可以由软件配置成如下 8 种模式:
输入模式浮空输入:浮空(floating)就是逻辑器件的输入引脚即不接高电平,也不接低电平。由于逻辑器件的内部结构,当它输入引脚悬空时,相当于该引脚接了高电平。一般实际运用时,引脚不建议悬空,易受干扰。通俗讲就是让管脚什么都不接,浮空着。信号进入芯片内部后,既没有接上拉电阻也没有接下拉电阻,经由触发器输入。配置成这个模式后,用电压变量引脚电压为1点几伏,这是个不确定值。由于其输入阻抗比较大,一般把这种模式用于标准的通讯协议,比如iic、usart的等。该模式是gd32复位之后的默认模式。
上拉输入:上拉就是把电位拉高,比如拉到vcc。上拉就是将不确定的信号通过一个电阻嵌位在高电平,电阻同时起限流作用,弱强只是上拉电阻的阻值不同,没有什么严格区分。上拉输入就是信号进入芯片后加了一个上拉电阻,再经过施密特触发器转换成0、1信号,读取此时的引脚电平为高电平。
下拉输入:就是把电压拉低,拉到gnd。与上拉原理相似。下拉输入就是信号进入芯片后加了一个下拉电阻,再经过施密特触发器转换成0、1信号,读取此时的引脚电平为低电平。
模拟输入:信号进入后不经过上拉电阻或者下拉电阻,关闭施密特触发器,经由另一线路把电压信号传送到片上外设模块。模拟输入是指传统方式的输入,数字输入是输入pcm数字信号,即0、1的二进制数字信号,通过数模转换,转换成模拟信号,经前级放大进入功率放大器,功率放大器还是模拟的。比如传送给adc模块,由adc采集电压信号。所以可以理解为模拟输入的信号是未经处理的信号,是原汁原味的信号。
输出模式开漏输出:一般用在电平不匹配的场合,如需要输出5v的高电平。输出端相当于三极管的集电极,要得到高电平状态需要上拉电阻才行。适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内)。
复用开漏输出:可以理解为gpio口被用作第二功能时的配置情况(即并非作为通用io口使用)。端口必须配置成复用开漏功能输出模式。
推挽式输出:可以输出高、低电平,连接数字器件;推挽结构一般是指两个三极管分别受两个互补信号的控制,总是在一个三极管导通的时候另一个截止。高低电平由ic的电源决定。推挽电路是两个参数相同的三极管或mosfet,以推挽方式存在于电路中,各负责正负半周的波形放大任务,电路工作时,两只对称的功率开关管每次只有一个导通,所以导通损耗小、效率高。输出既可以向负载灌电流,也可以从负载抽取电流。推拉式输出级既提高电路的负载能力,又提高开关速度。
推挽式复用输出:可以理解为gpio口被用作第二功能时的配置情况(即并非作为通用io口使用)。端口必须配置成复用推挽功能输出模式。
2 i/o复用和重映射2.1 i/o复用gd32 有很多的内置外设,这些外设的外部引脚都是与 gpio 复用的。也就是说,一个 gpio如果可以复用为内置外设的功能引脚,那么当这个 gpio 作为内置外设使用的时候,就叫做复用。当i/o端口被配置为复用功能时:
● 在开漏或推挽式配置中,输出缓冲器被打开
● 内置外设的信号驱动输出缓冲器(复用功能输出)
● 施密特触发输入被激活
● 弱上拉和下拉电阻被禁止
● 在每个apb2时钟周期,出现在i/o脚上的数据被采样到输入数据寄存器
● 开漏模式时,读输入数据寄存器时可得到i/o口状态
● 在推挽模式时,读输出数据寄存器时可得到最后一次写的值
大家都知道,mcu 都有串口,gd32 有好几个串口。比如说 gd32f207ik有 8个串口,我们可以查手册知道,串口 0 的引脚对应的 io 为 pa9,pa10.pa9, pa10 默认功能是 gpio, 所以当pa9,pa10 引脚作为串口0的 tx,rx 引脚使用的时候,那就是端口复用。
usart0_txpa9
usart0_rx pa10
关于串口的内容后面的章节会详细讲解。
2.2 i/o重映射为了使不同器件封装的外设 io 功能数量达到最优,可以把一些复用功能重新映射到其他一些引脚上。 gd32 中有很多内置外设的输入输出引脚都具有重映射(remap)的功能。 我们知道每个内置外设都有若干个输入输出引脚,一般这些引脚的输出端口都是固定不变的,为了让设计工程师可以更好地安排引脚的走向和功能,在 gd32中引入了外设引脚重映射的概念,即一个外设的引脚除了具有默认的端口外,还可以通过设置重映射寄存器的方式,把这个外设的引脚映射到其它的端口。
复用功能usart1_remap = 0usart1_remap = 1
usart0_tx pa9 pb6
usart0_rx pa10 pb7
从表中可以看出,默认情况下,串口 0复用的时候的引脚位 pa9、pa10,同时我们可以将 tx 和 rx 重新映射到管脚 pb6 和 pb7 上面去。所以重映射我们同样要使能复用功能的时候讲解的 2 个时钟外,还要使能 afio 功能时钟,然后要调用重映射函数。
3 gpio流水灯硬件电路分析发光二极管是属于二极管的一种,具有二级管单向导电特性,即只有在正向电压(二极管的正极接正,负极接负)下才能导通发光。pf6引脚接发光二极管(led1)的正极,所以pf6引脚输出高电平led1亮,pf6引脚输出低电平led1熄灭,其他led同理。
值得注意的,不同的开发板,led连接的gpio一般是不同的,请注意修改。
4 gpio流水灯寄存器分析要想真正掌握一款单片机,分析寄存器是必不可少,但是对于gd32来再说,gd已经将寄存器操作封装成库函数,开发者只需要调用库函数即可,对于初学者来说,只需学会使用使用函数即可,对于没有基础的读者朋友就不必细究每个寄存器,当学到一定程度,再来一探究竟吧,笔者再这里只是给出gpio的寄存配置相关配置表,在后面的章节也是如此。好了,继续进入正题吧。
每个gpio端口都有两个32位配置寄存器(gpio_ctl0 ,gpio_ctl1) ,两个16位数据寄存器 (gpio_istat和gpio_octl),一个32位置位寄存器(gpio_bop),一个16位复位寄存器(gpio_bc),一个16位锁定寄存器(gpio_lock)。每个i/o端口位可以自由编程。
点亮led,基本步骤是:配置寄存器;控制寄存器。库开发只是将传统的配置方式编程函数,是的单片机开发变得简单方便快捷。
我们常用的 io 端口寄存器只有 4 个: gpio_ctl0、gpio_ctl1、 gpio_octl、 gpio_bop。其中gpio_ctl0、gpio_ctl1 控制着每个 io 口的模式及输出速率。
gpio_ctl0、gpio_ctl1类似,读者朋友可以参看《gd32f10x_user_manual_en_rev2.4》数据输入输出寄存器是将对应的io口置位,从而进行数据的输入与输出。
5 gpio 流水灯实现流程笔者在上文已经分析了gpio的原理及操作步骤,现在我们就来写代码吧。
gpio是开发gd32最基本的配置,所以掌握gpio的配置显得尤为重要。要实现流水灯,一般步骤可以总结为如下:
gpio 时钟使能;gpio 端口模式设置;初始化io口;编写处理函数;6 gpio 流水灯实现6.1 gpio库函数gpio库函数相关的库函数如下:
gpio_deinit 复位外设gpiogpio_afio_deinit 复位afiogpio_init gpio参数初始化gpio_bit_set 置位引脚值gpio_bit_reset 复位引脚值gpio_bit_write 将特定的值写入引脚gpio_port_write 将特定的值写入一组端口gpio_input_bit_get 获取引脚的输入值gpio_input_port_get 获取一组端口的输入值gpio_output_bit_get 获取引脚的输出值gpio_output_port_get 获取一组端口的输出值gpio_pin_remap_config 配置gpio引脚重映射gpio_pin_remap1_config 配置gpio引脚重映射1gpio_exti_source_select 选择哪个引脚作为exti源gpio_ethernet_phy_select 以太网mii或rmii phy选择gpio_event_output_config 配置事件输出gpio_event_output_enable 事件输出使能gpio_event_output_disable 事件输出禁能gpio_pin_lock 相应的引脚配置被锁定6.2 流水灯代码实现主函数代码如下:
/* brief main function param[in] none param[out] none retval none*/int main(void){ /* configure led1 gpio port */ led_init(led1); /* configure led2 gpio port */ led_init(led2); /* configure led3 gpio port */ led_init(led3); /* configure led4 gpio port */ led_init(led4); while(1) { /* turn on led1, turn off led4 */ led_on(led1); led_off(led4); /*delay about 500ms*/ delay(0xffffff); /* turn on led2, turn off led1 */ led_on(led2); led_off(led1); /*delay about 500ms*/ delay(0xffffff); /* turn on led3, turn off led2 */ led_on(led3); led_off(led2); /*delay about 500ms*/ delay(0xffffff); /* turn on led4, turn off led3 */ led_on(led4); led_off(led3); /*delay about 500ms*/ delay(0xffffff); }}代码还是比较简单的,首先开启gpio的时钟,然后对gpio初始化,主要是设置模式和速率,gpio的初始化代码如下:
/* brief configure led gpio param[in] lednum: specify the led to be configured arg led1 arg led2 arg led3 arg led4 param[out] none retval none*/void led_init(led_typedef_enum lednum){ /* enable the led clock */ rcu_periph_clock_enable(gpio_clk[lednum]); /* configure led gpio port */ gpio_init(gpio_port[lednum], gpio_mode_out_pp, gpio_ospeed_50mhz, gpio_pin[lednum]); gpio_bc(gpio_port[lednum]) = gpio_pin[lednum];}然后就可以控制gpio高低电平了。
7 实验现象将编译好的程序下载到板子中,可以看到四个led灯依次闪烁。
七牛云召开战略发布会,持续推动数智化升级
直线电机3D打印技术将被应用于海上风力发电
CCD机器视觉及其检测系统的优势
【节能学院】直流电能表在意大利光伏蓄电池项目的设计与应用
PCB数据交换的关键技术分析
GD32开发实战指南(基础篇) 第2章 初始GPIO流水灯
嵌入式安全威胁就在眼前,对策你想好了吗
一文解析相控阵天线的仿真应用
变频器能耗制动斩波控制原理
关于北斗模块相关应用领域的详细讲解
支付宝越来越完善了,将逐渐开放生物识别、AR、AI 等能力
电动汽车PTC优选器件方案
爆华为商城将上架自研台式机,标配鲲鹏920处理器和国产系统
怎样修理无图电话机
全面提升游戏体验,联发科G90让骁龙855大惊失色
大数据与机器学习主管Kireet Reddy分享入门机器学习的经验
抗混迭滤波器,什么是抗混迭滤波器
有铅中温锡膏和无铅中温锡膏有什么区别?
关于IBM推出具有相变存储器的8位模拟芯片性能分析介绍
单端反激电路工作原理及输出波形(三种工作模式)