发新帖本帖赏金 20.00元(功能说明)我要提问
返回列表
打印
[CW32L083系列]

CW32L083评估板学习-4.了解GPIO

[复制链接]
682|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
#申请原创# @21小跑堂  
4.了解GPIO
GPIO(General Purpose Input Output)通用输入输出,是MCU和各种外设通讯的桥梁
CW32L083的GPIO可配置为数字输入输出和模拟功能,支持外设功能复用,支持高电平、低电平、上升沿和下降沿 4 种中断源,可在深度休眠模式下通过外部中断唤醒 MCU 回到运行模式

4.1数字输出模式
可以配置为择推挽输出或开漏输出
推挽输出:这种模式下IO可以直接输出高低电平,高电平时可以向外输出电流,输出高电平电压与VCC保持一致,需要注意连接的受控设备的IO电压承受范围
开漏输出:这种模式下IO不能真正的输出高电平,需要借助上拉电阻来实现高电平输出,输出高电平电压取决于上拉电阻所接的电源,这种模式下可以实现电平的转换,通过读取输入寄存器的值可以获得真实的高低电平,在I2C和一些单线通讯的场景下就可以用这个模式
实验-用推挽输出模式点亮LED
评估板上的LED是直接接在IO上的,这时候想要点亮它就要用到推挽模式

使用CW32的库函数可以方便的设置GPIO的模式

int32_t main(void)
{
    RCC_HSE_16M_PLL64M_init();
    RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
    RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
    __RCC_GPIOC_CLK_ENABLE();
    PC02_DIGTAL_ENABLE();
    PC03_DIGTAL_ENABLE();
    PC02_DIR_OUTPUT();
    PC03_DIR_OUTPUT();
    PC02_PUSHPULL_ENABLE();
    PC03_PUSHPULL_ENABLE();
        PC02_SETLOW();
        PC03_SETLOW();
    while(1)
    {
        PC02_TOG();
        yuyy_delay_ms(250);
        PC03_TOG();
        yuyy_delay_ms(250);
    }
}
或者使用另外一种方法
int32_t main(void)
{
    RCC_HSE_16M_PLL64M_init();
    RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
    RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
    __RCC_GPIOC_CLK_ENABLE();
    GPIO_InitTypeDef gpiodef;
    gpiodef.Pins = GPIO_PIN_2|GPIO_PIN_3;
    gpiodef.IT = GPIO_IT_NONE;
    gpiodef.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_Init(CW_GPIOC,&gpiodef);
    GPIO_WritePin(CW_GPIOC,GPIO_PIN_2|GPIO_PIN_3,GPIO_Pin_RESET);
    while(1)
    {
        GPIO_TogglePin(CW_GPIOC,GPIO_PIN_2);
        yuyy_delay_ms(250);
        GPIO_TogglePin(CW_GPIOC,GPIO_PIN_3);
        yuyy_delay_ms(250);
    }
}
最终效果都是一样的,运行效果

实验-用开漏输出模式实现线与效果
将两个开漏输出的IO连接上拉电阻并连接在一起,这时候只有两个IO都输出高电平时整体才能输出高电平,注意这个功能是不能用推挽模式去做的会造成短路

int32_t main(void)
{
    RCC_HSE_16M_PLL64M_init();
    RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
    RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
    __RCC_GPIOC_CLK_ENABLE();
    GPIO_InitTypeDef gpiodef;
    gpiodef.Pins = GPIO_PIN_2|GPIO_PIN_3;
    gpiodef.IT = GPIO_IT_NONE;
    gpiodef.Mode = GPIO_MODE_OUTPUT_OD;
    GPIO_Init(CW_GPIOC,&gpiodef);
    GPIO_WritePin(CW_GPIOC,GPIO_PIN_2|GPIO_PIN_3,GPIO_Pin_RESET);
    PC02_PUR_ENABLE();
    PC03_PUR_ENABLE();
    while(1)
    {
        GPIO_TogglePin(CW_GPIOC,GPIO_PIN_2);
        yuyy_delay_ms(250);
        GPIO_TogglePin(CW_GPIOC,GPIO_PIN_3);
        yuyy_delay_ms(250);
    }
}
由于使用的内部上拉电阻,阻值很大,IO输出电流不足以驱动板载LED,因此外接LED进行测试,运行效果

现象解释:
当不短接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个按键已经接了上拉电阻,默认输入为高电平

读取按键电平并输出到LED

评估板上的2个按键已经接了上拉电阻,默认输入为高电平,读取按键电平并输出到LED
int32_t main(void)
{
    RCC_HSE_16M_PLL64M_init();
    RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
    RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
    __RCC_GPIOC_CLK_ENABLE();
    __RCC_GPIOA_CLK_ENABLE();
    GPIO_InitTypeDef gpiodef;
    gpiodef.Pins = GPIO_PIN_2|GPIO_PIN_3;
    gpiodef.IT = GPIO_IT_NONE;
    gpiodef.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_Init(CW_GPIOC,&gpiodef);
    gpiodef.Pins = GPIO_PIN_4|GPIO_PIN_5;
    gpiodef.Mode = GPIO_MODE_INPUT;
    GPIO_Init(CW_GPIOA,&gpiodef);
    while(1)
    {
        GPIO_WritePin(CW_GPIOC,GPIO_PIN_2,GPIO_ReadPin(CW_GPIOA,GPIO_PIN_4));
        GPIO_WritePin(CW_GPIOC,GPIO_PIN_3,GPIO_ReadPin(CW_GPIOA,GPIO_PIN_5));
    }
}
运行效果

再借助这两个按键做一个实验,读取开漏模式下的IO真实电平
int32_t main(void)
{
    RCC_HSE_16M_PLL64M_init();
    RCC_HCLKPRS_Config(RCC_HCLK_DIV1);
    RCC_PCLKPRS_Config(RCC_PCLK_DIV1);
    __RCC_GPIOC_CLK_ENABLE();
    __RCC_GPIOA_CLK_ENABLE();
    GPIO_InitTypeDef gpiodef;
    gpiodef.Pins = GPIO_PIN_2|GPIO_PIN_3;
    gpiodef.IT = GPIO_IT_NONE;
    gpiodef.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_Init(CW_GPIOC,&gpiodef);
    gpiodef.Pins = GPIO_PIN_4|GPIO_PIN_5;
    gpiodef.Mode = GPIO_MODE_OUTPUT_OD;
    GPIO_Init(CW_GPIOA,&gpiodef);
    GPIO_WritePin(CW_GPIOA,GPIO_PIN_4,GPIO_Pin_RESET);
    GPIO_WritePin(CW_GPIOA,GPIO_PIN_5,GPIO_Pin_SET);
    while(1)
    {
        GPIO_WritePin(CW_GPIOC,GPIO_PIN_2,GPIO_ReadPin(CW_GPIOA,GPIO_PIN_4));
        GPIO_WritePin(CW_GPIOC,GPIO_PIN_3,GPIO_ReadPin(CW_GPIOA,GPIO_PIN_5));
    }
}
运行效果

现象解释:
PA04输出低电平,从结构图能看出来这时PA04相当于接地,外部上拉电阻并不能拉高,因此读到的一直是低电平
PA05输出高电平,但开漏模式下是由上拉电阻实现的高电平,当按键按松开时可以读到高电平,按键按下时PA05接地读到低电平
因此如果将开漏模式用于双向数据传输,例如读取DHT11温湿度,在读取外设数据前要将IO输出高电平

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

在CW32提供的GPIO库函数中也提供了直接设置GPIO为某个复用功能的方法


使用特权

评论回复

打赏榜单

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

评论
21小跑堂 2023-8-23 16:49 回复TA
简述GPIO的几种模式并用实验将部分功能加以实现 
沙发
小夏天的大西瓜| | 2023-8-26 11:52 | 只看该作者
对于任何单片机来说控制IO是最基本的也是最重要的操作

使用特权

评论回复
板凳
星辰大海不退缩| | 2023-8-27 20:40 | 只看该作者
GPIO控制是很重要的基本操作

使用特权

评论回复
地板
AdaMaYun| | 2023-8-27 21:27 | 只看该作者
CW32L083的GPIO可配置为数字输入输出和模拟功能,支持外设功能复用,支持高电平、低电平、上升沿和下降沿 4 种中断源,可在深度休眠模式下通过外部中断唤醒 MCU

使用特权

评论回复
5
OKAKAKO| | 2023-8-27 22:23 | 只看该作者
对于单片机来说控制IO是最基本的也是最重要的操作

使用特权

评论回复
发新帖 本帖赏金 20.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

85

主题

450

帖子

4

粉丝