[技术问答] N76E003的iic主从机问题

[复制链接]
 楼主| wlgdc 发表于 2018-6-7 11:13 | 显示全部楼层 |阅读模式
请问各位大佬,我买了两个nutiny-sdk-n76e003的开发板,用的官方给的iic主从机例子,接完后用示波器来查看SDA和SCL线的波形,结果一直显示下面这种波形,而且SDA线是黄色那条最高是3V,请问这是什么情况

评论

早说呀,我免费给你申请一块开发板玩玩,我是新唐一级代理商,有机会多交流沟通。  发表于 2019-1-18 10:18
 楼主| wlgdc 发表于 2018-6-7 11:16 | 显示全部楼层
C:\Users\luojiangtao\Desktop\rda5807m-stm32f429\IMG_20180607_111016.jpg
 楼主| wlgdc 发表于 2018-6-7 11:22 | 显示全部楼层
两张图贴上

示波器

示波器

连接线

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

从机初始化

从机初始化

主机初始化

主机初始化

数据手册iic

数据手册iic
yiyigirl2014 发表于 2018-6-7 15:48 | 显示全部楼层
能否正常传输数据
yiyigirl2014 发表于 2018-6-7 15:48 | 显示全部楼层
看看这个是不是需要设置什么配置字,或者波特率要求。
tianxj01 发表于 2018-6-7 22:41 | 显示全部楼层
wlgdc 发表于 2018-6-7 11:30
对于双向传输操作,SDA 及SCL 引脚必须配置成开漏模式,形成逻辑线与功能:总线上当有一个器件输出0,总线 ...

SDA和SCL线的波形 怎么是一模一样的?SCL线应该是间隔均匀的1:1方波+一定的间隔。
上面黄色波形明显是物理短路的波形
 楼主| wlgdc 发表于 2018-6-8 15:15 | 显示全部楼层
tianxj01 发表于 2018-6-7 22:41
SDA和SCL线的波形 怎么是一模一样的?SCL线应该是间隔均匀的1:1方波+一定的间隔。
上面黄色波形明显是物 ...

好了,代码出了些问题,找厂商要最新的就可以了
 楼主| wlgdc 发表于 2018-6-8 15:15 | 显示全部楼层
yiyigirl2014 发表于 2018-6-7 15:48
看看这个是不是需要设置什么配置字,或者波特率要求。

找厂商要了最新的代码,可以了
小明的同学 发表于 2018-6-8 15:50 | 显示全部楼层
最新的是1.05版,你看看是不是。

评论

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

所有IIC操作,必须按照接口规范,无论是单向还是双向,或者多芯片,其任何接入的SDA和SCL均必须配置为开漏,这个不容置疑。
任何不按照规范处理IIC端口的行为,都会产生不可控后果。
nannan1218 发表于 2019-1-17 22:58 | 显示全部楼层
本帖最后由 nannan1218 于 2019-1-21 08:40 编辑

。。。。
nannan1218 发表于 2019-1-17 22:59 来自手机 | 显示全部楼层
本帖最后由 nannan1218 于 2019-1-21 08:40 编辑
wlgdc 发表于 2018-6-7 11:16
。。。。
nannan1218 发表于 2019-1-18 09:07 | 显示全部楼层
本帖最后由 nannan1218 于 2019-1-21 08:40 编辑

……
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端口配置来解决。有解决的童鞋请告知一下,谢谢。以下是我的代码仅供参考。



  1. //***********************************************************************************************************
  2. //  N76E003-series I2C slave mode demo code, the Slave address = 0xA4
  3. //
  4. //   ____________            _____________
  5. //  |            |   SDA    |             |
  6. //  |            |<-------->|             |
  7. //  |            |          |             |
  8. //  |029(M) |    | N76E003(S) |
  9. //  |(I2C_Master)|          | (I2C_Slave) |
  10. //  |            |   SCL    |             |
  11. //  |            |--------->|             |
  12. //  |____________|          |_____________|
  13. //
  14. //***********************************************************************************************************


  15. #define EEPROM_SLA          0x86

  16. xdata volatile unsigned char I2C_trans_data[D_I2C_length_max];
  17. xdata volatile unsigned char I2C_rec_data[D_I2C_length_max];
  18. xdata unsigned char I2C_SP=0;
  19. bit F_I2C_REC_OK = 0;

  20. //========================================================================================================
  21. void I2C_ISR(void) interrupt 6
  22. {
  23.     switch (I2STAT)
  24.     {        /*总线错误*/
  25.         case 0x00:  //00H,bus error occurs
  26.             STO = 1;//recover from bus error
  27.             break;
  28.                 /*从机接受地址应答*/
  29.         case 0x60: //60H,  own  SLA+W  received,  ACK returned
  30.             AA = 1;//接收到正确地址并应答
  31.                         I2C_SP = 0;
  32.             break;
  33.                 /*从机接受仲裁失败*/               
  34.         case 0x68://68H, arbitration lost in SLA+W/R
  35.                         AA = 0;
  36.                         STA = 1;//仲裁丢失,尝试重新起始信号
  37.             break;
  38.                  /*从机接收数据应答*/
  39.         case 0x80:       
  40.             I2C_rec_data[I2C_SP] = I2DAT;
  41.             I2C_SP++;
  42.             if (I2C_SP >=D_I2C_length_max)
  43.             {
  44.                           AA = 0;//最后数据不应达,应与主机匹配发送的数据长度
  45.                           F_I2C_REC_OK = 1;
  46.                         }
  47.             else
  48.                 AA = 1;
  49.             break;
  50.             /*从机接收地址无应答*/
  51.         case 0x88:
  52.             I2C_rec_data[I2C_SP] = I2DAT;//好像没什么用处
  53.             I2C_SP = 0;//等待下一次地址信号
  54.             AA = 1;
  55.             break;
  56.                 /*从机发送重复开始或停止信号*/
  57.         case 0xA0:
  58.             AA = 1;
  59.                                                 I2C_SP = 0;
  60.             break;
  61.                 /*从机发送地址应答*/
  62.         case 0xA8:
  63.             I2DAT = I2C_trans_data[I2C_SP];//第一位
  64.                                                 I2C_SP=1;
  65.             AA = 1;//读取时收到的地址正确,发送应答信号
  66.             break;
  67.                 /*从机发送仲裁失败*/
  68.                 case 0xB0:
  69.                         I2DAT = I2C_trans_data[I2C_SP];//虚假数据?
  70.                         AA = 0;
  71.                         I2C_SP = 0;
  72.                         STA = 1;
  73.                         break;
  74.         /*从机发送数据应答*/
  75.         case 0xB8:
  76.             I2DAT = I2C_trans_data[I2C_SP];
  77.             I2C_SP++;
  78.             if (I2C_SP >= D_I2C_length_max)
  79.                 AA = 0;
  80.             else
  81.                 AA = 1;
  82.             break;
  83.                 /*从机发送数据无应答*/
  84.         case 0xC0:
  85.             AA = 1;
  86.             break;
  87.                 /*从机发送最后数据应答*/
  88.         case 0xC8:
  89.             AA = 1;
  90.             break;  

  91.                                         default:
  92.                                         {
  93.                                                 Init_I2C_Slave();
  94.                                         };
  95.     }
  96.                

  97.     SI = 0;
  98.     while(STO);
  99.                
  100. }

  101. //========================================================================================================
  102. void Init_I2C_Slave(void)
  103. {               
  104.                 clr_EI2C;
  105.                 clr_I2CEN;
  106.                 clr_AA;
  107.        
  108.     P13_Quasi_Mode;                         //set SCL (P13) is Quasi mode
  109.     P14_Quasi_Mode;                         //set SDA (P14) is Quasi mode
  110.    
  111.     SDA = 1;                                //set SDA and SCL pins high
  112.     SCL = 1;
  113.    
  114.     set_P1SR_3;                             //set SCL (P13) is  Schmitt triggered input select.
  115.    
  116.     set_EI2C;                               //enable I2C interrupt by setting IE1 bit 0
  117. //    set_EA;

  118.     I2ADDR = EEPROM_SLA;                    //define own slave address
  119.     set_I2CEN;                              //enable I2C circuit
  120.     set_AA;

  121.         Array_Init(I2C_trans_data,D_I2C_length_max);
  122.         Array_Init(I2C_rec_data,D_I2C_length_max);
  123.        
  124.         I2C_reset_cnt=D_I2C_reset_cnt;
  125. }

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


  1. xdata volatile unsigned char Comm_I2C_Rec[D_I2C_length_max];
  2. xdata volatile unsigned char Comm_I2C_Trans[D_I2C_length_max];
  3. xdata unsigned char I2C_test_cnt;
  4. xdata unsigned char I2C_reset_cnt;
  5. xdata unsigned char i2c_err=0;

  6. void I2C_Get_Data(void)
  7. {
  8.         disp_data[0]=Comm_I2C_Rec[1];
  9.         disp_data[1]=Comm_I2C_Rec[2];
  10.         disp_data[2]=Comm_I2C_Rec[3];
  11. }

  12. void I2C_Send_Data(void)
  13. {
  14.         Comm_I2C_Trans[1]        = 1;
  15.         Comm_I2C_Trans[2]        = 1;
  16.         Comm_I2C_Trans[3]        = I2C_test_cnt;
  17.         Comm_I2C_Trans[4]        = 1;
  18.         Comm_I2C_Trans[5]        = 1;
  19.         Comm_I2C_Trans[6]        = 1;
  20.         Comm_I2C_Trans[7]        = 1;
  21. }

  22. /*主机I2C周期应选在16ms~64ms之间,若频率过快,可能会未解码完成,新的I2C
  23. 中断产生并被覆盖。
  24. */
  25. void Comm_I2C_Slave(void)
  26. {
  27.         xdata unsigned char sum=0;
  28.         static unsigned char err_cnt=0;
  29.        
  30.         if(F_I2C_REC_OK)
  31.         {
  32.                 move_ram(I2C_rec_data,Comm_I2C_Rec,D_I2C_length_max);//复制接收到的数据
  33.                 sum = check_sum_char(Comm_I2C_Rec,(D_I2C_length_max-2));//校验
  34.                 if((Comm_I2C_Rec[0]==0xAA) &&(Comm_I2C_Rec[D_I2C_length_max-1]==0x55)
  35.                  &&(Comm_I2C_Rec[(D_I2C_length_max-2)]==sum)
  36.                 )
  37.                 {
  38.                         err_cnt=0;
  39.                         I2C_Get_Data();
  40.                         I2C_Send_Data();
  41.                         test_disp++;
  42.                         Comm_I2C_Trans[0] =0x55;
  43.                         Comm_I2C_Trans[D_I2C_length_max-1]=0xAA;
  44.                         sum = check_sum_char(Comm_I2C_Trans,(D_I2C_length_max-2));//校验
  45.                         Comm_I2C_Trans[(D_I2C_length_max-2)]=sum;
  46.                   move_ram(Comm_I2C_Trans,I2C_trans_data,D_I2C_length_max);//复制需要发送的数据
  47.                        
  48.                         I2C_reset_cnt=D_I2C_reset_cnt;
  49.                 }
  50.                 F_I2C_REC_OK = 0;
  51.                 I2C_rec_data[0]=0;
  52.                 I2C_rec_data[(D_I2C_length_max-2)]=0;
  53.                 I2C_rec_data[(D_I2C_length_max-1)]=0;
  54.                 Comm_I2C_Rec[(D_I2C_length_max-2)]=0;
  55.                 Comm_I2C_Rec[(D_I2C_length_max-1)]=0;
  56.         }
  57.         else
  58.         {
  59.                         while(SI != 0)//发生I2C总线故障时做以下处理
  60.                         {
  61.                                 if(I2STAT == 0x00)
  62.                                 {
  63.                                                 STO = 1;
  64.                                 }
  65.                                 SI = 0;
  66.                                 if(SI != 0)
  67.                                 {
  68.                                         I2CEN = 0;
  69.                                         I2CEN = 1;
  70.                                         SI = 0;
  71.                                         I2CEN = 0;
  72.                                 }
  73.                                 err_cnt++;
  74.                                 if(err_cnt>=5)
  75.                                 {
  76.                                         err_cnt=0;
  77.                                         Init_I2C_Slave();
  78.                                 }
  79.                         }
  80.         }
  81.        
  82.         if(I2C_reset_cnt==0)
  83.         {
  84.                 Init_I2C_Slave();
  85.                 F_err_I2c=1;
  86.                 i2c_err++;
  87.         }
  88.        
  89.         /*
  90.         if(F_err_I2c)
  91.         {
  92.                 disp_data[0]=0;
  93.           disp_data[1]=0;
  94.                 DispTemp(i2c_err,0);
  95.         }
  96.         */
  97. }
  98. /******************主机到从机的数据******************************/


  99. //****************************从机到主机*************************************//






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

粉丝
快速回复 在线客服 返回列表 返回顶部