嵌入式学习小组
直播中

efwedfd

8年用户 999经验值
擅长:EMC/EMI设计
私信 关注

NUC970通用GPIO输入数据无法反应IO状态的原因?

测试发现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
* 作者                        :        
* 时间                        :        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;
        }
        
}




//GPIO模式定义 第三个8位:输入输出; 第二个8位:上下拉; 第一个8位 输入类型
typedef enum
{
        OUT_PP                        =        0x010000,                //推挽输出
        OUT_PP_OPU                =        0x010100,                //上拉推挽输出
        OUT_PP_OPD                =        0x010200,                //下拉推挽输出
        
        IN_FLOAtiNG         =        0x000000,                //浮空输入
        IN_IPU                        =        0x000100,                //上拉输入
        IN_IPD                        =        0x000200,                //下拉输入
}SYS_GPIO_MODE;
//输入模式
#define GPIO_IN_NONE                0                        //默认的输入模式
#define GPIO_IN_DE_BOUNCE        (1<<0)                //输入消抖
#define GPIO_IN_CMOS                (1<<1)                //CMOS输入缓冲与施密特触发器只能二选一
#define GPIO_IN_SCHMITT                (1<<2)                //施密特触发器


SYS_GPIOx_OneInit(GPIOA,1,IN_FLOATING,GPIO_IN_CMOS)//SDA输入模式

回帖(1)

其实znvm

2023-10-23 09:58:49
ode_TypeDef io_mode, SYS_GPIO_Type_TypeDef io_type)

这个函数用于初始化一个GPIO口的参数,包括输入输出模式、上拉下拉、施密特触发等等。其中,io_mode参数对应的是输入模式/输出模式,io_type参数对应的是CMOS缓冲区/施密特触发/普通IO等。如果没有开启CMOS缓冲区或者施密特触发,那么就需要在初始化时设置对应的参数。

另外,手册上没有提到这个问题可能是因为这个问题是比较特殊的,一般情况下GPIO的输入输出都不会出现这个问题。如果遇到了类似的问题,可以根据具体情况开启对应的参数。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分