测试发现IO输出没问题,输入必须开启CMOS缓冲或者施密特触发,这个在手册上面么有提到,目前使用都是开启了CMOS缓冲区才能做为输入IO,否则输入读取的数据无法反应IO状态。
*************************************************************************************************************************
* 函数 : void SYS_GPIOx_OneInit(GPIO_TypeDef *GPIOx, u8 io_num, SYS_GPIO_MODE mode, u8 InMode)
* 功能 : 初始化一个IO
* 参数 : GPIOx:GPIO对象;io_num:io索引,从0开始;mode:IO模式;InMode:输入模式设置
* 返回 : 无
* 依赖 : 底层与OS
* 作者 : cp1300@139.com
* 时间 : 2020-09-01
* 最后修改时间 : 2020-09-01
* 说明 : 用于初始化一个IO
InMode:输入模式
GPIO_IN_NONE 0 //默认的输入模式
GPIO_IN_DE_BOUNCE (1<<0) //输入消抖
GPIO_IN_CMOS (1<<1) //CMOS输入缓冲
GPIO_IN_SCHMITT (1<<2) //施密特触发器
CMOS输入缓冲与施密特触发器只能二选一,输入不能设置为GPIO_IN_NONE
*************************************************************************************************************************/
void SYS_GPIOx_OneInit(GPIO_TypeDef *GPIOx, u8 io_num, SYS_GPIO_MODE mode, u8 InMode)
{
if(io_num > 15) return;
if(mode & 0x010000) //输出
{
GPIOx->DBEN &= ~(1 << io_num); //去掉输入消抖
GPIOx->ICEN &= ~(1 << io_num); //去掉输入CMOS缓冲
GPIOx->ISEN &= ~(1 << io_num); //去掉施密特触发器
GPIOx->DIR |= 1 << io_num;
}
else //如果做为输入,必须开启CMOS或施密特
{
GPIOx->DIR &= ~(1 << io_num);
if(InMode == GPIO_IN_NONE) InMode|= GPIO_IN_CMOS; //2020-10-20 输入模式必须选择GPIO_IN_CMOS或GPIO_IN_SCHMITT,否则没法读取到IO数据
//输入消抖
if(InMode & GPIO_IN_DE_BOUNCE)
{
GPIOx->DBEN |= 1 << io_num;
}
else
{
GPIOx->DBEN &= ~(1 << io_num);
}
//输入CMOS缓冲器
if(InMode & GPIO_IN_CMOS)
{
InMode &= ~GPIO_IN_SCHMITT; //如果使能了CMOS,则去掉施密特触发器
GPIOx->ICEN |= 1 << io_num;
}
else
{
GPIOx->ICEN &= ~(1 << io_num);
}
//输入施密特触发器
if(InMode & GPIO_IN_SCHMITT)
{
GPIOx->ISEN |= 1 << io_num;
}
else
{
GPIOx->ISEN &= ~(1 << io_num);
}
}
//先清除上下拉
GPIOx->PUEN &= ~(1 << io_num);
GPIOx->PDEN &= ~(1 << io_num);
if(mode & 0x000100) //上拉
{
GPIOx->PUEN |= 1 << io_num;
}
else if(mode & 0x000200) //下拉
{
GPIOx->PDEN |= 1 << io_num;
}
}
|