举报
示波器
连接线
从机初始化
主机初始化
数据手册iic
wlgdc 发表于 2018-6-7 11:30 对于双向传输操作,SDA 及SCL 引脚必须配置成开漏模式,形成逻辑线与功能:总线上当有一个器件输出0,总线 ...
tianxj01 发表于 2018-6-7 22:41 SDA和SCL线的波形 怎么是一模一样的?SCL线应该是间隔均匀的1:1方波+一定的间隔。 上面黄色波形明显是物 ...
yiyigirl2014 发表于 2018-6-7 15:48 看看这个是不是需要设置什么配置字,或者波特率要求。
wlgdc 发表于 2018-6-7 11:16
nannan1218 发表于 2019-1-18 09:07 你好 我最近在搞N76E003的IIC,从官网下的代码,不行,波形总是出错,通信失败。我想求一份你的最新IIC代 ...
//*********************************************************************************************************** // 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); } */ } /******************主机到从机的数据******************************/ //****************************从机到主机*************************************//
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); } */ } /******************主机到从机的数据******************************/ //****************************从机到主机*************************************//
flove00 发表于 2019-1-18 17:32 刚好有用到003做I2c从机,目前使用过程中发现一些问题。当发生干扰导致i2c通信失败之后,003 i2c端口就 ...
本版积分规则 发表回复 回帖并转播 回帖后跳转到最后一页
人才类勋章
时间类勋章
1
7
扫码关注 21ic 官方微信
扫码关注嵌入式微处理器
扫码关注电源系统设计
扫码关注21ic项目外包
扫码浏览21ic手机版
本站介绍 | 申请友情链接 | 欢迎投稿 | 隐私声明 | 广告业务 | 网站地图 | 联系我们 | 诚聘英才
京公网安备 11010802024343号