📄 i2c.lst
字号:
C51 COMPILER V8.08 I2C 05/21/2008 20:12:34 PAGE 1
C51 COMPILER V8.08, COMPILATION OF MODULE I2C
OBJECT MODULE PLACED IN I2c.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE I2c.c BROWSE DEBUG OBJECTEXTEND
line level source
1 //I2C
2 #include "C8051F000.h"
3
4 #define uchar unsigned char
5 #define uint unsigned int
6
7 //--------------------------------------------------------------------
8 // 全局常量
9 //--------------------------------------------------------------------
10 #define WRITE 0x00 // SMBus 写命令
11 #define READ 0x01 // SMBus 读命令
12 // 器件地址(7位,最低位没使用)
13 #define CHIP_A 0xA0 // 芯片A的器件地址
14 #define CHIP_B 0xA2 // 芯片B的器件地址
15 #define CHIP_C 0xA4 // 芯片C的器件地址
16 // SMBus状态
17 // MT = 主发送器
18 // MR = 主接收器
19 #define SMB_BUS_ERROR 0x00 // (对所有方式)总线错误
20 #define SMB_START 0x08 // (MT & MR)起始条件已发送
21 #define SMB_RP_START 0x10 // (MT & MR)重复起始条件
22 #define SMB_MTADDACK 0x18 // (MT) 从地址 + W 已发送;收到ACK
23 #define SMB_MTADDNACK 0x20 // (MT) 从地址 + W 已发送;收到NACK
24 #define SMB_MTDBACK 0x28 // (MT) 数据字节已发送;收到ACK
25 #define SMB_MTDBNACK 0x30 // (MT) 数据字节已发送;收到NACK
26 #define SMB_MTARBLOST 0x38 // (MT) 竞争失败
27 #define SMB_MRADDACK 0x40 // (MR) 从地址 + R 已发送;收到ACK
28 #define SMB_MRADDNACK 0x48 // (MR) 从地址 + W 已发送;收到NACK
29 #define SMB_MRDBACK 0x50 // (MR) 收到数据字节;ACK已发送
30 #define SMB_MRDBNACK 0x58 // (MR) 收到数据字节;NACK已发送
31
32 extern void Delay(uint sum);
33 //--------------------------------------------------------------------
34 //全局变量
35 //--------------------------------------------------------------------
36 char COMMAND; // 在SMBus中断服务程序中用于
37 // 保存从地址 + R/W 位。
38 char WORD; // 保持SMBus要发送的数据字节
39 // 或刚收到的数据
40 char BYTE_NUMBER; // 在中用于检查发送的是什么数据
41 // 高地址字节、低地址字节或数据字节
42 uchar HIGH_ADD, LOW_ADD; // EEPROM存储器地址的高、低字节
43 //bit SM_BUSY; // 该位在发送或接收开始时被置1,
44 // // 操作结束后由中断服务程序
45
46 // SMBus 字节写函数-----------------------------------------------------
47 // 向给定存储器地址写一个字节
48 //
49 // out_byte = 待写数据
50 // byte_address = 待写存储器地址(2字节)
51 // chip_select = 待写EEPROM芯片的器件地址
52 void SM_Send (char chip_select, unsigned int byte_address, char out_byte)
53 {
54 1 // while(SM_BUSY); // 等待SMBus空闲
55 1 // SM_BUSY = 1; // 占用SMBus(设置为忙)
C51 COMPILER V8.08 I2C 05/21/2008 20:12:34 PAGE 2
56 1 SMB0CN = 0x44; // SMBus允许,应答周期发ACK
57 1 BYTE_NUMBER = 2; // 2地址字节
58 1 COMMAND = (chip_select | WRITE); // 片选 + WRITE
59 1 HIGH_ADD = ((byte_address >> 8) & 0x00FF); // 高8位地址
60 1 LOW_ADD = (byte_address & 0x00FF); // 低8位地址
61 1 WORD = out_byte; // 待写数据
62 1 STA = 1; // 启动传输过程
63 1 Delay(50);
64 1 }
65 // SMBus随机读函数-----------------------------------------------------
66 // 从给定存储器地址读一个字节
67 //
68 // byte_address = 要读取的存储器地址
69 // chip_select = 待读EEPROM的器件地址
70 char SM_Receive (char chip_select, unsigned int byte_address)
71 {
72 1 // while (SM_BUSY); // 等待总线空闲
73 1 // SM_BUSY = 1; //占用SMBus(设置为忙)
74 1 SMB0CN = 0x44; // 允许SMBus,应答周期发ACK
75 1 BYTE_NUMBER = 2; // 2地址字节
76 1 COMMAND = (chip_select | READ); // 片选 + READ
77 1 HIGH_ADD = ((byte_address >> 8) & 0x00FF); // 高8位地址
78 1 LOW_ADD = (byte_address & 0x00FF); // 低8位地址
79 1 STA = 1; // 启动传输过程
80 1 // while(SM_BUSY); // 等待传输结束
81 1 Delay(50);
82 1 return WORD;
83 1 }
84
85 //--------------------------------------------------------------------
86 // 中断服务程序
87 //--------------------------------------------------------------------
88 // SMBus中断服务程序
89 void SMBUS_ISR (void) interrupt 7
90 {
91 1 switch (SMB0STA){ // SMBus状态码(SMB0STA寄存器)
92 2 // 主发送器/接收器:起始条件已发送
93 2 // 在该状态发送的COMMAND字的R/W位总是为0(W),
94 2 // 因为对于读和写操作来说都必须先写存储器地址。
95 2 case SMB_START:
96 2 SMB0DAT = (COMMAND & 0xFE); // 装入要访问的从器件的地址
97 2 STA = 0; // 手动清除START位
98 2 break;
99 2 //主发送器/接收器:重复起始条件已发送。
100 2 //该状态只应在读操作期间出现,在存储器地址已发送并得到确认之后
101 2 case SMB_RP_START:
102 2 SMB0DAT = COMMAND; // COMMAND中应保持从地址 + R.
103 2 STA = 0;
104 2 break;
105 2 // 主发送器:从地址 + WRITE已发送,收到ACK。
106 2 case SMB_MTADDACK:
107 2 SMB0DAT = HIGH_ADD; // 装入待写存储器地址的高字节
108 2 break;
109 2 // 主发送器:从地址 + WRITE已发送,收到NACK。
110 2 // 从器件不应答,发送STOP + START重试
111 2 case SMB_MTADDNACK:
112 2 STO = 1;
113 2 STA = 1;
114 2 break;
115 2 // 主发送器:数据字节已发送,收到ACK。
116 2 // 该状态在写和读操作中都要用到。BYTE_NUMBER看存储器地址状态 – 如果
117 2 // 只发送了HIGH_ADD,则装入LOW_ADD。如果LOW_ADD已发送,检查COMMAND
C51 COMPILER V8.08 I2C 05/21/2008 20:12:34 PAGE 3
118 2 // 中的R/W 值以决定下一状态。
119 2 case SMB_MTDBACK:
120 2 switch (BYTE_NUMBER){
121 3 case 2: // 如果BYTE_NUMBER=2,
122 3 SMB0DAT = LOW_ADD; // 只发送了HIGH_ADD。
123 3 BYTE_NUMBER--; // 减1,为下一轮作准备
124 3 break;
125 3 case 1: // 如果BYTE_NUMBER=1,LOW_ADD已发送。
126 3 if (COMMAND & 0x01) // 如果R/W=READ,发送重复起始条件
127 3 STA = 1;
128 3 else{
129 4 SMB0DAT = WORD; // 如果R/W=WRITE,装入待写字节
130 4 BYTE_NUMBER--;}
131 3 break;
132 3 default: // 如果BYTE_NUMBER=0,传输结束
133 3 STO = 1;
134 3 //SM_BUSY = 0; // 释放SMBus
135 3 }
136 2 break;
137 2 // 主发送器:数据字节已发送,收到NACK。
138 2 // 从器件不应答,发送STOP + START重试
139 2 case SMB_MTDBNACK:
140 2 STO = 1;
141 2 STA = 1;
142 2 break;
143 2 // 主发送器:竞争失败
144 2 // 不应出现。如果出现,重新开始传输过程
145 2 case SMB_MTARBLOST:
146 2 STO = 1;
147 2 STA = 1;
148 2 break;
149 2 // 主接收器:从地址 + READ 已发送。收到ACK。
150 2 // 设置为在下一次传输后发送NACK,因为那将是最后一个字节(唯一)。
151 2 case SMB_MRADDACK:
152 2 AA = 0; // 在应答周期NACK。
153 2 break;
154 2 // 主接收器:从地址 + READ 已发送。收到NACK。
155 2 // 从器件不应答,发送重复起始条件重试
156 2 case SMB_MRADDNACK:
157 2 STA = 1;
158 2 break;
159 2 // 收到数据字节。ACK已发送。
160 2 // 该状态不应出现,因为AA已在前一状态被清0。如果出现,发送停止条件。
161 2 case SMB_MRDBACK:
162 2 STO = 1;
163 2 //SM_BUSY = 0;
164 2 break;
165 2 // 收到数据字节。NACK已发送。
166 2 // 读操作已完成。读数据寄存器后发送停止条件。
167 2 case SMB_MRDBNACK:
168 2 WORD = SMB0DAT;
169 2 STO = 1;
170 2 //SM_BUSY = 0; // 释放SMBus
171 2 break;
172 2 // 在本应用中,所有其它状态码没有意义。通信复位。
173 2 default:
174 2 STO = 1; // 通信复位。
175 2 //SM_BUSY = 0;
176 2 break;
177 2 }
178 1 SI=0; // 清除中断标志
179 1 }
C51 COMPILER V8.08 I2C 05/21/2008 20:12:34 PAGE 4
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 211 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = 5 ----
IDATA SIZE = ---- ----
BIT SIZE = ---- ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -