#申请原创# @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为某个复用功能的方法
|
简述GPIO的几种模式并用实验将部分功能加以实现