📄 scu_bm.lst
字号:
C51 COMPILER V6.10 SCU_BM 04/18/2001 17:23:01 PAGE 1
C51 COMPILER V6.10, COMPILATION OF MODULE SCU_BM
OBJECT MODULE PLACED IN .\SCU_BM.OBJ
COMPILER INVOKED BY: C:\KEIL\C51\BIN\C51.EXE .\SCU_BM.C OPTIMIZE(SIZE) BROWSE DEBUG OBJECTEXTEND
stmt level source
1 /*------------------------------------------------------------------*-
2
3 SCU_Bm.c (v1.00)
4
5 ------------------------------------------------------------------
6
7 This is an implementation of SCU SCHEDULER (RS-485) for 8051/52.
8
9 --- See Chapter 27 ---
10
11 *** MASTER NODE ***
12 *** CHECKS FOR SLAVE ACKNOWLEDEMENTS ***
13 *** Includes support for tranceiver enables ***
14
15 --- Assumes 12.00 MHz crystal -> 5ms tick rate ---
16 --- Master and slave(s) share same tick rate ---
17
18 --- Assumes '1232' watchdog on Master and Slave ---
19
20
21 COPYRIGHT
22 ---------
23
24 This code is from the book:
25
26 PATTERNS FOR TIME-TRIGGERED EMBEDDED SYSTEMS by Michael J. Pont
27 [Pearson Education, 2001; ISBN: 0-201-33138-1].
28
29 This code is copyright (c) 2001 by Michael J. Pont.
30
31 See book for copyright details and other information.
32
33 -*------------------------------------------------------------------*/
34
35 #include "Main.h"
36 #include "Port.h"
37
38 #include "SCU_Bm.H"
39 #include "Delay_T0.h"
40 #include "TLight_B.h"
41
42 // ------ Public variable definitions ------------------------------
43
44 tByte Tick_message_data_G[NUMBER_OF_SLAVES] = {'M'};
45 tByte Ack_message_data_G[NUMBER_OF_SLAVES];
46
47 // ------ Public variable declarations -----------------------------
48
49 // The array of tasks (see Sch51.c)
50 extern sTask SCH_tasks_G[SCH_MAX_TASKS];
51
52 // The error code variable (see Sch51.c)
53 extern tByte Error_code_G;
54
55 // ------ Private variable definitions -----------------------------
C51 COMPILER V6.10 SCU_BM 04/18/2001 17:23:01 PAGE 2
56
57 static tByte Current_slave_index_G = 0;
58 static bit First_ack_G = 1;
59 static bit WATCHDOG_state_G = 0;
60
61 // ------ Private function prototypes ------------------------------
62
63 static void SCU_B_MASTER_Reset_the_Network(void);
64 static void SCU_B_MASTER_Shut_Down_the_Network(void);
65 static void SCU_B_MASTER_Switch_To_Backup_Slave(const tByte);
66
67 static void SCU_B_MASTER_Send_Tick_Message(const tByte);
68 static bit SCU_B_MASTER_Process_Ack(const tByte);
69
70 static void SCU_B_MASTER_Watchdog_Init(void);
71 static void SCU_B_MASTER_Watchdog_Refresh(void) reentrant;
72
73 // ------ Private constants ----------------------------------------
74
75 // Slave IDs may be any NON-ZERO tByte value (all must be different)
76 // NOTE: ID 0x00 is for error handling.
77 static const tByte MAIN_SLAVE_IDs[NUMBER_OF_SLAVES] = {0x31};
78 static const tByte BACKUP_SLAVE_IDs[NUMBER_OF_SLAVES] = {0x31};
79
80 #define NO_NETWORK_ERROR (1)
81 #define NETWORK_ERROR (0)
82
83 // Adjust (if required) to increase interval between network resets
84 // (in the event of sustained network error)
85 #define SLAVE_RESET_INTERVAL 0U
86
87 // ------ Private variables ----------------------------------------
88
89 static tWord Slave_reset_attempts_G[NUMBER_OF_SLAVES];
90
91 // See MAIN_SLAVE_IDs[] above
92 static tByte Current_Slave_IDs_G[NUMBER_OF_SLAVES] = {0};
93
94 static bit Message_byte_G = 1;
95
96 /*------------------------------------------------------------------*-
97
98 SCU_B_MASTER_Init_T1_T2()
99
100 Scheduler initialisation function. Prepares scheduler data
101 structures and sets up timer interrupts at required rate.
102 You must call this function before using the scheduler.
103
104 BAUD_RATE - The required baud rate.
105
106 -*------------------------------------------------------------------*/
107 void SCU_B_MASTER_Init_T1_T2(const tWord BAUD_RATE)
108 {
109 1 tByte Task_index;
110 1 tByte Slave_index;
111 1
112 1 // No interrupts (yet)
113 1 EA = 0;
114 1
115 1 // Start the watchdog
116 1 SCU_B_MASTER_Watchdog_Init();
117 1
C51 COMPILER V6.10 SCU_BM 04/18/2001 17:23:01 PAGE 3
118 1 Network_error_pin = NO_NETWORK_ERROR;
119 1
120 1 // Set up RS-485 tranceiver
121 1 RS485_Rx_NOT_Enable = 0; // Master Rec is constantly enabled
122 1 RS485_Tx_Enable = 1; // Master Tran is constantly enabled
123 1
124 1 // ------ Set up the scheduler ----------------------------------
125 1 // Sort out the tasks
126 1 for (Task_index = 0; Task_index < SCH_MAX_TASKS; Task_index++)
127 1 {
128 2 SCH_Delete_Task(Task_index);
129 2 }
130 1
131 1 // Reset the global error variable
132 1 // - SCH_Delete_Task() will generate an error code,
133 1 // (because the task array is empty)
134 1 Error_code_G = 0;
135 1
136 1 // We allow any combination of ID numbers in slaves
137 1 // - but reserve ID 0x00
138 1 for (Slave_index = 0; Slave_index < NUMBER_OF_SLAVES; Slave_index++)
139 1 {
140 2 Slave_reset_attempts_G[Slave_index] = 0;
141 2 Current_Slave_IDs_G[Slave_index] = MAIN_SLAVE_IDs[Slave_index];
142 2 }
143 1
144 1 // ------ Set the baud rate (begin) -----------------------------
145 1 PCON &= 0x7F; // Set SMOD bit to 0 (don't double baud rates)
146 1
147 1 // Receiver enabled
148 1 // *9-bit data*, 1 start bit, 1 stop bit, variable baud rate (asynchronous)
149 1 SCON = 0xD2;
150 1
151 1 TMOD |= 0x20; // T1 in mode 2, 8-bit auto reload
152 1
153 1 TH1 = (256 - (tByte)((((tLong)OSC_FREQ / 100) * 3125)
154 1 / ((tLong) BAUD_RATE * OSC_PER_INST * 1000)));
155 1
156 1 TL1 = TH1;
157 1 TR1 = 1; // Run the timer
158 1 TI = 1; // Send first character (dummy)
159 1 // ------ Set the baud rate (end) -------------------------------
160 1
161 1 // Serial interrupt *NOT* enabled
162 1 ES = 0;
163 1 // ------ Set up the serial link (end) --------------------------
164 1
165 1 // ------ Set up Timer 2 (begin) --------------------------------
166 1 // Crystal is assumed to be 12 MHz, 12 osc/increment
167 1 //
168 1 // The Timer 2 resolution is 0.000001 seconds (1 祍)
169 1 // The required Timer 2 overflow is 0.005 seconds (5 ms)
170 1 // - this takes 5000 timer ticks
171 1 // Reload value is 65536 - 5000 = 60536 (dec) = 0xEC78
172 1
173 1 T2CON = 0x04; // load Timer 2 control register
174 1 T2MOD = 0x00; // load Timer 2 mode register
175 1
176 1 TH2 = 0xEC; // load timer 2 high byte
177 1 RCAP2H = 0xEC; // load timer 2 reload capture reg, high byte
178 1 TL2 = 0x78; // load timer 2 low byte
179 1 RCAP2L = 0x78; // load timer 2 reload capture reg, low byte
C51 COMPILER V6.10 SCU_BM 04/18/2001 17:23:01 PAGE 4
180 1
181 1 ET2 = 1; // Timer 2 interrupt is enabled
182 1
183 1 TR2 = 1; // Start Timer 2
184 1 // ------ Set up Timer 2 (end) ----------------------------------
185 1 }
186
187 /*------------------------------------------------------------------*-
188
189 SCU_B_MASTER_Start()
190
191 Starts the scheduler, by enabling interrupts.
192
193 NOTE: Usually called after all regular tasks are added,
194 to keep the tasks synchronised.
195
196 NOTE: ONLY THE SCHEDULER INTERRUPT SHOULD BE ENABLED!!!
197
198 NOTE: Delays here (2ms) assume a baud rate of at leadt 9600 baud.
199 You will need to fine-tune this code if you opt for a lower baud
200 rate.
201
202 -*------------------------------------------------------------------*/
203 void SCU_B_MASTER_Start(void)
204 {
205 1 tByte Slave_ID;
206 1 tByte Num_active_slaves;
207 1 tByte Id, i;
208 1 bit First_byte = 0;
209 1 bit Slave_replied_correctly;
210 1 tByte Slave_index;
211 1
212 1 // Refresh the watchdog
213 1 SCU_B_MASTER_Watchdog_Refresh();
214 1
215 1 // Place system in 'safe state'
216 1 SCU_B_MASTER_Enter_Safe_State();
217 1
218 1 // Report error as we wait to start
219 1 Network_error_pin = NETWORK_ERROR;
220 1
221 1 Error_code_G = ERROR_SCH_WAITING_FOR_SLAVE_TO_ACK;
222 1 SCH_Report_Status(); // Sch not yet running - do this manually
223 1
224 1 // Pause here (3000 ms), to time-out all the slaves
225 1 // (This is the means by which we synchronise the network)
226 1 for (i = 0; i < 100; i++)
227 1 {
228 2 Hardware_Delay_T0(30);
229 2 SCU_B_MASTER_Watchdog_Refresh();
230 2 }
231 1
232 1 // Currently disconnected from all slaves
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -