C51 COMPILER V9.59.0.0 IIC 02/24/2024 21:37:53 PAGE 1 C51 COMPILER V9.59.0.0, COMPILATION OF MODULE IIC OBJECT MODULE PLACED IN .\Objects\iic.obj COMPILER INVOKED BY: D:\Keil_v5\C51\BIN\C51.EXE ..\Driver\iic.c OPTIMIZE(8,SPEED) BROWSE INCDIR(..\Driver) DEBUG OBJECTE -XTEND PRINT(.\Listings\iic.lst) TABS(2) OBJECT(.\Objects\iic.obj) line level source 1 /* # I2C代码片段说明 2 1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。 3 2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型 -运行速度和试题 4 中对单片机时钟频率的要求,进行代码调试和修改。 5 */ 6 #include "iic.h" 7 #include "intrins.h" 8 #define DELAY_TIME 5 9 sbit scl = P2 ^ 0; 10 sbit sda = P2 ^ 1; 11 // 12 static void I2C_Delay(unsigned char n) 13 { 14 1 do 15 1 { 16 2 _nop_(); 17 2 _nop_(); 18 2 _nop_(); 19 2 _nop_(); 20 2 _nop_(); 21 2 _nop_(); 22 2 _nop_(); 23 2 _nop_(); 24 2 _nop_(); 25 2 _nop_(); 26 2 _nop_(); 27 2 _nop_(); 28 2 _nop_(); 29 2 _nop_(); 30 2 _nop_(); 31 2 } while (n--); 32 1 } 33 34 // 35 void I2CStart(void) 36 { 37 1 sda = 1; 38 1 scl = 1; 39 1 I2C_Delay(DELAY_TIME); 40 1 sda = 0; 41 1 I2C_Delay(DELAY_TIME); 42 1 scl = 0; 43 1 } 44 45 // 46 void I2CStop(void) 47 { 48 1 sda = 0; 49 1 scl = 1; 50 1 I2C_Delay(DELAY_TIME); 51 1 sda = 1; 52 1 I2C_Delay(DELAY_TIME); 53 1 } C51 COMPILER V9.59.0.0 IIC 02/24/2024 21:37:53 PAGE 2 54 55 // 56 void I2CSendByte(unsigned char byt) 57 { 58 1 unsigned char i; 59 1 60 1 for (i = 0; i < 8; i++) 61 1 { 62 2 scl = 0; 63 2 I2C_Delay(DELAY_TIME); 64 2 if (byt & 0x80) 65 2 { 66 3 sda = 1; 67 3 } 68 2 else 69 2 { 70 3 sda = 0; 71 3 } 72 2 I2C_Delay(DELAY_TIME); 73 2 scl = 1; 74 2 byt <<= 1; 75 2 I2C_Delay(DELAY_TIME); 76 2 } 77 1 78 1 scl = 0; 79 1 } 80 81 // 82 unsigned char I2CReceiveByte(void) 83 { 84 1 unsigned char da; 85 1 unsigned char i; 86 1 for (i = 0; i < 8; i++) 87 1 { 88 2 scl = 1; 89 2 I2C_Delay(DELAY_TIME); 90 2 da <<= 1; 91 2 if (sda) 92 2 da |= 0x01; 93 2 scl = 0; 94 2 I2C_Delay(DELAY_TIME); 95 2 } 96 1 return da; 97 1 } 98 99 // 100 unsigned char I2CWaitAck(void) 101 { 102 1 unsigned char ackbit; 103 1 104 1 scl = 1; 105 1 I2C_Delay(DELAY_TIME); 106 1 ackbit = sda; 107 1 scl = 0; 108 1 I2C_Delay(DELAY_TIME); 109 1 110 1 return ackbit; 111 1 } 112 113 // 114 void I2CSendAck(unsigned char ackbit) 115 { C51 COMPILER V9.59.0.0 IIC 02/24/2024 21:37:53 PAGE 3 116 1 scl = 0; 117 1 sda = ackbit; 118 1 I2C_Delay(DELAY_TIME); 119 1 scl = 1; 120 1 I2C_Delay(DELAY_TIME); 121 1 scl = 0; 122 1 sda = 1; 123 1 I2C_Delay(DELAY_TIME); 124 1 } 125 126 unsigned char Ad_Read(unsigned char addr) 127 { 128 1 unsigned char temp; 129 1 // 选择芯片为PCF 130 1 I2CStart(); 131 1 I2CSendByte(0x90); 132 1 I2CWaitAck(); 133 1 I2CSendByte(addr); 134 1 I2CWaitAck(); 135 1 I2CStart(); 136 1 I2CSendByte(0x91); 137 1 I2CWaitAck(); 138 1 temp = I2CReceiveByte(); 139 1 I2CSendAck(1); 140 1 I2CStop(); 141 1 return temp; 142 1 } 143 // 写入的值是数字值0-255,而不是模拟值 144 void Da_Write(unsigned char dat) 145 { 146 1 // 选择芯片为PCF 147 1 I2CStart(); 148 1 I2CSendByte(0x90); 149 1 I2CWaitAck(); 150 1 151 1 I2CSendByte(0x41); 152 1 I2CWaitAck(); 153 1 I2CSendByte(dat); 154 1 I2CWaitAck(); 155 1 I2CStop(); 156 1 } 157 158 /// @brief EEPROM 写函数 159 /// @param EEPROM_String 写入的数组指针(如果只写入一个数据,那么要用&data) 160 /// @param addr 8的倍数 161 /// @param num 写入的数组大小 162 void EEPROM_Write(unsigned char *EEPROM_String, unsigned char addr, unsigned char num) 163 { 164 1 // 选择芯片为EEPROM,模式为写 165 1 I2CStart(); 166 1 I2CSendByte(0xA0); 167 1 I2CWaitAck(); 168 1 169 1 I2CSendByte(addr); // 写入的数据的地址 170 1 I2CWaitAck(); 171 1 while (num--) 172 1 { 173 2 I2CSendByte(*EEPROM_String++); 174 2 I2CWaitAck(); 175 2 I2C_Delay(200); 176 2 } 177 1 I2CStop(); C51 COMPILER V9.59.0.0 IIC 02/24/2024 21:37:53 PAGE 4 178 1 } 179 /// @brief EEPROM 读函数 180 /// @param EEPROM_String 读取的数组指针(如果只读取一个数据,那么要用&data) 181 /// @param addr 8的倍数 182 /// @param num 读取的数组大小 183 void EEPROM_Read(unsigned char *EEPROM_String, unsigned char addr, unsigned char num) 184 { 185 1 // 选择芯片为EEPROM,模式为写 186 1 I2CStart(); 187 1 I2CSendByte(0xA0); 188 1 I2CWaitAck(); 189 1 190 1 I2CSendByte(addr); 191 1 I2CWaitAck(); 192 1 193 1 // 选择芯片为EEPROM,模式为读 194 1 I2CStart(); 195 1 I2CSendByte(0xA1); 196 1 I2CWaitAck(); 197 1 while (num--) 198 1 { 199 2 *EEPROM_String++ = I2CReceiveByte(); 200 2 if (num) 201 2 I2CSendAck(0); 202 2 else 203 2 I2CSendAck(1); // 停止读取 204 2 } 205 1 I2CStop(); 206 1 } MODULE INFORMATION: STATIC OVERLAYABLE CODE SIZE = 378 ---- CONSTANT SIZE = ---- ---- XDATA SIZE = ---- ---- PDATA SIZE = ---- ---- DATA SIZE = ---- 10 IDATA SIZE = ---- ---- BIT SIZE = ---- ---- END OF MODULE INFORMATION. C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)