📄 smb_ex2.lst
字号:
C51 COMPILER V7.06 SMB_EX2 05/20/2004 15:09:37 PAGE 1
C51 COMPILER V7.06, COMPILATION OF MODULE SMB_EX2
OBJECT MODULE PLACED IN .\output\SMB_Ex2.obj
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE SMB_Ex2.c OPTIMIZE(6,SPEED) BROWSE ORDER DEBUG OBJECTEXTEND PRINT(.\output\
-SMB_Ex2.lst) OBJECT(.\output\SMB_Ex2.obj)
stmt level source
1 //------------------------------------------------------------------------------------
2 //
3 // Copyright 2001 Cygnal Integrated Products, Inc.
4 //
5 // FILE NAME : SMB_Ex2.c
6 // TARGET DEVICE : C8051F000
7 // CREATED ON : 2/20/01
8 // CREATED BY : JS
9 //
10 //
11 // Example code for interfacing a C8051F0xx to three EEPROMs via the SMBus.
12 // Code assumes that three 16-bit address space EEPROMs are connected
13 // on the SCL and SDA lines, and configured so that their slave addresses
14 // are as follows:
15 // CHIP_A = 1010000
16 // CHIP_B = 1010001
17 // CHIP_C = 1010010
18 //
19 // Slave and arbitration states are not defined. Assume the CF000 is the only
20 // master in the system.
21 // Functions: SM_Send performs a 1-byte write to the specified EEPROM
22 // SM_Receive performs a 1-byte read of the specified EEPROM address (both include
23 // memory address references).
24 //
25 // Includes test code section.
26
27 //------------------------------------------------------------------------------------
28 // Includes
29 //------------------------------------------------------------------------------------
30 #include "config.h" // SFR declarations
31
32 //------------------------------------------------------------------------------------
33 // Global CONSTANTS
34 //------------------------------------------------------------------------------------
35
36 #define WRITE 0x00 // SMBus WRITE command
37 #define READ 0x01 // SMBus READ command
38
39 // Device addresses (7 bits, lsb is a don't care)
40 #define CHIP_A 0xA0 // Device address for chip A
41 #define CHIP_B 0xA2 // Device address for chip B
42 #define CHIP_C 0xA4 // Device address for chip C
43
44 // SMBus states:
45 // MT = Master Transmitter
46 // MR = Master Receiver
47 #define SMB_BUS_ERROR 0x00 // (all modes) BUS ERROR
48 #define SMB_START 0x08 // (MT & MR) START transmitted
49 #define SMB_RP_START 0x10 // (MT & MR) repeated START
50 #define SMB_MTADDACK 0x18 // (MT) Slave address + W transmitted;
51 // ACK received
52 #define SMB_MTADDNACK 0x20 // (MT) Slave address + W transmitted;
53 // NACK received
54 #define SMB_MTDBACK 0x28 // (MT) data byte transmitted; ACK rec'vd
C51 COMPILER V7.06 SMB_EX2 05/20/2004 15:09:37 PAGE 2
55 #define SMB_MTDBNACK 0x30 // (MT) data byte transmitted; NACK rec'vd
56 #define SMB_MTARBLOST 0x38 // (MT) arbitration lost
57 #define SMB_MRADDACK 0x40 // (MR) Slave address + R transmitted;
58 // ACK received
59 #define SMB_MRADDNACK 0x48 // (MR) Slave address + R transmitted;
60 // NACK received
61 #define SMB_MRDBACK 0x50 // (MR) data byte rec'vd; ACK transmitted
62 #define SMB_MRDBNACK 0x58 // (MR) data byte rec'vd; NACK transmitted
63
64
65 //-----------------------------------------------------------------------------------
66 //Global VARIABLES
67 //-----------------------------------------------------------------------------------
68 char COMMAND; // Holds the slave address + R/W bit for
69 // use in the SMBus ISR.
70
71 char WORD; // Holds data to be transmitted by the SMBus
72 // OR data that has just been received.
73
74 char BYTE_NUMBER; // Used by ISR to check what data has just been
75 // sent - High address byte, Low byte, or data
76 // byte
77
78 unsigned char HIGH_ADD, LOW_ADD; // High & Low byte for EEPROM memory address
79
80 bit SM_BUSY; // This bit is set when a send or receive
81 // is started. It is cleared by the
82 // ISR when the operation is finished.
83
84
85 //------------------------------------------------------------------------------------
86 // Function PROTOTYPES
87 //------------------------------------------------------------------------------------
88
89 void SMBus_ISR (void);
90 void SM_Send (char chip_select, unsigned int byte_address, char out_byte);
91 char SM_Receive (char chip_select, unsigned int byte_address);
92
93 //------------------------------------------------------------------------------------
94 // MAIN Routine
95 //------------------------------------------------------------------------------------
96 //
97 // Main routine configures the crossbar and SMBus, and tests
98 // the SMBus interface between the three EEPROMs
99 void eeprom_test (void)
100 {
101 1 unsigned char check; // Used for testing purposes
102 1 /*
103 1 WDTCN = 0xde; // disable watchdog timer
104 1 WDTCN = 0xad;
105 1
106 1 OSCICN |= 0x03; // Set internal oscillator to highest setting
107 1 // (16 MHz)
108 1
109 1 XBR0 = 0x01; // Route SMBus to GPIO pins through crossbar
110 1 XBR2 = 0x40; // Enable crossbar and weak pull-ups
111 1
112 1 SMB0CN = 0x44; // Enable SMBus with ACKs on acknowledge
113 1 // cycle
114 1 SMB0CR = -80; // SMBus clock rate = 100kHz.
115 1
116 1 EIE1 |= 2; // SMBus interrupt enable
C51 COMPILER V7.06 SMB_EX2 05/20/2004 15:09:37 PAGE 3
117 1 EA = 1; // Global interrupt enable
118 1 */
119 1 SM_BUSY = 0; // Free SMBus for first transfer.
120 1
121 1
122 1 // TEST CODE---------------------------------------------------------------------
123 1 SM_Send(CHIP_A, 8, 0x0); // Send 0x53(data) to address 0x88 on CHIP_A
124 1 SM_Send(CHIP_A, 18, 0x1); // Send 0x53(data) to address 0x88 on CHIP_A
125 1 SM_Send(CHIP_A, 28, 0x2); // Send 0x53(data) to address 0x88 on CHIP_A
126 1 SM_Send(CHIP_A, 38, 0x3); // Send 0x53(data) to address 0x88 on CHIP_A
127 1 SM_Send(CHIP_A, 48, 0x4); // Send 0x53(data) to address 0x88 on CHIP_A
128 1 SM_Send(CHIP_A, 58, 0x5); // Send 0x53(data) to address 0x88 on CHIP_A
129 1 SM_Send(CHIP_A, 68, 0x6); // Send 0x53(data) to address 0x88 on CHIP_A
130 1 SM_Send(CHIP_A, 78, 0x7); // Send 0x53(data) to address 0x88 on CHIP_A
131 1 SM_Send(CHIP_A, 88, 0x8); // Send 0x53(data) to address 0x88 on CHIP_A
132 1 SM_Send(CHIP_A, 98, 0x9); // Send 0x53(data) to address 0x88 on CHIP_A
133 1 // SM_Send(CHIP_B, 0x0001, 0x66); // Send 0x66(data) to address 0x01 on CHIP_B
134 1 // SM_Send(CHIP_C, 0x0010, 0x77);
135 1 // SM_Send(CHIP_B, 0x0333, 0xF0);
136 1 SM_Send(CHIP_A, 0x0242, 0xF0);
137 1
138 1 check = SM_Receive(CHIP_A, 0x0088); // Read address 0x88 on CHIP_A
139 1 // check = SM_Receive(CHIP_B, 0x0001); // Read address 0x01 on CHIP_B
140 1 // check = SM_Receive(CHIP_C, 0x0010);
141 1 // check = SM_Receive(CHIP_B, 0x0333);
142 1 check = SM_Receive(CHIP_A, 0x0242);
143 1 // END TEST CODE-----------------------------------------------------------------
144 1
145 1 }
146
147
148 // SMBus byte write function-----------------------------------------------------
149 // Writes a single byte at the specified memory location.
150 //
151 // out_byte = data byte to be written
152 // byte_address = memory location to be written into (2 bytes)
153 // chip_select = device address of EEPROM chip to be written to
154 void SM_Send (char chip_select, unsigned int byte_address, char out_byte)
155 {
156 1 while (SM_BUSY); // Wait for SMBus to be free.
157 1 SM_BUSY = 1; // Occupy SMBus (set to busy)
158 1 SMB0CN = 0x44; // SMBus enabled,
159 1 // ACK on acknowledge cycle
160 1
161 1 BYTE_NUMBER = 2; // 2 address bytes.
162 1 COMMAND = (chip_select | WRITE); // Chip select + WRITE
163 1
164 1 HIGH_ADD = ((byte_address >> 8) & 0x00FF);// Upper 8 address bits
165 1 LOW_ADD = (byte_address & 0x00FF); // Lower 8 address bits
166 1
167 1 WORD = out_byte; // Data to be writen
168 1
169 1 STO = 0;
170 1 STA = 1; // Start transfer
171 1
172 1 }
173
174 // SMBus random read function------------------------------------------------------
175 // Reads 1 byte from the specified memory location.
176 //
177 // byte_address = memory address of byte to read
178 // chip_select = device address of EEPROM to be read from
C51 COMPILER V7.06 SMB_EX2 05/20/2004 15:09:37 PAGE 4
179 char SM_Receive (char chip_select, unsigned int byte_address)
180 {
181 1 while (SM_BUSY); // Wait for bus to be free.
182 1 SM_BUSY = 1; // Occupy SMBus (set to busy)
183 1 SMB0CN = 0x44; // SMBus enabled, ACK on acknowledge cycle
184 1
185 1 BYTE_NUMBER = 2; // 2 address bytes
186 1 COMMAND = (chip_select | READ); // Chip select + READ
187 1
188 1 HIGH_ADD = ((byte_address >> 8) & 0x00FF);// Upper 8 address bits
189 1 LOW_ADD = (byte_address & 0x00FF); // Lower 8 address bits
190 1
191 1 STO = 0;
192 1 STA = 1; // Start transfer
193 1 while (SM_BUSY); // Wait for transfer to finish
194 1 return WORD;
195 1 }
196
197
198 //------------------------------------------------------------------------------------
199 // Interrupt Service Routine
200 //------------------------------------------------------------------------------------
201
202
203 // SMBus interrupt service routine:
204
205 void SMBUS_ISR (void) interrupt 7
206 {
207 1 switch (SMB0STA){ // Status code for the SMBus (SMB0STA register)
208 2
209 2 // Master Transmitter/Receiver: START condition transmitted.
210 2 // The R/W bit of the COMMAND word sent after this state will
211 2 // always be a zero (W) because for both read and write,
212 2 // the memory address must be written first.
213 2 case SMB_START:
214 2 SMB0DAT = (COMMAND & 0xFE); // Load address of the slave to be accessed.
215 2 STA = 0; // Manually clear START bit
216 2 break;
217 2
218 2 // Master Transmitter/Receiver: Repeated START condition transmitted.
219 2 // This state should only occur during a read, after the memory address has been
220 2 // sent and acknowledged.
221 2 case SMB_RP_START:
222 2 SMB0DAT = COMMAND; // COMMAND should hold slave address + R.
223 2 STA = 0;
224 2 break;
225 2
226 2 // Master Transmitter: Slave address + WRITE transmitted. ACK received.
227 2 case SMB_MTADDACK:
228 2 SMB0DAT = HIGH_ADD; // Load high byte of memory address
229 2 // to be written.
230 2 break;
231 2
232 2 // Master Transmitter: Slave address + WRITE transmitted. NACK received.
233 2 // The slave is not responding. Send a STOP followed by a START to try again.
234 2 case SMB_MTADDNACK:
235 2 STO = 1;
236 2 STA = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -