返回列表 发新帖我要提问本帖赏金: 20.00元(功能说明)

[CW32L083系列] CW32L083评估板学习-4.了解GPIO

[复制链接]
 楼主| yuyy1989 发表于 2023-8-10 18:58 | 显示全部楼层 |阅读模式
<
#申请原创# @21小跑堂  
4.了解GPIO
GPIO(General Purpose Input Output)通用输入输出,是MCU和各种外设通讯的桥梁
CW32L083的GPIO可配置为数字输入输出和模拟功能,支持外设功能复用,支持高电平、低电平、上升沿和下降沿 4 种中断源,可在深度休眠模式下通过外部中断唤醒 MCU 回到运行模式
QQ截图20230809093831.png
4.1数字输出模式
可以配置为择推挽输出或开漏输出
推挽输出:这种模式下IO可以直接输出高低电平,高电平时可以向外输出电流,输出高电平电压与VCC保持一致,需要注意连接的受控设备的IO电压承受范围
开漏输出:这种模式下IO不能真正的输出高电平,需要借助上拉电阻来实现高电平输出,输出高电平电压取决于上拉电阻所接的电源,这种模式下可以实现电平的转换,通过读取输入寄存器的值可以获得真实的高低电平,在I2C和一些单线通讯的场景下就可以用这个模式
实验-用推挽输出模式点亮LED
评估板上的LED是直接接在IO上的,这时候想要点亮它就要用到推挽模式
QQ截图20230809095140.png
使用CW32的库函数可以方便的设置GPIO的模式

  1. int32_t main(void)
  2. {
  3.     RCC_HSE_16M_PLL64M_init();
  4.     RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
  5.     RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
  6.     __RCC_GPIOC_CLK_ENABLE();
  7.     PC02_DIGTAL_ENABLE();
  8.     PC03_DIGTAL_ENABLE();
  9.     PC02_DIR_OUTPUT();
  10.     PC03_DIR_OUTPUT();
  11.     PC02_PUSHPULL_ENABLE();
  12.     PC03_PUSHPULL_ENABLE();
  13.         PC02_SETLOW();
  14.         PC03_SETLOW();
  15.     while(1)
  16.     {
  17.         PC02_TOG();
  18.         yuyy_delay_ms(250);
  19.         PC03_TOG();
  20.         yuyy_delay_ms(250);
  21.     }
  22. }
或者使用另外一种方法
  1. int32_t main(void)
  2. {
  3.     RCC_HSE_16M_PLL64M_init();
  4.     RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
  5.     RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
  6.     __RCC_GPIOC_CLK_ENABLE();
  7.     GPIO_InitTypeDef gpiodef;
  8.     gpiodef.Pins = GPIO_PIN_2|GPIO_PIN_3;
  9.     gpiodef.IT = GPIO_IT_NONE;
  10.     gpiodef.Mode = GPIO_MODE_OUTPUT_PP;
  11.     GPIO_Init(CW_GPIOC,&gpiodef);
  12.     GPIO_WritePin(CW_GPIOC,GPIO_PIN_2|GPIO_PIN_3,GPIO_Pin_RESET);
  13.     while(1)
  14.     {
  15.         GPIO_TogglePin(CW_GPIOC,GPIO_PIN_2);
  16.         yuyy_delay_ms(250);
  17.         GPIO_TogglePin(CW_GPIOC,GPIO_PIN_3);
  18.         yuyy_delay_ms(250);
  19.     }
  20. }
最终效果都是一样的,运行效果
WeChat_20230810182521 00_00_00-00_00_30.gif
实验-用开漏输出模式实现线与效果
将两个开漏输出的IO连接上拉电阻并连接在一起,这时候只有两个IO都输出高电平时整体才能输出高电平,注意这个功能是不能用推挽模式去做的会造成短路

  1. int32_t main(void)
  2. {
  3.     RCC_HSE_16M_PLL64M_init();
  4.     RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
  5.     RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
  6.     __RCC_GPIOC_CLK_ENABLE();
  7.     GPIO_InitTypeDef gpiodef;
  8.     gpiodef.Pins = GPIO_PIN_2|GPIO_PIN_3;
  9.     gpiodef.IT = GPIO_IT_NONE;
  10.     gpiodef.Mode = GPIO_MODE_OUTPUT_OD;
  11.     GPIO_Init(CW_GPIOC,&gpiodef);
  12.     GPIO_WritePin(CW_GPIOC,GPIO_PIN_2|GPIO_PIN_3,GPIO_Pin_RESET);
  13.     PC02_PUR_ENABLE();
  14.     PC03_PUR_ENABLE();
  15.     while(1)
  16.     {
  17.         GPIO_TogglePin(CW_GPIOC,GPIO_PIN_2);
  18.         yuyy_delay_ms(250);
  19.         GPIO_TogglePin(CW_GPIOC,GPIO_PIN_3);
  20.         yuyy_delay_ms(250);
  21.     }
  22. }
由于使用的内部上拉电阻,阻值很大,IO输出电流不足以驱动板载LED,因此外接LED进行测试,运行效果
WeChat_20230810182545 00_00_00-00_00_30.gif
现象解释:
当不短接PC02与PC03时每个LED都是亮起500毫秒熄灭500毫秒,顺序如下
PC02:0-250ms-1-250ms-1-250ms-0-250ms-
PC03:0-250ms-0-250ms-1-250ms-1-250ms-
短接PC02与PC03以后只有两个IO都为1时才能总输出为1,这时LED亮起250ms熄灭750ms
线与:0-250ms-0-250ms-1-250ms-0-250ms-

4.2数字输入模式
数字输入模式下MCU可以通过IO读取外部输入的高低电平,电流向MCU流入,可以配置上拉或下拉电阻来设定默认输入电平,高低电平的改变可以触发中断
实验-根据按键电平设置LED的亮灭
评估板上的2个按键已经接了上拉电阻,默认输入为高电平
QQ截图20230809101530.png
读取按键电平并输出到LED

  1. 评估板上的2个按键已经接了上拉电阻,默认输入为高电平,读取按键电平并输出到LED
  2. int32_t main(void)
  3. {
  4.     RCC_HSE_16M_PLL64M_init();
  5.     RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
  6.     RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
  7.     __RCC_GPIOC_CLK_ENABLE();
  8.     __RCC_GPIOA_CLK_ENABLE();
  9.     GPIO_InitTypeDef gpiodef;
  10.     gpiodef.Pins = GPIO_PIN_2|GPIO_PIN_3;
  11.     gpiodef.IT = GPIO_IT_NONE;
  12.     gpiodef.Mode = GPIO_MODE_OUTPUT_PP;
  13.     GPIO_Init(CW_GPIOC,&gpiodef);
  14.     gpiodef.Pins = GPIO_PIN_4|GPIO_PIN_5;
  15.     gpiodef.Mode = GPIO_MODE_INPUT;
  16.     GPIO_Init(CW_GPIOA,&gpiodef);
  17.     while(1)
  18.     {
  19.         GPIO_WritePin(CW_GPIOC,GPIO_PIN_2,GPIO_ReadPin(CW_GPIOA,GPIO_PIN_4));
  20.         GPIO_WritePin(CW_GPIOC,GPIO_PIN_3,GPIO_ReadPin(CW_GPIOA,GPIO_PIN_5));
  21.     }
  22. }
运行效果
WeChat_20230810182558 00_00_00-00_00_30.gif
再借助这两个按键做一个实验,读取开漏模式下的IO真实电平
  1. int32_t main(void)
  2. {
  3.     RCC_HSE_16M_PLL64M_init();
  4.     RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
  5.     RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
  6.     __RCC_GPIOC_CLK_ENABLE();
  7.     __RCC_GPIOA_CLK_ENABLE();
  8.     GPIO_InitTypeDef gpiodef;
  9.     gpiodef.Pins = GPIO_PIN_2|GPIO_PIN_3;
  10.     gpiodef.IT = GPIO_IT_NONE;
  11.     gpiodef.Mode = GPIO_MODE_OUTPUT_PP;
  12.     GPIO_Init(CW_GPIOC,&gpiodef);
  13.     gpiodef.Pins = GPIO_PIN_4|GPIO_PIN_5;
  14.     gpiodef.Mode = GPIO_MODE_OUTPUT_OD;
  15.     GPIO_Init(CW_GPIOA,&gpiodef);
  16.     GPIO_WritePin(CW_GPIOA,GPIO_PIN_4,GPIO_Pin_RESET);
  17.     GPIO_WritePin(CW_GPIOA,GPIO_PIN_5,GPIO_Pin_SET);
  18.     while(1)
  19.     {
  20.         GPIO_WritePin(CW_GPIOC,GPIO_PIN_2,GPIO_ReadPin(CW_GPIOA,GPIO_PIN_4));
  21.         GPIO_WritePin(CW_GPIOC,GPIO_PIN_3,GPIO_ReadPin(CW_GPIOA,GPIO_PIN_5));
  22.     }
  23. }
运行效果
WeChat_20230810185610 00_00_00-00_00_30.gif
现象解释:
PA04输出低电平,从结构图能看出来这时PA04相当于接地,外部上拉电阻并不能拉高,因此读到的一直是低电平
PA05输出高电平,但开漏模式下是由上拉电阻实现的高电平,当按键按松开时可以读到高电平,按键按下时PA05接地读到低电平
因此如果将开漏模式用于双向数据传输,例如读取DHT11温湿度,在读取外设数据前要将IO输出高电平

4.3模拟功能
配置成模式功能后端口的数字功能关闭,内部上拉、下拉均被断开,内部数字输入信号通过ADS开关被短接到VSS,内部数字输出功能被禁止,对于有模拟功能的IO配置成模拟功后就可以使用对应的模拟功能外设去控制了,例如ADC VC LVD等
4.4复用功能
GPIO可以通过配置复用功能寄存器实现做为某个外设的指定引脚功能,复用功能表可以查看数据手册的引脚定义或者用户手册的复用功能
QQ截图20230809102644.png
在CW32提供的GPIO库函数中也提供了直接设置GPIO为某个复用功能的方法

QQ截图20230809102857.png

打赏榜单

21小跑堂 打赏了 20.00 元 2023-08-23
理由:恭喜通过原创审核!期待您更多的原创作品~

评论

简述GPIO的几种模式并用实验将部分功能加以实现  发表于 2023-8-23 16:49
小夏天的大西瓜 发表于 2023-8-26 11:52 | 显示全部楼层
对于任何单片机来说控制IO是最基本的也是最重要的操作
星辰大海不退缩 发表于 2023-8-27 20:40 | 显示全部楼层
GPIO控制是很重要的基本操作
AdaMaYun 发表于 2023-8-27 21:27 | 显示全部楼层
CW32L083的GPIO可配置为数字输入输出和模拟功能,支持外设功能复用,支持高电平、低电平、上升沿和下降沿 4 种中断源,可在深度休眠模式下通过外部中断唤醒 MCU
OKAKAKO 发表于 2023-8-27 22:23 | 显示全部楼层
对于单片机来说控制IO是最基本的也是最重要的操作
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:同飞软件研发工程师
简介:制冷系统单片机软件开发,使用PID控制温度

161

主题

815

帖子

10

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