C51 COMPILER V9.59.0.0 I2C 03/09/2021 14:05:10 PAGE 1 C51 COMPILER V9.59.0.0, COMPILATION OF MODULE I2C OBJECT MODULE PLACED IN .\list\I2C.obj COMPILER INVOKED BY: C:\Keil_v5\C51\BIN\C51.EXE I2C.c OPTIMIZE(8,SPEED) BROWSE DEBUG OBJECTEXTEND PRINT(.\list\I2C.lst) -TABS(2) OBJECT(.\list\I2C.obj) line level source 1 /*---------------------------------------------------------------------*/ 2 /* --- STC MCU Limited ------------------------------------------------*/ 3 /* --- STC 1T Series MCU Demo Programme -------------------------------*/ 4 /* --- Mobile: (86)13922805190 ----------------------------------------*/ 5 /* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/ 6 /* --- Tel: 86-0513-55012928,55012929,55012966 ------------------------*/ 7 /* --- Web: www.STCMCU.com --------------------------------------------*/ 8 /* --- Web: www.STCMCUDATA.com ---------------------------------------*/ 9 /* --- QQ: 800003751 -------------------------------------------------*/ 10 /* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序 */ 11 /*---------------------------------------------------------------------*/ 12 13 #include "I2C.h" 14 15 #define Software_I2C //使能软件模拟I2C 16 17 u8 I2C_BUF_type I2C_Buffer[I2C_BUF_LENTH]; 18 I2C_IsrTypeDef I2CIsr; 19 20 extern bit DisplayFlag; 21 22 //======================================================================== 23 // 函数: void I2C_Init(I2C_InitTypeDef *I2Cx) 24 // 描述: I2C初始化程序. 25 // 参数: I2Cx: 结构参数,请参考I2C.h里的定义. 26 // 返回: none. 27 // 版本: V1.0, 2020-09-16 28 //======================================================================== 29 void I2C_Init(I2C_InitTypeDef *I2Cx) 30 { 31 1 EAXSFR(); /* MOVX A,@DPTR/MOVX @DPTR,A指令的操作对象为扩展SFR(XSFR) */ 32 1 33 1 if(I2Cx->I2C_Mode == I2C_Mode_Master) 34 1 { 35 2 I2C_Master(); //设为主机 36 2 I2CMSST = 0x00; //清除I2C主机状态寄存器 37 2 I2C_Master_Inturrupt(I2Cx->I2C_MS_Interrupt); 38 2 I2C_SetSpeed(I2Cx->I2C_Speed); 39 2 if(I2Cx->I2C_MS_WDTA == ENABLE) I2C_WDTA_EN(); //使能自动发送 40 2 else I2C_WDTA_DIS(); //禁止自动发送 41 2 } 42 1 else 43 1 { 44 2 I2C_Slave(); //设为从机 45 2 I2CSLST = 0x00; //清除I2C从机状态寄存器 46 2 if(I2Cx->I2C_SL_ESTAI == ENABLE) I2C_ESTAI_EN(); //使能从机接收START信号中断 47 2 else I2C_ESTAI_DIS(); //禁止从机接收START信号中断 48 2 if(I2Cx->I2C_SL_ERXI == ENABLE) I2C_ERXI_EN(); //使能从机接收1字节数据中断 49 2 else I2C_ERXI_DIS(); //禁止从机接收1字节数据中断 50 2 if(I2Cx->I2C_SL_ETXI == ENABLE) I2C_ETXI_EN(); //使能从机发送1字节数据中断 51 2 else I2C_ETXI_DIS(); //禁止从机发送1字节数据中断 52 2 if(I2Cx->I2C_SL_ESTOI == ENABLE) I2C_ESTOI_EN(); //使能从机接收STOP信号中断 53 2 else I2C_ESTOI_DIS(); //禁止从机接收STOP信号中断 54 2 I2C_Address(I2Cx->I2C_SL_ADR); C51 COMPILER V9.59.0.0 I2C 03/09/2021 14:05:10 PAGE 2 55 2 if(I2Cx->I2C_SL_MA == ENABLE) I2C_MATCH_EN(); //从机地址比较功能,只接受相匹配地址 56 2 else I2C_MATCH_DIS(); //禁止从机地址比较功能,接受所有设备地址 57 2 } 58 1 59 1 P_SW2 = (P_SW2 & ~(3<<4)) | I2Cx->I2C_IoUse; 60 1 I2C_Function(I2Cx->I2C_Enable); 61 1 62 1 I2CIsr.isda = 1; 63 1 I2CIsr.isma = 1; 64 1 I2CIsr.addr = 0; 65 1 I2CTXD = I2C_Buffer[I2CIsr.addr]; 66 1 67 1 EAXRAM(); /* MOVX A,@DPTR/MOVX @DPTR,A指令的操作对象为扩展RAM(XRAM) */ 68 1 } 69 70 #ifdef Software_I2C 71 72 #define SLAW 0x5A 73 #define SLAR 0x5B 74 75 sbit SDA = P0^1; //定义SDA 76 sbit SCL = P0^0; //定义SCL 77 78 /****************************/ 79 void I2C_Delay(void) //for normal MCS51, delay (2 * dly + 4) T, for STC12Cxxxx delay (4 * dly + 10) T 80 { 81 1 u8 dly; 82 1 dly = MAIN_Fosc / 2000000UL; //按2us计算 83 1 while(--dly); 84 1 } 85 86 /****************************/ 87 void I2C_Start(void) //start the I2C, SDA High-to-low when SCL is high 88 { 89 1 SDA = 1; 90 1 I2C_Delay(); 91 1 SCL = 1; 92 1 I2C_Delay(); 93 1 SDA = 0; 94 1 I2C_Delay(); 95 1 SCL = 0; 96 1 I2C_Delay(); 97 1 } 98 99 100 void I2C_Stop(void) //STOP the I2C, SDA Low-to-high when SCL is high 101 { 102 1 SDA = 0; 103 1 I2C_Delay(); 104 1 SCL = 1; 105 1 I2C_Delay(); 106 1 SDA = 1; 107 1 I2C_Delay(); 108 1 } 109 110 void S_ACK(void) //Send ACK (LOW) 111 { 112 1 SDA = 0; 113 1 I2C_Delay(); 114 1 SCL = 1; 115 1 I2C_Delay(); 116 1 SCL = 0; C51 COMPILER V9.59.0.0 I2C 03/09/2021 14:05:10 PAGE 3 117 1 I2C_Delay(); 118 1 } 119 120 void S_NoACK(void) //Send No ACK (High) 121 { 122 1 SDA = 1; 123 1 I2C_Delay(); 124 1 SCL = 1; 125 1 I2C_Delay(); 126 1 SCL = 0; 127 1 I2C_Delay(); 128 1 } 129 130 void I2C_Check_ACK(void) //Check ACK, If F0=0, then right, if F0=1, then error 131 { 132 1 SDA = 1; 133 1 I2C_Delay(); 134 1 SCL = 1; 135 1 I2C_Delay(); 136 1 F0 = SDA; 137 1 SCL = 0; 138 1 I2C_Delay(); 139 1 } 140 141 /****************************/ 142 void I2C_WriteAbyte(u8 dat) //write a byte to I2C 143 { 144 1 u8 i; 145 1 i = 8; 146 1 do 147 1 { 148 2 if(dat & 0x80) SDA = 1; 149 2 else SDA = 0; 150 2 dat <<= 1; 151 2 I2C_Delay(); 152 2 SCL = 1; 153 2 I2C_Delay(); 154 2 SCL = 0; 155 2 I2C_Delay(); 156 2 } 157 1 while(--i); 158 1 } 159 160 /****************************/ 161 u8 I2C_ReadAbyte(void) //read A byte from I2C 162 { 163 1 u8 i,dat; 164 1 i = 8; 165 1 SDA = 1; 166 1 do 167 1 { 168 2 SCL = 1; 169 2 I2C_Delay(); 170 2 dat <<= 1; 171 2 if(SDA) dat++; 172 2 SCL = 0; 173 2 I2C_Delay(); 174 2 } 175 1 while(--i); 176 1 return(dat); 177 1 } 178 C51 COMPILER V9.59.0.0 I2C 03/09/2021 14:05:10 PAGE 4 179 /****************************/ 180 void WriteNbyte(u8 addr, u8 *p, u8 number) /* WordAddress,First Data Address,Byte lenth */ 181 { 182 1 I2C_Start(); 183 1 I2C_WriteAbyte(SLAW); 184 1 I2C_Check_ACK(); 185 1 if(!F0) //F0=0,right, F0=1,error 186 1 { 187 2 I2C_WriteAbyte(addr); 188 2 I2C_Check_ACK(); 189 2 if(!F0) 190 2 { 191 3 do 192 3 { 193 4 I2C_WriteAbyte(*p); p++; 194 4 I2C_Check_ACK(); 195 4 if(F0) break; 196 4 } 197 3 while(--number); 198 3 } 199 2 } 200 1 I2C_Stop(); 201 1 } 202 203 204 /****************************/ 205 void ReadNbyte(u8 addr, u8 *p, u8 number) /* WordAddress,First Data Address,Byte lenth */ 206 { 207 1 I2C_Start(); 208 1 I2C_WriteAbyte(SLAW); 209 1 I2C_Check_ACK(); 210 1 if(!F0) 211 1 { 212 2 I2C_WriteAbyte(addr); 213 2 I2C_Check_ACK(); 214 2 if(!F0) 215 2 { 216 3 I2C_Start(); 217 3 I2C_WriteAbyte(SLAR); 218 3 I2C_Check_ACK(); 219 3 if(!F0) 220 3 { 221 4 do 222 4 { 223 5 *p = I2C_ReadAbyte(); p++; 224 5 if(number != 1) S_ACK(); //send ACK 225 5 } 226 4 while(--number); 227 4 S_NoACK(); //send no ACK 228 4 } 229 3 } 230 2 } 231 1 I2C_Stop(); 232 1 } 233 234 #else #define SLAW 0xA2 #define SLAR 0xA3 //======================================================================== // 函数: void Wait (void) // 描述: 等待主机模式I2C控制器执行完成I2CMSCR. C51 COMPILER V9.59.0.0 I2C 03/09/2021 14:05:10 PAGE 5 // 参数: none. // 返回: none. // 版本: V1.0, 2012-11-22 //======================================================================== void Wait() { while (!(I2CMSST & 0x40)); I2CMSST &= ~0x40; } //======================================================================== // 函数: void Start (void) // 描述: I2C总线起始函数. // 参数: none. // 返回: none. // 版本: V1.0, 2020-09-15 //======================================================================== void Start() { I2CMSCR = 0x01; //发送START命令 Wait(); } //======================================================================== // 函数: void SendData (char dat) // 描述: I2C发送一个字节数据函数. // 参数: 发送的数据. // 返回: none. // 版本: V1.0, 2020-09-15 //======================================================================== void SendData(char dat) { I2CTXD = dat; //写数据到数据缓冲区 I2CMSCR = 0x02; //发送SEND命令 Wait(); } //======================================================================== // 函数: void RecvACK (void) // 描述: I2C获取ACK函数. // 参数: none. // 返回: none. // 版本: V1.0, 2020-09-15 //======================================================================== void RecvACK() { I2CMSCR = 0x03; //发送读ACK命令 Wait(); } //======================================================================== // 函数: char RecvData (void) // 描述: I2C读取一个字节数据函数. // 参数: none. // 返回: 读取数据. // 版本: V1.0, 2020-09-15 //======================================================================== char RecvData() { I2CMSCR = 0x04; //发送RECV命令 Wait(); return I2CRXD; C51 COMPILER V9.59.0.0 I2C 03/09/2021 14:05:10 PAGE 6 } //======================================================================== // 函数: void SendACK (void) // 描述: I2C发送ACK函数. // 参数: none. // 返回: none. // 版本: V1.0, 2020-09-15 //======================================================================== void SendACK() { I2CMSST = 0x00; //设置ACK信号 I2CMSCR = 0x05; //发送ACK命令 Wait(); } //======================================================================== // 函数: void SendNAK (void) // 描述: I2C发送NAK函数. // 参数: none. // 返回: none. // 版本: V1.0, 2020-09-15 //======================================================================== void SendNAK() { I2CMSST = 0x01; //设置NAK信号 I2CMSCR = 0x05; //发送ACK命令 Wait(); } //======================================================================== // 函数: void Stop (void) // 描述: I2C总线停止函数. // 参数: none. // 返回: none. // 版本: V1.0, 2020-09-15 //======================================================================== void Stop() { I2CMSCR = 0x06; //发送STOP命令 Wait(); } //======================================================================== // 函数: void WriteNbyte(u8 addr, u8 *p, u8 number) // 描述: I2C写入数据函数. // 参数: addr: 指定地址, *p写入数据存储位置, number写入数据个数. // 返回: none. // 版本: V1.0, 2020-09-15 //======================================================================== void WriteNbyte(u8 addr, u8 *p, u8 number) /* WordAddress,First Data Address,Byte lenth */ { EAXSFR(); /* MOVX A,@DPTR/MOVX @DPTR,A指令的操作对象为扩展SFR(XSFR) */ Start(); //发送起始命令 SendData(SLAW); //发送设备地址+写命令 RecvACK(); SendData(addr); //发送存储地址 RecvACK(); do { SendData(*p++); RecvACK(); C51 COMPILER V9.59.0.0 I2C 03/09/2021 14:05:10 PAGE 7 } while(--number); Stop(); //发送停止命令 EAXRAM(); /* MOVX A,@DPTR/MOVX @DPTR,A指令的操作对象为扩展RAM(XRAM) */ } //======================================================================== // 函数: void ReadNbyte(u8 addr, u8 *p, u8 number) // 描述: I2C读取数据函数. // 参数: addr: 指定地址, *p读取数据存储位置, number读取数据个数. // 返回: none. // 版本: V1.0, 2020-09-15 //======================================================================== void ReadNbyte(u8 addr, u8 *p, u8 number) /* WordAddress,First Data Address,Byte lenth */ { EAXSFR(); /* MOVX A,@DPTR/MOVX @DPTR,A指令的操作对象为扩展SFR(XSFR) */ Start(); //发送起始命令 SendData(SLAW); //发送设备地址+写命令 RecvACK(); SendData(addr); //发送存储地址 RecvACK(); Start(); //发送起始命令 SendData(SLAR); //发送设备地址+读命令 RecvACK(); do { *p = RecvData(); p++; if(number != 1) SendACK(); //send ACK } while(--number); SendNAK(); //send no ACK Stop(); //发送停止命令 EAXRAM(); /* MOVX A,@DPTR/MOVX @DPTR,A指令的操作对象为扩展RAM(XRAM) */ } #endif 402 //======================================================================== 403 // 函数: void I2C_Isr (void) interrupt I2C_VECTOR 404 // 描述: I2C中断函数. 405 // 参数: none. 406 // 返回: none. 407 // 版本: V1.0, 2020-09-15 408 //======================================================================== 409 void I2C_Isr() interrupt I2C_VECTOR 410 { 411 1 char store; 412 1 413 1 store = P_SW2; 414 1 P_SW2 |= 0x80; 415 1 416 1 if (I2CSLST & 0x40) 417 1 { 418 2 I2CSLST &= ~0x40; //处理START事件 419 2 } 420 1 else if (I2CSLST & 0x20) 421 1 { 422 2 I2CSLST &= ~0x20; //处理RECV事件,SLACKO设置为0 423 2 if (I2CIsr.isda) 424 2 { 425 3 I2CIsr.isda = 0; //处理RECV事件(RECV DEVICE ADDR) 426 3 } C51 COMPILER V9.59.0.0 I2C 03/09/2021 14:05:10 PAGE 8 427 2 else if (I2CIsr.isma) 428 2 { 429 3 I2CIsr.isma = 0; //处理RECV事件(RECV MEMORY ADDR) 430 3 I2CIsr.addr = I2CRXD; 431 3 I2CTXD = I2C_Buffer[I2CIsr.addr]; 432 3 } 433 2 else 434 2 { 435 3 I2C_Buffer[I2CIsr.addr++] = I2CRXD; //处理RECV事件(RECV DATA) 436 3 } 437 2 } 438 1 else if (I2CSLST & 0x10) 439 1 { 440 2 I2CSLST &= ~0x10; //处理SEND事件 441 2 if (I2CSLST & 0x02) 442 2 { 443 3 I2CTXD = 0xff; 444 3 } 445 2 else 446 2 { 447 3 I2CTXD = I2C_Buffer[++I2CIsr.addr]; 448 3 } 449 2 } 450 1 else if (I2CSLST & 0x08) 451 1 { 452 2 I2CSLST &= ~0x08; //处理STOP事件 453 2 I2CIsr.isda = 1; 454 2 I2CIsr.isma = 1; 455 2 DisplayFlag = 1; 456 2 } 457 1 458 1 P_SW2 = store; 459 1 } 460 MODULE INFORMATION: STATIC OVERLAYABLE CODE SIZE = 698 ---- CONSTANT SIZE = ---- ---- XDATA SIZE = 128 ---- PDATA SIZE = ---- ---- DATA SIZE = 3 10 IDATA SIZE = ---- ---- BIT SIZE = ---- ---- END OF MODULE INFORMATION. C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)