📄 f33x_smbus_master.lst
字号:
C51 COMPILER V8.09 F33X_SMBUS_MASTER 12/28/2008 14:53:39 PAGE 1
C51 COMPILER V8.09, COMPILATION OF MODULE F33X_SMBUS_MASTER
OBJECT MODULE PLACED IN F33x_SMBus_Master.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE F33x_SMBus_Master.c BROWSE DEBUG OBJECTEXTEND
line level source
1 //-----------------------------------------------------------------------------
2 // F33x_SMBus_Master.c
3 //-----------------------------------------------------------------------------
4 // Copyright 2006 Silicon Laboratories, Inc.
5 // http://www.silabs.com
6 //
7 // Program Description:
8 //
9 // Example software to demonstrate the C8051F33x SMBus interface in
10 // Master mode.
11 // - Interrupt-driven SMBus implementation
12 // - Only master states defined (no slave or arbitration)
13 // - 1-byte SMBus data holders used for each transmit and receive
14 // - Timer1 used as SMBus clock source
15 // - Timer3 used by SMBus for SCL low timeout detection
16 // - SCL frequency defined by <SMB_FREQUENCY> constant
17 // - ARBLOST support included
18 // - Pinout:
19 // P0.0 -> SDA (SMBus)
20 // P0.1 -> SCL (SMBus)
21 //
22 // P1.3 -> LED
23 //
24 // P2.0 -> C2D (debug interface)
25 //
26 // all other port pins unused
27 //
28 // How To Test:
29 //
30 // 1) Verify that J6 is not populated.
31 // 2) Download code to a 'F33x device that is connected to a SMBus slave.
32 // 3) Run the code:
33 // a) The test will indicate proper communication with the slave by
34 // toggling the LED on and off each time a value is sent and
35 // received.
36 // b) The best method to view the proper functionality is to run to
37 // the indicated line of code in the TEST CODE section of main and
38 // view the SMB_DATA_IN and SMB_DATA_OUT variables in the Watch
39 // Window.
40 //
41 //
42 // FID: 33X000013
43 // Target: C8051F33x
44 // Tool chain: Keil C51 7.50 / Keil EVAL C51
45 // Command Line: None
46 //
47 // Release 1.0
48 // -Initial Revision (TP)
49 // -30 MAR 2006
50 //
51
52 //-----------------------------------------------------------------------------
53 // Includes
54 //-----------------------------------------------------------------------------
55
C51 COMPILER V8.09 F33X_SMBUS_MASTER 12/28/2008 14:53:39 PAGE 2
56 #include <C8051F330.h> // SFR declarations
57
58 //-----------------------------------------------------------------------------
59 // Global CONSTANTS
60 //-----------------------------------------------------------------------------
61
62 #define SYSCLK 24500000 // System clock frequency in Hz
63
64
65 #define SMB_FREQUENCY 10000 // Target SCL clock rate
66 // This example supports between 10kHz
67 // and 100kHz
68
69 #define WRITE 0x00 // SMBus WRITE command
70 #define READ 0x01 // SMBus READ command
71
72 // Device addresses (7 bits, LSB is a don't care)
73 #define SLAVE_ADDR 0x70 // Device address for slave target
74
75 // Status vector - top 4 bits only
76 #define SMB_MTSTA 0xE0 // (MT) start transmitted
77 #define SMB_MTDB 0xC0 // (MT) data byte transmitted
78 #define SMB_MRDB 0x80 // (MR) data byte received
79 // End status vector definition
80
81 //-----------------------------------------------------------------------------
82 // Global VARIABLES
83 //-----------------------------------------------------------------------------
84 unsigned char SMB_DATA_IN; // Global holder for SMBus data
85 // All receive data is written here
86
87 unsigned char SMB_DATA_OUT; // Global holder for SMBus data.
88 // All transmit data is read from here
89
90 unsigned char TARGET; // Target SMBus slave address
91
92 bit SMB_BUSY; // Software flag to indicate when the
93 // SMB_Read() or SMB_Write() functions
94 // have claimed the SMBus
95
96 bit SMB_RW; // Software flag to indicate the
97 // direction of the current transfer
98
99 unsigned long NUM_ERRORS; // Counter for the number of errors.
100
101 // 16-bit SFR declarations
102 sfr16 TMR3RL = 0x92; // Timer3 reload registers
103 sfr16 TMR3 = 0x94; // Timer3 counter registers
104
105 sbit LED = P1^3; // LED on port P1.3
106
107 sbit SDA = P0^0; // SMBus on P0.0
108 sbit SCL = P0^1; // and P0.1
109
110 //-----------------------------------------------------------------------------
111 // Function PROTOTYPES
112 //-----------------------------------------------------------------------------
113
114 void SMBus_Init (void);
115 void Timer1_Init (void);
116 void Timer3_Init (void);
117 void Port_Init (void);
C51 COMPILER V8.09 F33X_SMBUS_MASTER 12/28/2008 14:53:39 PAGE 3
118
119 void SMBus_ISR (void);
120 void Timer3_ISR (void);
121
122 void SMB_Write (void);
123 void SMB_Read (void);
124 void T0_Wait_ms (unsigned char ms);
125
126 //-----------------------------------------------------------------------------
127 // MAIN Routine
128 //-----------------------------------------------------------------------------
129 //
130 // Main routine performs all configuration tasks, then loops forever sending
131 // and receiving SMBus data to the slave <SLAVE_ADDR>.
132 //
133 void main (void)
134 {
135 1 volatile unsigned char dat; // Test counter
136 1 unsigned char i; // Dummy variable counters
137 1
138 1 PCA0MD &= ~0x40; // WDTE = 0 (watchdog timer enable bit)
139 1
140 1 OSCICN |= 0x03; // Set internal oscillator to highest
141 1 // setting of 24500000
142 1
143 1 // If slave is holding SDA low because of an improper SMBus reset or error
144 1 while(!SDA)
145 1 {
146 2 // Provide clock pulses to allow the slave to advance out
147 2 // of its current state. This will allow it to release SDA.
148 2 XBR1 = 0x40; // Enable Crossbar
149 2 SCL = 0; // Drive the clock low
150 2 for(i = 0; i < 255; i++); // Hold the clock low
151 2 SCL = 1; // Release the clock
152 2 while(!SCL); // Wait for open-drain
153 2 // clock output to rise
154 2 for(i = 0; i < 10; i++); // Hold the clock high
155 2 XBR1 = 0x00; // Disable Crossbar
156 2 }
157 1
158 1 Port_Init (); // Initialize Crossbar and GPIO
159 1
160 1 Timer1_Init (); // Configure Timer1 for use as SMBus
161 1 // clock source
162 1
163 1 Timer3_Init (); // Configure Timer3 for use with SMBus
164 1 // low timeout detect
165 1
166 1 SMBus_Init (); // Configure and enable SMBus
167 1
168 1 EIE1 |= 0x01; // Enable the SMBus interrupt
169 1
170 1 LED = 0;
171 1
172 1 EA = 1; // Global interrupt enable
173 1
174 1 // TEST CODE-------------------------------------------------------------------
175 1
176 1 dat = 0; // Output data counter
177 1 NUM_ERRORS = 0; // Error counter
178 1 while (1)
179 1 {
C51 COMPILER V8.09 F33X_SMBUS_MASTER 12/28/2008 14:53:39 PAGE 4
180 2 // SMBus Write Sequence
181 2 SMB_DATA_OUT = dat; // Define next outgoing byte
182 2 TARGET = SLAVE_ADDR; // Target the F3xx/Si8250 Slave for next
183 2 // SMBus transfer
184 2 SMB_Write(); // Initiate SMBus write
185 2
186 2 // SMBus Read Sequence
187 2 TARGET = SLAVE_ADDR; // Target the F3xx/Si8250 Slave for next
188 2 // SMBus transfer
189 2 SMB_Read();
190 2
191 2 // Check transfer data
192 2 if(SMB_DATA_IN != SMB_DATA_OUT) // Received data match transmit data?
193 2 {
194 3 NUM_ERRORS++; // Increment error counter if no match
195 3 }
196 2
197 2 // Indicate that an error has occurred (LED no longer lit)
198 2 if (NUM_ERRORS > 0)
199 2 {
200 3 LED = 0;
201 3 }
202 2 else
203 2 {
204 3 LED = ~LED;
205 3 }
206 2
207 2 // Run to here to view the SMB_DATA_IN and SMB_DATA_OUT variables
208 2
209 2 dat++;
210 2
211 2 T0_Wait_ms (1); // Wait 1 ms until the next cycle
212 2 }
213 1
214 1 // END TEST CODE---------------------------------------------------------------
215 1
216 1 }
217
218 //-----------------------------------------------------------------------------
219 // Initialization Routines
220 //-----------------------------------------------------------------------------
221
222 //-----------------------------------------------------------------------------
223 // SMBus_Init
224 //-----------------------------------------------------------------------------
225 //
226 // Return Value : None
227 // Parameters : None
228 //
229 // SMBus configured as follows:
230 // - SMBus enabled
231 // - Slave mode inhibited
232 // - Timer1 used as clock source. The maximum SCL frequency will be
233 // approximately 1/3 the Timer1 overflow rate
234 // - Setup and hold time extensions enabled
235 // - Bus Free and SCL Low timeout detection enabled
236 //
237 void SMBus_Init (void)
238 {
239 1 SMB0CF = 0x5D; // Use Timer1 overflows as SMBus clock
240 1 // source;
241 1 // Disable slave mode;
C51 COMPILER V8.09 F33X_SMBUS_MASTER 12/28/2008 14:53:39 PAGE 5
242 1 // Enable setup & hold time
243 1 // extensions;
244 1 // Enable SMBus Free timeout detect;
245 1 // Enable SCL low timeout detect;
246 1
247 1 SMB0CF |= 0x80; // Enable SMBus;
248 1 }
249
250 //-----------------------------------------------------------------------------
251 // Timer1_Init
252 //-----------------------------------------------------------------------------
253 //
254 // Return Value : None
255 // Parameters : None
256 //
257 // Timer1 configured as the SMBus clock source as follows:
258 // - Timer1 in 8-bit auto-reload mode
259 // - SYSCLK or SYSCLK / 4 as Timer1 clock source
260 // - Timer1 overflow rate => 3 * SMB_FREQUENCY
261 // - The resulting SCL clock rate will be ~1/3 the Timer1 overflow rate
262 // - Timer1 enabled
263 //
264 void Timer1_Init (void)
265 {
266 1
267 1 // Make sure the Timer can produce the appropriate frequency in 8-bit mode
268 1 // Supported SMBus Frequencies range from 10kHz to 100kHz. The CKCON register
269 1 // settings may need to change for frequencies outside this range.
270 1 #if ((SYSCLK/SMB_FREQUENCY/3) < 255)
#define SCALE 1
CKCON |= 0x08; // Timer1 clock source = SYSCLK
#elif ((SYSCLK/SMB_FREQUENCY/4/3) < 255)
274 1 #define SCALE 4
275 1 CKCON |= 0x01;
276 1 CKCON &= ~0x0A; // Timer1 clock source = SYSCLK / 4
277 1 #endif
278 1
279 1 TMOD = 0x20; // Timer1 in 8-bit auto-reload mode
280 1
281 1 // Timer1 configured to overflow at 1/3 the rate defined by SMB_FREQUENCY
282 1 TH1 = -(SYSCLK/SMB_FREQUENCY/SCALE/3);
283 1
284 1 TL1 = TH1; // Init Timer1
285 1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -