[学习笔记] 【杰发科技AC7840x测评】GPIO极限速度测试

[复制链接]
 楼主| lulugl 发表于 2023-11-27 15:49 | 显示全部楼层 |阅读模式
本帖最后由 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灯
4aa6b6f74b830bc6ab518779cce3df22
a707e480523ab62bbd4198cb709d6dde
【配置步骤】
1、引用gpio_drv.h头文件,这个文件是官方提供的固件,用于提供gpio集成函数接口。
2、初始化LED引脚
初始化引脚功能,有部分引脚上电默认为非GPIO,必须选择其功能为GPIO才能作为GPIO使用。数据手册中有下图所描述:
d57a3316e43f8c6742d0980bed05017f
在gpio_drv.h中枚举了复用的几种情况:
  1. /*!

  2. * [url=home.php?mod=space&uid=247401]@brief[/url] Configures the pin mux.

  3. */

  4. typedef enum

  5. {

  6. PORT_PIN_DISABLED = 0U, /*!< gpio is disabled or as an analog funciton */

  7. PORT_MUX_AS_GPIO = 1U, /*!< gpio is configured as GPIO */

  8. PORT_MUX_ALT2 = 2U, /*!< chip-specific */

  9. PORT_MUX_ALT3 = 3U, /*!< chip-specific */

  10. PORT_MUX_ALT4 = 4U, /*!< chip-specific */

  11. PORT_MUX_ALT5 = 5U, /*!< chip-specific */

  12. PORT_MUX_ALT6 = 6U, /*!< chip-specific */

  13. PORT_MUX_ALT7 = 7U /*!< chip-specific */

  14. } port_mux_t;

因此我们先要配置他们的复用:
  1. GPIO_DRV_SetMuxModeSel(LED3_PORT, LED3_PIN, PORT_MUX_AS_GPIO); /*功能复用选择*/

  2. GPIO_DRV_SetMuxModeSel(LED4_PORT, LED4_PIN, PORT_MUX_AS_GPIO);

  3. GPIO_DRV_SetMuxModeSel(RGBLED_R_PORT, RGBLED_R_PIN, PORT_MUX_AS_GPIO);

  4. GPIO_DRV_SetMuxModeSel(RGBLED_G_PORT, RGBLED_G_PIN, PORT_MUX_AS_GPIO);

  5. GPIO_DRV_SetMuxModeSel(RGBLED_B_PORT, RGBLED_B_PIN, PORT_MUX_AS_GPIO);

注:其中的端口、引脚宏定义为:
  1. #define LED3_PORT (PORTC)

  2. #define LED3_GPIO (GPIOC)

  3. #define LED3_PIN (6)

  4. #define LED4_PORT (PORTC)

  5. #define LED4_GPIO (GPIOC)

  6. #define LED4_PIN (7)

  7. #define RGBLED_R_PORT (PORTD)

  8. #define RGBLED_R_GPIO (GPIOD)

  9. #define RGBLED_R_PIN (16)

  10. #define RGBLED_G_PORT (PORTD)

  11. #define RGBLED_G_GPIO (GPIOD)

  12. #define RGBLED_G_PIN (15)

  13. #define RGBLED_B_PORT (PORTE)

  14. #define RGBLED_B_GPIO (GPIOE)

  15. #define RGBLED_B_PIN (9)

接下来,我们对端口配置为输出模式:
  1. <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)进入写入操作。其寄存器的说明如下图:
df9aad06b5de5a4031d041a1cf09a05f
在函数库中,封装了写入的函数:
  1. <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的输出函数如下代码:
  1. int main(void)
  2. {
  3.     SystemClock_Config();
  4.     InitDebug();
  5.     printf("GPIO Basic Test\r\n");

  6.     GPIO_LedInit();
  7.     GPIO_KeyInit();

  8.     while (1)
  9.     {
  10.         if (Get_Key4Value() == 1) /*按键按下*/
  11.         {
  12.             LED3_TOGGLE;
  13.             LED4_TOGGLE;
  14.         }
  15.         RGB_Toggle();
  16.     }
  17. }

最后编译下载程序就可以看到了LED灯的闪烁了。
【小结】
对gpio的输出操作,主要有三个步骤,配置引脚复用、输入与输出、对PODR进行数据写入,这就实现了对GPIO的控制了。
【翻转速率的测试】
1、使用读写函数进行翻转:
fd5a1995cbe22de7cd2f498f46c631c9
测得的波形为:
c43db3df28a7e075bf95fe734b024c2f
翻转速为1.94MHz。
2、使用翻转库函数进行操作:
2deedd1fbbf2bca454ad8616fcdfa079
测得波形为:
d1cccc3b3d6f02a1e7984a19908b7ce9
速率为4MHz。
3、为了达到极限的速度,我直接对寄存器进行操作,
7236e718faeed20ff1f29074240f0f85
测得波形如下
ac0aaf95c6423c1d5b13c3f65785154f
速度为10MHz。
5、去掉移位取反等位的操作,直接写寄存器:
118ba86109c95f505ff4dedc80a5e2ed
测得波形如下:
cd5c22a697d9f1e392cc5d373d6c3af3
翻转速度为30.3MHz。
【总结】
AC7840x的总线频率为120MHz,GPIO可翻转速率可以达到30MHz。
在GPIO通用输入输出功能上,使用官方提供的库函数,分三步就可以实现对外设的驱动。

tpgf 发表于 2023-12-14 14:20 | 显示全部楼层
这个波形也太好了吧 一点杂波也没有啊
 楼主| lulugl 发表于 2023-12-14 15:25 | 显示全部楼层
tpgf 发表于 2023-12-14 14:20
这个波形也太好了吧 一点杂波也没有啊

说明杰发的芯片的质量是非常好的。
paotangsan 发表于 2023-12-14 15:56 | 显示全部楼层
波形的尖刺是怎么出来的呢 可以消除吗
 楼主| lulugl 发表于 2023-12-14 18:28 | 显示全部楼层
paotangsan 发表于 2023-12-14 15:56
波形的尖刺是怎么出来的呢 可以消除吗

这个没办法呀,这是厂家IO驱动的事情了,如果开关速度不高的话,他不会出现这种情况的。
wakayi 发表于 2023-12-14 19:11 | 显示全部楼层
这个是在没有任何干扰的情况下的测试结果吧
renzheshengui 发表于 2023-12-14 19:47 | 显示全部楼层
非常的平滑 再高的话 波形就会走样了是吗
wowu 发表于 2023-12-15 09:03 | 显示全部楼层
gpio的速度和外部硬件的连接有关系吗
 楼主| lulugl 发表于 2023-12-15 09:26 | 显示全部楼层
wowu 发表于 2023-12-15 09:03
gpio的速度和外部硬件的连接有关系吗

这个当然有关系呀,如果外部不支持,你快也没得用,要同时才能实现通信。
xiaoqizi 发表于 2023-12-15 23:32 | 显示全部楼层
这个测试速度有没有查看不同的输出模式的速度是不是相同的呢
您需要登录后才可以回帖 登录 | 注册

本版积分规则

180

主题

830

帖子

12

粉丝
快速回复 在线客服 返回列表 返回顶部