打印
[技术问答]

76e003 P1.3 P1.4开漏输出上升沿缓慢

[复制链接]
1096|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
请教各位大师,我用003  P1.3 P1.4 开漏输出做模拟I2C,上拉电阻4.7K(试过1K有改善,但不能彻底解决),外面只挂了个PCF8563,4us的高电平由于上升沿不够陡峭,变成了尖顶,用推挽输出可以很快。请知道的告诉一声,感激不尽!

使用特权

评论回复
沙发
tianxj01| | 2019-8-22 18:33 | 只看该作者
上升沿慢很正常,开漏如果负载容性比较大,或者哪怕走线走的长,对VCC、GND分布电容大点,上升沿就不会陡峭,你只是挂了一个IIC设备,测试过,在IIC线布线合适,长度100mm以内,标准的3.3K上拉就完全可以实现400KHz的IIC最高频率,这时候时钟才2.5uS呢,时钟的样子是一个上升沿稍慢的,顶部变成尖顶但是满幅度,由于标准硬件IIC是在上升沿和下降沿的一段时间,而尖顶的折合到门槛电压由至少1/2时钟宽度的有效时间,因此该样子时钟通讯完全正常。
你是软件模拟IIC,则可能时序上面处理不合理,会导致IIC数据处理容错性比较差。
到1K都改善不多,完全说明你的软IIC处理时序有问题。
注意IIC信号采集是在SCL上下沿之间采集SDA数据。如果是输出,则SDA数据的准备,必须在时钟低电平的时间的一半时刻完成。

使用特权

评论回复
板凳
wahahaheihei| | 2019-8-22 21:01 | 只看该作者
赶紧换了吧,用ML51或者MS51

使用特权

评论回复
地板
wahahaheihei| | 2019-8-22 21:01 | 只看该作者

MS51或者ML51被官方的PIN配置软件支持。

使用特权

评论回复
5
598330983| | 2019-8-24 10:21 | 只看该作者
你要算算实际上应该多少。

使用特权

评论回复
6
643757107| | 2019-8-24 10:24 | 只看该作者
这个要这么快是干啥的

使用特权

评论回复
7
xuanhuanzi| | 2019-8-24 10:37 | 只看该作者
003好像是有I2C的吧

使用特权

评论回复
8
21mengnan| | 2019-8-25 21:45 | 只看该作者
直接试试官方的

使用特权

评论回复
9
21mengnan| | 2019-8-25 21:45 | 只看该作者
/*---------------------------------------------------------------------------------------------------------*/
/*                                                                                                         */
/* Copyright(c) 2017 Nuvoton Technology Corp. All rights reserved.                                         */
/*                                                                                                         */
/*---------------------------------------------------------------------------------------------------------*/

//***********************************************************************************************************
//  Nuvoton Technoledge Corp.
//  Website: http://www.nuvoton.com
//  E-Mail : MicroC-8bit@nuvoton.com
//  Date   : Apr/29/2017
//***********************************************************************************************************

//***********************************************************************************************************
//  File Function: N76E003 I2C master mode demo code, the Slave address = 0xA4
//
//   ____________            _____________
//  |            |   SDA    |             |
//  |            |<-------->|             |
//  |            |          |             |
//  |N76E003(M) |          | N76E003(S) |
//  |(I2C_Master)|          | (I2C_Slave) |
//  |            |   SCL    |             |
//  |            |--------->|             |
//  |____________|          |_____________|
//
//  The protocol of I2C is same the "24LC64"
//***********************************************************************************************************


#include "N76E003.h"
#include "Common.h"
#include "Delay.h"
#include "SFR_Macro.h"
#include "Function_define.h"

#define I2C_CLOCK               13
#define EEPROM_SLA              0xA4
#define EEPROM_WR               0
#define EEPROM_RD               1
#define ERROR_CODE              0x78
#define PAGE_SIZE               32

//========================================================================================================
void Init_I2C(void)
{
//    /* Set I2C clock rate */
    I2CLK = I2C_CLOCK;

    /* Enable I2C */
    set_I2CEN;                                   
}
//========================================================================================================
void I2C_Error(void)
{
//    P3 = I2STAT;
//    P3 = ERROR_CODE;
    while (1);   
}
//========================================================================================================
void I2C_Process(UINT8 u8DAT)
{
    UINT32 u32Count;

//--------------------------------------------------------------------------------------------
//----  Page Write----------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
    /* Step1 */
    set_STA;                                    /* Send Start bit to I2C EEPROM */
    clr_SI;
    while (!SI);                                //Check SI set or not
    if (I2STAT != 0x08)                         //Check status value after every step
        I2C_Error();
   
    /* Step2 */
    clr_STA;                                    //STA=0
    I2DAT = (EEPROM_SLA | EEPROM_WR);
    clr_SI;
    while (!SI);                                //Check SI set or not
    if (I2STAT != 0x18)              
        I2C_Error();

    /* Step3 */
    I2DAT = 0x00;                               //address high for I2C EEPROM
    clr_SI;
    while (!SI);                                //Check SI set or not
    if (I2STAT != 0x28)              
        I2C_Error();
                    
    /* Step4 */
    I2DAT = 0x00;                               //address low for I2C EEPROM
    clr_SI;
    while (!SI);                                //Check SI set or not
    if (I2STAT != 0x28)              
        I2C_Error();

    /* Step5 */
    for (u32Count = 0; u32Count < PAGE_SIZE; u32Count++)
    {
        I2DAT = u8DAT;
        clr_SI;
        while (!SI);                            //Check SI set or not
        if (I2STAT != 0x28)              
            I2C_Error();

        u8DAT = ~u8DAT;        
    }

//--------------------------------------------------------------------------------------------
//----  Waitting the ready for I2C write------------------------------------------------------
//--------------------------------------------------------------------------------------------
    /* Step6 */
    do{
        set_STO;
        clr_SI;
        
        set_STA;                                //Check if no ACK is returned by EEPROM, it is under timed-write cycle
        clr_SI;
        while (!SI);                            //Check SI set or not
        if (I2STAT != 0x08)                     //Check status value after every step
            I2C_Error();

        clr_STA;
        I2DAT = (EEPROM_SLA | EEPROM_WR);
        clr_SI;
        while (!SI);                            //Check SI set or not
    }while (I2STAT != 0x18);
   
    /* Step7 */
    set_STO;
    clr_SI;
    while (STO);                                /* Check STOP signal */
//--------------------------------------------------------------------------------------------
//----  Page Read ----------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
    /* Step8 */
    set_STA;
    clr_SI;         
    while (!SI);                                //Check SI set or not
    if (I2STAT != 0x08)                         //Check status value after every step
        I2C_Error();

    /* Step9 */
    I2DAT = (EEPROM_SLA | EEPROM_WR);
    clr_STA;
    clr_SI;
    while (!SI);                                //Check SI set or not
    if (I2STAT != 0x18)              
        I2C_Error();

    /* Step10 */
    I2DAT = 0x00;                               //address high for I2C EEPROM
    clr_SI;
    while (!SI);                                //Check SI set or not
    if (I2STAT != 0x28)              
        I2C_Error();

    /* Step11 */
    I2DAT = 0x00;                               //address low for I2C EEPROM
    clr_SI;
    while (!SI);                                //Check SI set or not
    if (I2STAT != 0x28)              
        I2C_Error();

    /* Step12 */
    /* Repeated START */
    set_STA;                       
    clr_SI;
    while (!SI);                                //Check SI set or not
    if (I2STAT != 0x10)                         //Check status value after every step
        I2C_Error();
   
    /* Step13 */
    clr_STA;                                    //STA needs to be cleared after START codition is generated
    I2DAT = (EEPROM_SLA | EEPROM_RD);
    clr_SI;
    while (!SI);                                //Check SI set or not
    if (I2STAT != 0x40)              
        I2C_Error();
   
    /* Step14 */
    for (u32Count = 0; u32Count <PAGE_SIZE-1; u32Count++)
    {
        set_AA;
        clr_SI;        
        while (!SI);                            //Check SI set or not

        if (I2STAT != 0x50)              
            I2C_Error();
        
        if (I2DAT != u8DAT)            
            I2C_Error();
        u8DAT = ~u8DAT;
    }
   
    /* Step15 */
    clr_AA;
    clr_SI;
    while (!SI);                                //Check SI set or not
    if (I2STAT != 0x58)              
        I2C_Error();

    /* Step16 */
    set_STO;
    clr_SI;
    while (STO);                                /* Check STOP signal */
}
//========================================================================================================
void main(void)
{
    /* Note
       MCU power on system clock is HIRC (22.1184MHz), so Fsys = 22.1184MHz
    */
   
    Set_All_GPIO_Quasi_Mode;       
    Init_I2C();                                 //initial I2C circuit
    I2C_Process(0x55);                          /* I2C Master will send 0x55,0xAA,.... to slave */
   
    P0 = 0x00;
    P3 = 0x00;
   
    while (1);
/* =================== */
}

使用特权

评论回复
10
gx_huang| | 2019-8-26 10:53 | 只看该作者
硬件问题硬件方式分析,无非就是RC的充放电波形,如果1K了,上升沿时间还是太长,肯定是总线的电容太大了。
这个完全可以计算的。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

3

帖子

0

粉丝