iot-fan

联系: iotfan123#163.com
注意:
1,本博客之内容来源于网上收集以及相关技术人员提供,如果有侵犯到您的权益,请电邮我沟通;
2,本博客之内容乃分享,交流,学习,研究之目的,作者不对内容的真实性,有效性,及时性负责,也不对因本博客的任何内容导致的任何后果负责;
3,本博客之内容禁止转发到CSDN网站,转到别的网站请保留出处.

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

在沁恒家32位机(CH56x,CH57X,CH58X)中,我们发现GPIO似乎并没有一个单独的输出模式叫开漏(OD,open-drian)

在CH57x,CH58x只有下面几种模式:

/**
  * @brief  Configuration GPIO Mode
  */
typedef enum{
    GPIO_ModeIN_Floating,       //浮空输入
    GPIO_ModeIN_PU,             //上拉输入
    GPIO_ModeIN_PD,             //下拉输入
    GPIO_ModeOut_PP_5mA,        //推挽输出最大5mA
    GPIO_ModeOut_PP_20mA,       //推挽输出最大20mA
}GPIOModeTypeDef;

那么怎么实现开漏呢?

开漏的特性:

  • 输出高的时候: 悬空/ 弱上拉
  • 输出低的时候: 强吸入电流

沁恒的的GPIO模式配置函数:

这里我们只拿GPIOA来做说明

/*******************************************************************************
* Function Name  : GPIOA_ModeCfg
* Description    : GPIOA端口引脚模式配置
* Input          : pin:
                       PA0-PA15
                       GPIO_Pin_0 - GPIO_Pin_15
                   mode:
                       GPIO_ModeIN_Floating  -  浮空输入
                       GPIO_ModeIN_PU        -  上拉输入
                       GPIO_ModeIN_PD        -  下拉输入
                       GPIO_ModeOut_PP_5mA   -  推挽输出最大5mA
                       GPIO_ModeOut_PP_20mA  -  推挽输出最大20mA
* Return         : None
*******************************************************************************/
void GPIOA_ModeCfg( uint32_t pin, GPIOModeTypeDef mode ) {
    switch(mode){
        case GPIO_ModeIN_Floating:
            R32_PA_PD_DRV &= ~pin;
            R32_PA_PU     &= ~pin;
            R32_PA_DIR    &= ~pin;
            break;
        case GPIO_ModeIN_PU:
            R32_PA_PD_DRV &= ~pin;
            R32_PA_PU     |= pin;
            R32_PA_DIR    &= ~pin;
            break;
        case GPIO_ModeIN_PD:
            R32_PA_PD_DRV |= pin;
            R32_PA_PU     &= ~pin;
            R32_PA_DIR    &= ~pin;
            break;
        case GPIO_ModeOut_PP_5mA:
            R32_PA_PD_DRV &= ~pin;
            R32_PA_DIR    |= pin;
            break;
        case GPIO_ModeOut_PP_20mA:
            R32_PA_PD_DRV |= pin;
            R32_PA_DIR    |= pin;
            break;
        default:
            break;
    }
}

所以,我们只需要按照下面的方式即可实现,开漏

下面使用PB5/PB4 模拟iic 的初始化代码

初始化:

把要设置为开漏输出的IO, 初始化为输入模式,然后输出设置为低电平就行了,

#define IIC_CKL_PIN     GPIO_Pin_5
#define IIC_SDA_PIN     GPIO_Pin_4

#define ch57x_i2c_clk_init()    {   GPIOB_ModeCfg(IIC_CKL_PIN,GPIO_ModeIN_PU );\
                                    GPIOB_ResetBits(IIC_CKL_PIN);}

#define ch57x_i2c_sda_init()    {   GPIOB_ModeCfg(IIC_SDA_PIN,GPIO_ModeIN_PU );\
                                    GPIOB_ResetBits(IIC_SDA_PIN);}

使用:

通过设置IO的方向寄存器,来实现开漏的高低电平控制


#define GPIOB_PinOutput(pin)      (R32_PB_DIR    |= pin)
#define GPIOB_PinInput(pin)       (R32_PB_DIR    &= ~pin)

#define ch57x_i2c_clk_set()     {   GPIOB_PinInput(IIC_CKL_PIN);  }
#define ch57x_i2c_clk_clr()     {   GPIOB_PinOutput(IIC_CKL_PIN); }
#define ch57x_i2c_clk_get()     (   GPIOB_ReadPortPin(IIC_CKL_PIN) )

#define ch57x_i2c_sda_set()     {   GPIOB_PinInput(IIC_SDA_PIN);  }
#define ch57x_i2c_sda_clr()     {   GPIOB_PinOutput(IIC_SDA_PIN); }
#define ch57x_i2c_sda_get()     (   GPIOB_ReadPortPin(IIC_SDA_PIN))

注意事项:

  • 除了耐受5v输入的IO外,其他IO处于输入模式时,不能高于芯片的供电电压,所以如果对接5v系统的iic,尽量用耐受5v输入的IO.
  • CH57x,CH58x 系列芯片的内部上拉/下拉是50K,如果速度比较快,通常是需要挂外部上拉的.

扩展

posted on 2020-08-11 10:03  iot-fan  阅读(2040)  评论(0编辑  收藏  举报