本帖最后由 lulugl 于 2023-11-27 15:54 编辑
#申请原创# #有奖活动#
【前言】
GPIO是MCU的最基础的外设,GPIO过经配置后,可以驱动LED。经过处理后可以模拟I2C、SPI、UART、PWM时序来驱动外设。
一、驱动板载的5个LED灯
经查看开发板原理图
开发板提供了两个 LED(PC6/PC7)用于指示程序运行状态,两个灯都为绿色,两个 LED 分别通
过一个三极管连接到 IO 口,IO 口通过输出高点亮 LED,同时 LED3/LED4 连接的 IO 口均具有 PWM 功能,可以通过 PWM 输出来调节 LED 亮度。
还有一个RGB灯通过(PD16、PD15、PE9)连接,输出高电平点亮RGB灯
【配置步骤】
1、引用gpio_drv.h头文件,这个文件是官方提供的固件,用于提供gpio集成函数接口。
2、初始化LED引脚
初始化引脚功能,有部分引脚上电默认为非GPIO,必须选择其功能为GPIO才能作为GPIO使用。数据手册中有下图所描述:
在gpio_drv.h中枚举了复用的几种情况:
/*!
* [url=home.php?mod=space&uid=247401]@brief[/url] Configures the pin mux.
*/
typedef enum
{
PORT_PIN_DISABLED = 0U, /*!< gpio is disabled or as an analog funciton */
PORT_MUX_AS_GPIO = 1U, /*!< gpio is configured as GPIO */
PORT_MUX_ALT2 = 2U, /*!< chip-specific */
PORT_MUX_ALT3 = 3U, /*!< chip-specific */
PORT_MUX_ALT4 = 4U, /*!< chip-specific */
PORT_MUX_ALT5 = 5U, /*!< chip-specific */
PORT_MUX_ALT6 = 6U, /*!< chip-specific */
PORT_MUX_ALT7 = 7U /*!< chip-specific */
} port_mux_t;
因此我们先要配置他们的复用:
GPIO_DRV_SetMuxModeSel(LED3_PORT, LED3_PIN, PORT_MUX_AS_GPIO); /*功能复用选择*/
GPIO_DRV_SetMuxModeSel(LED4_PORT, LED4_PIN, PORT_MUX_AS_GPIO);
GPIO_DRV_SetMuxModeSel(RGBLED_R_PORT, RGBLED_R_PIN, PORT_MUX_AS_GPIO);
GPIO_DRV_SetMuxModeSel(RGBLED_G_PORT, RGBLED_G_PIN, PORT_MUX_AS_GPIO);
GPIO_DRV_SetMuxModeSel(RGBLED_B_PORT, RGBLED_B_PIN, PORT_MUX_AS_GPIO);
注:其中的端口、引脚宏定义为:
#define LED3_PORT (PORTC)
#define LED3_GPIO (GPIOC)
#define LED3_PIN (6)
#define LED4_PORT (PORTC)
#define LED4_GPIO (GPIOC)
#define LED4_PIN (7)
#define RGBLED_R_PORT (PORTD)
#define RGBLED_R_GPIO (GPIOD)
#define RGBLED_R_PIN (16)
#define RGBLED_G_PORT (PORTD)
#define RGBLED_G_GPIO (GPIOD)
#define RGBLED_G_PIN (15)
#define RGBLED_B_PORT (PORTE)
#define RGBLED_B_GPIO (GPIOE)
#define RGBLED_B_PIN (9)
接下来,我们对端口配置为输出模式:
<p>GPIO_DRV_SetPinDirection(LED3_GPIO, LED3_PIN, 1); /*设置GPIO为输出*/</p><p> GPIO_DRV_SetPinDirection(LED4_GPIO, LED4_PIN, 1);</p><p> GPIO_DRV_SetPinDirection(RGBLED_R_GPIO, RGBLED_R_PIN, 1);</p><p> GPIO_DRV_SetPinDirection(RGBLED_G_GPIO, RGBLED_G_PIN, 1);</p><p>GPIO_DRV_SetPinDirection(RGBLED_B_GPIO, RGBLED_B_PIN, 1);</p>
杰发重构了配置函数,函数的命令具有可读性。最后一个参数如果为 1则为输出,如果为0则为输入。
【输出电平】
在上面的配置好寄存器后,我们需要对GPIO的输出数据寄存器(GPIO_PODR)进入写入操作。其寄存器的说明如下图:
在函数库中,封装了写入的函数:
<p>/*!</p><p> * [url=home.php?mod=space&uid=247401]@brief[/url] Write the IO output level for one pin.</p><p> *</p><p> * @param[in] base: GPIO base pointer (GPIOA, GPIOB, GPIOC, etc.)</p><p> * @param[in] pin: The pin number to be written</p><p> * @param[in] value: Pin value to be written</p><p> * - 0: corresponding pin is set to low</p><p> * - 1: corresponding pin is set to high</p><p> * [url=home.php?mod=space&uid=266161]@return[/url] none</p><p> */</p><p>static inline void GPIO_WritePin(GPIO_Type * const base, gpio_channel_type_t pin, gpio_level_type_t value)</p><p>{</p><p> gpio_channel_type_t pinsValues = (gpio_channel_type_t)base->PODR;</p><p> pinsValues &= (gpio_channel_type_t)(~((gpio_channel_type_t)1U << pin));</p><p> pinsValues |= (gpio_channel_type_t)((gpio_channel_type_t)value << pin);</p><p> base->PODR = pinsValues;</p><p>}</p>
他最先是读出端口的值,然后对该位寄存器进行写入value,有三步运算,这跟其它的MCU的有所区别,比如stm32是对BSRR也BRR进行写。
在例程中,对5个GPIO的输出函数如下代码:
int main(void)
{
SystemClock_Config();
InitDebug();
printf("GPIO Basic Test\r\n");
GPIO_LedInit();
GPIO_KeyInit();
while (1)
{
if (Get_Key4Value() == 1) /*按键按下*/
{
LED3_TOGGLE;
LED4_TOGGLE;
}
RGB_Toggle();
}
}
最后编译下载程序就可以看到了LED灯的闪烁了。
【小结】
对gpio的输出操作,主要有三个步骤,配置引脚复用、输入与输出、对PODR进行数据写入,这就实现了对GPIO的控制了。
【翻转速率的测试】
1、使用读写函数进行翻转:
测得的波形为:
翻转速为1.94MHz。
2、使用翻转库函数进行操作:
测得波形为:
速率为4MHz。
3、为了达到极限的速度,我直接对寄存器进行操作,
测得波形如下
速度为10MHz。
5、去掉移位取反等位的操作,直接写寄存器:
测得波形如下:
翻转速度为30.3MHz。
【总结】
AC7840x的总线频率为120MHz,GPIO可翻转速率可以达到30MHz。
在GPIO通用输入输出功能上,使用官方提供的库函数,分三步就可以实现对外设的驱动。
|