打印
[技术问答]

N76E003的iic主从机问题

[复制链接]
3366|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wlgdc|  楼主 | 2018-6-7 11:13 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
请问各位大佬,我买了两个nutiny-sdk-n76e003的开发板,用的官方给的iic主从机例子,接完后用示波器来查看SDA和SCL线的波形,结果一直显示下面这种波形,而且SDA线是黄色那条最高是3V,请问这是什么情况
评论
sofiewu 2019-1-18 10:18 回复TA
早说呀,我免费给你申请一块开发板玩玩,我是新唐一级代理商,有机会多交流沟通。 
沙发
wlgdc|  楼主 | 2018-6-7 11:16 | 只看该作者
C:\Users\luojiangtao\Desktop\rda5807m-stm32f429\IMG_20180607_111016.jpg

使用特权

评论回复
板凳
wlgdc|  楼主 | 2018-6-7 11:22 | 只看该作者
两张图贴上

2.png (581.93 KB )

连接线

连接线

1.png (616.66 KB )

示波器

示波器

使用特权

评论回复
地板
wlgdc|  楼主 | 2018-6-7 11:30 | 只看该作者
对于双向传输操作,SDA 及SCL 引脚必须配置成开漏模式,形成逻辑线与功能:总线上当有一个器件输出0,总线上就是0电平,所有器件全输出1,总线上才是高电平,需要通过外接上拉电阻把电平拉高。N76E003, 在设置I2CEN (I2CON.6)使能I2C功能之前,必须把SCL,SDA的输出锁存在逻辑1的状态。根据数据手册里这段话也在主机SDA和SCL线加了上拉电阻2K的,还有初始化也改成这样子(用原始的也代码不行),主机即使不加上面4行代码,只使能时钟和iic也不行

5.png (60.21 KB )

数据手册iic

数据手册iic

4.png (12.97 KB )

主机初始化

主机初始化

3.png (20.13 KB )

从机初始化

从机初始化

使用特权

评论回复
5
yiyigirl2014| | 2018-6-7 15:48 | 只看该作者
能否正常传输数据

使用特权

评论回复
6
yiyigirl2014| | 2018-6-7 15:48 | 只看该作者
看看这个是不是需要设置什么配置字,或者波特率要求。

使用特权

评论回复
7
tianxj01| | 2018-6-7 22:41 | 只看该作者
wlgdc 发表于 2018-6-7 11:30
对于双向传输操作,SDA 及SCL 引脚必须配置成开漏模式,形成逻辑线与功能:总线上当有一个器件输出0,总线 ...

SDA和SCL线的波形 怎么是一模一样的?SCL线应该是间隔均匀的1:1方波+一定的间隔。
上面黄色波形明显是物理短路的波形

使用特权

评论回复
8
wlgdc|  楼主 | 2018-6-8 15:15 | 只看该作者
tianxj01 发表于 2018-6-7 22:41
SDA和SCL线的波形 怎么是一模一样的?SCL线应该是间隔均匀的1:1方波+一定的间隔。
上面黄色波形明显是物 ...

好了,代码出了些问题,找厂商要最新的就可以了

使用特权

评论回复
9
wlgdc|  楼主 | 2018-6-8 15:15 | 只看该作者
yiyigirl2014 发表于 2018-6-7 15:48
看看这个是不是需要设置什么配置字,或者波特率要求。

找厂商要了最新的代码,可以了

使用特权

评论回复
10
小明的同学| | 2018-6-8 15:50 | 只看该作者
最新的是1.05版,你看看是不是。

使用特权

评论回复
评论
wlgdc 2018-6-9 11:43 回复TA
官网给的示例里有些代码是多余,直接从别的例子里拉过来,注释也没改,所以还是多配合数据手册一起看比较好,实在不行就只能问厂商= = 
11
tianxj01| | 2018-6-10 11:25 | 只看该作者
wlgdc 发表于 2018-6-7 11:30
对于双向传输操作,SDA 及SCL 引脚必须配置成开漏模式,形成逻辑线与功能:总线上当有一个器件输出0,总线 ...

所有IIC操作,必须按照接口规范,无论是单向还是双向,或者多芯片,其任何接入的SDA和SCL均必须配置为开漏,这个不容置疑。
任何不按照规范处理IIC端口的行为,都会产生不可控后果。

使用特权

评论回复
12
nannan1218| | 2019-1-17 22:58 | 只看该作者
本帖最后由 nannan1218 于 2019-1-21 08:40 编辑

。。。。

使用特权

评论回复
13
nannan1218| | 2019-1-17 22:59 | 只看该作者
本帖最后由 nannan1218 于 2019-1-21 08:40 编辑
wlgdc 发表于 2018-6-7 11:16
。。。。

使用特权

评论回复
14
nannan1218| | 2019-1-18 09:07 | 只看该作者
本帖最后由 nannan1218 于 2019-1-21 08:40 编辑

……

使用特权

评论回复
15
flove00| | 2019-1-18 17:32 | 只看该作者
本帖最后由 flove00 于 2019-1-18 17:37 编辑
nannan1218 发表于 2019-1-18 09:07
你好   我最近在搞N76E003的IIC,从官网下的代码,不行,波形总是出错,通信失败。我想求一份你的最新IIC代 ...

   刚好有用到003做I2c从机,目前使用过程中发现一些问题。当发生干扰导致i2c通信失败之后,003 i2c端口就死掉了,无法进入中断。不知道应该怎么配置i2c死掉后可以自动恢复。目前只能做i2c从机通信丢失超过1s,重置i2c端口配置来解决。有解决的童鞋请告知一下,谢谢。以下是我的代码仅供参考。



//***********************************************************************************************************
//  N76E003-series I2C slave mode demo code, the Slave address = 0xA4
//
//   ____________            _____________
//  |            |   SDA    |             |
//  |            |<-------->|             |
//  |            |          |             |
//  |029(M) |    | N76E003(S) |
//  |(I2C_Master)|          | (I2C_Slave) |
//  |            |   SCL    |             |
//  |            |--------->|             |
//  |____________|          |_____________|
//
//***********************************************************************************************************


#define EEPROM_SLA          0x86

xdata volatile unsigned char I2C_trans_data[D_I2C_length_max];
xdata volatile unsigned char I2C_rec_data[D_I2C_length_max];
xdata unsigned char I2C_SP=0;
bit F_I2C_REC_OK = 0;

//========================================================================================================
void I2C_ISR(void) interrupt 6
{
    switch (I2STAT)
    {        /*总线错误*/
        case 0x00:  //00H,bus error occurs
            STO = 1;//recover from bus error
            break;
                /*从机接受地址应答*/
        case 0x60: //60H,  own  SLA+W  received,  ACK returned
            AA = 1;//接收到正确地址并应答
                        I2C_SP = 0;
            break;
                /*从机接受仲裁失败*/               
        case 0x68://68H, arbitration lost in SLA+W/R
                        AA = 0;
                        STA = 1;//仲裁丢失,尝试重新起始信号
            break;
                 /*从机接收数据应答*/
        case 0x80:       
            I2C_rec_data[I2C_SP] = I2DAT;
            I2C_SP++;
            if (I2C_SP >=D_I2C_length_max)
            {
                          AA = 0;//最后数据不应达,应与主机匹配发送的数据长度
                          F_I2C_REC_OK = 1;
                        }
            else
                AA = 1;
            break;
            /*从机接收地址无应答*/
        case 0x88:
            I2C_rec_data[I2C_SP] = I2DAT;//好像没什么用处
            I2C_SP = 0;//等待下一次地址信号
            AA = 1;
            break;
                /*从机发送重复开始或停止信号*/
        case 0xA0:
            AA = 1;
                                                I2C_SP = 0;
            break;
                /*从机发送地址应答*/
        case 0xA8:
            I2DAT = I2C_trans_data[I2C_SP];//第一位
                                                I2C_SP=1;
            AA = 1;//读取时收到的地址正确,发送应答信号
            break;
                /*从机发送仲裁失败*/
                case 0xB0:
                        I2DAT = I2C_trans_data[I2C_SP];//虚假数据?
                        AA = 0;
                        I2C_SP = 0;
                        STA = 1;
                        break;
        /*从机发送数据应答*/
        case 0xB8:
            I2DAT = I2C_trans_data[I2C_SP];
            I2C_SP++;
            if (I2C_SP >= D_I2C_length_max)
                AA = 0;
            else
                AA = 1;
            break;
                /*从机发送数据无应答*/
        case 0xC0:
            AA = 1;
            break;
                /*从机发送最后数据应答*/
        case 0xC8:
            AA = 1;
            break;  

                                        default:
                                        {
                                                Init_I2C_Slave();
                                        };
    }
               

    SI = 0;
    while(STO);
               
}

//========================================================================================================
void Init_I2C_Slave(void)
{               
                clr_EI2C;
                clr_I2CEN;
                clr_AA;
       
    P13_Quasi_Mode;                         //set SCL (P13) is Quasi mode
    P14_Quasi_Mode;                         //set SDA (P14) is Quasi mode
   
    SDA = 1;                                //set SDA and SCL pins high
    SCL = 1;
   
    set_P1SR_3;                             //set SCL (P13) is  Schmitt triggered input select.
   
    set_EI2C;                               //enable I2C interrupt by setting IE1 bit 0
//    set_EA;

    I2ADDR = EEPROM_SLA;                    //define own slave address
    set_I2CEN;                              //enable I2C circuit
    set_AA;

        Array_Init(I2C_trans_data,D_I2C_length_max);
        Array_Init(I2C_rec_data,D_I2C_length_max);
       
        I2C_reset_cnt=D_I2C_reset_cnt;
}

主机每32ms发一次数据,若i2c从机发生错误,通信丢失1s后重置i2c端口。


xdata volatile unsigned char Comm_I2C_Rec[D_I2C_length_max];
xdata volatile unsigned char Comm_I2C_Trans[D_I2C_length_max];
xdata unsigned char I2C_test_cnt;
xdata unsigned char I2C_reset_cnt;
xdata unsigned char i2c_err=0;

void I2C_Get_Data(void)
{
        disp_data[0]=Comm_I2C_Rec[1];
        disp_data[1]=Comm_I2C_Rec[2];
        disp_data[2]=Comm_I2C_Rec[3];
}

void I2C_Send_Data(void)
{
        Comm_I2C_Trans[1]        = 1;
        Comm_I2C_Trans[2]        = 1;
        Comm_I2C_Trans[3]        = I2C_test_cnt;
        Comm_I2C_Trans[4]        = 1;
        Comm_I2C_Trans[5]        = 1;
        Comm_I2C_Trans[6]        = 1;
        Comm_I2C_Trans[7]        = 1;
}

/*主机I2C周期应选在16ms~64ms之间,若频率过快,可能会未解码完成,新的I2C
中断产生并被覆盖。
*/
void Comm_I2C_Slave(void)
{
        xdata unsigned char sum=0;
        static unsigned char err_cnt=0;
       
        if(F_I2C_REC_OK)
        {
                move_ram(I2C_rec_data,Comm_I2C_Rec,D_I2C_length_max);//复制接收到的数据
                sum = check_sum_char(Comm_I2C_Rec,(D_I2C_length_max-2));//校验
                if((Comm_I2C_Rec[0]==0xAA) &&(Comm_I2C_Rec[D_I2C_length_max-1]==0x55)
                 &&(Comm_I2C_Rec[(D_I2C_length_max-2)]==sum)
                )
                {
                        err_cnt=0;
                        I2C_Get_Data();
                        I2C_Send_Data();
                        test_disp++;
                        Comm_I2C_Trans[0] =0x55;
                        Comm_I2C_Trans[D_I2C_length_max-1]=0xAA;
                        sum = check_sum_char(Comm_I2C_Trans,(D_I2C_length_max-2));//校验
                        Comm_I2C_Trans[(D_I2C_length_max-2)]=sum;
                  move_ram(Comm_I2C_Trans,I2C_trans_data,D_I2C_length_max);//复制需要发送的数据
                       
                        I2C_reset_cnt=D_I2C_reset_cnt;
                }
                F_I2C_REC_OK = 0;
                I2C_rec_data[0]=0;
                I2C_rec_data[(D_I2C_length_max-2)]=0;
                I2C_rec_data[(D_I2C_length_max-1)]=0;
                Comm_I2C_Rec[(D_I2C_length_max-2)]=0;
                Comm_I2C_Rec[(D_I2C_length_max-1)]=0;
        }
        else
        {
                        while(SI != 0)//发生I2C总线故障时做以下处理
                        {
                                if(I2STAT == 0x00)
                                {
                                                STO = 1;
                                }
                                SI = 0;
                                if(SI != 0)
                                {
                                        I2CEN = 0;
                                        I2CEN = 1;
                                        SI = 0;
                                        I2CEN = 0;
                                }
                                err_cnt++;
                                if(err_cnt>=5)
                                {
                                        err_cnt=0;
                                        Init_I2C_Slave();
                                }
                        }
        }
       
        if(I2C_reset_cnt==0)
        {
                Init_I2C_Slave();
                F_err_I2c=1;
                i2c_err++;
        }
       
        /*
        if(F_err_I2c)
        {
                disp_data[0]=0;
          disp_data[1]=0;
                DispTemp(i2c_err,0);
        }
        */
}
/******************主机到从机的数据******************************/


//****************************从机到主机*************************************//






使用特权

评论回复
16
nannan1218| | 2019-1-19 16:17 | 只看该作者
本帖最后由 nannan1218 于 2019-1-21 08:41 编辑
flove00 发表于 2019-1-18 17:32
刚好有用到003做I2c从机,目前使用过程中发现一些问题。当发生干扰导致i2c通信失败之后,003 i2c端口就 ...

。。。。

使用特权

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

本版积分规则

1

主题

7

帖子

1

粉丝