📄 scu_am.lst
字号:
C51 COMPILER V6.10 SCU_AM 04/18/2001 17:09:25 PAGE 1
C51 COMPILER V6.10, COMPILATION OF MODULE SCU_AM
OBJECT MODULE PLACED IN .\SCU_Am.OBJ
COMPILER INVOKED BY: C:\KEIL\C51\BIN\C51.EXE .\SCU_Am.c OPTIMIZE(SIZE) BROWSE DEBUG OBJECTEXTEND
stmt level source
1 /*------------------------------------------------------------------*-
2
3 SCU_Am.c (v1.00)
4
5 ------------------------------------------------------------------
6
7 This is an implementation of SCU SCHEDULER (LOCAL) for 8051/52.
8 AND an implementation of SCU SCHEDULER (RS-232) for 8051/52.
9
10 --- See Chapter 27 ---
11
12 *** MASTER NODE ***
13 *** CHECKS FOR SLAVE ACKNOWLEDEMENTS ***
14 *** Local / RS-232 version (no 'enable' support) ***
15
16 *** Uses 1232 watchdog timer ***
17
18 *** Both Master and Slave share the same tick rate (5 ms) ***
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_Am.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_AM 04/18/2001 17:09:25 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_A_MASTER_Reset_the_Network(void);
64 static void SCU_A_MASTER_Shut_Down_the_Network(void);
65 static void SCU_A_MASTER_Switch_To_Backup_Slave(const tByte);
66
67 static void SCU_A_MASTER_Send_Tick_Message(const tByte);
68 static bit SCU_A_MASTER_Process_Ack(const tByte);
69
70 static void SCU_A_MASTER_Watchdog_Init(void);
71 static void SCU_A_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_A_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_A_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_A_MASTER_Watchdog_Init();
117 1
C51 COMPILER V6.10 SCU_AM 04/18/2001 17:09:25 PAGE 3
118 1 Network_error_pin = NO_NETWORK_ERROR;
119 1
120 1 // ------ Set up the scheduler ----------------------------------
121 1 // Sort out the tasks
122 1 for (Task_index = 0; Task_index < SCH_MAX_TASKS; Task_index++)
123 1 {
124 2 SCH_Delete_Task(Task_index);
125 2 }
126 1
127 1 // Reset the global error variable
128 1 // - SCH_Delete_Task() will generate an error code,
129 1 // (because the task array is empty)
130 1 Error_code_G = 0;
131 1
132 1 // We allow any combination of ID numbers in slaves
133 1 // - but reserve ID 0x00
134 1 for (Slave_index = 0; Slave_index < NUMBER_OF_SLAVES; Slave_index++)
135 1 {
136 2 Slave_reset_attempts_G[Slave_index] = 0;
137 2 Current_Slave_IDs_G[Slave_index] = MAIN_SLAVE_IDs[Slave_index];
138 2 }
139 1
140 1 // ------ Set the baud rate (begin) -----------------------------
141 1 PCON &= 0x7F; // Set SMOD bit to 0 (don't double baud rates)
142 1
143 1 // Receiver enabled
144 1 // *9-bit data*, 1 start bit, 1 stop bit, variable baud rate (asynchronous)
145 1 SCON = 0xD2;
146 1
147 1 TMOD |= 0x20; // T1 in mode 2, 8-bit auto reload
148 1
149 1 TH1 = (256 - (tByte)((((tLong)OSC_FREQ / 100) * 3125)
150 1 / ((tLong) BAUD_RATE * OSC_PER_INST * 1000)));
151 1
152 1 TL1 = TH1;
153 1 TR1 = 1; // Run the timer
154 1 TI = 1; // Send first character (dummy)
155 1 // ------ Set the baud rate (end) -------------------------------
156 1
157 1 // Serial interrupt *NOT* enabled
158 1 ES = 0;
159 1 // ------ Set up the serial link (end) --------------------------
160 1
161 1 // ------ Set up Timer 2 (begin) --------------------------------
162 1 // Crystal is assumed to be 12 MHz, 12 osc/increment
163 1 //
164 1 // The Timer 2 resolution is 0.000001 seconds (1 祍)
165 1 // The required Timer 2 overflow is 0.005 seconds (5 ms)
166 1 // - this takes 5000 timer ticks
167 1 // Reload value is 65536 - 5000 = 60536 (dec) = 0xEC78
168 1
169 1 T2CON = 0x04; // load Timer 2 control register
170 1 T2MOD = 0x00; // load Timer 2 mode register
171 1
172 1 TH2 = 0xEC; // load timer 2 high byte
173 1 RCAP2H = 0xEC; // load timer 2 reload capture reg, high byte
174 1 TL2 = 0x78; // load timer 2 low byte
175 1 RCAP2L = 0x78; // load timer 2 reload capture reg, low byte
176 1
177 1 ET2 = 1; // Timer 2 interrupt is enabled
178 1
179 1 TR2 = 1; // Start Timer 2
C51 COMPILER V6.10 SCU_AM 04/18/2001 17:09:25 PAGE 4
180 1 // ------ Set up Timer 2 (end) ----------------------------------
181 1 }
182
183 /*------------------------------------------------------------------*-
184
185 SCU_A_MASTER_Start()
186
187 Starts the scheduler, by enabling interrupts.
188
189 NOTE: Usually called after all regular tasks are added,
190 to keep the tasks synchronised.
191
192 NOTE: ONLY THE SCHEDULER INTERRUPT SHOULD BE ENABLED!!!
193
194 NOTE: Delays here (2ms) assume a baud rate of at leadt 9600 baud.
195 You will need to fine-tune this code if you opt for a lower baud
196 rate.
197
198 -*------------------------------------------------------------------*/
199 void SCU_A_MASTER_Start(void)
200 {
201 1 tByte Slave_ID;
202 1 tByte Num_active_slaves;
203 1 tByte Id, i;
204 1 bit First_byte = 0;
205 1 bit Slave_replied_correctly;
206 1 tByte Slave_index;
207 1
208 1 // Refresh the watchdog
209 1 SCU_A_MASTER_Watchdog_Refresh();
210 1
211 1 // Place system in 'safe state'
212 1 SCU_A_MASTER_Enter_Safe_State();
213 1
214 1 // Report error as we wait to start
215 1 Network_error_pin = NETWORK_ERROR;
216 1
217 1 Error_code_G = ERROR_SCH_WAITING_FOR_SLAVE_TO_ACK;
218 1 SCH_Report_Status(); // Sch not yet running - do this manually
219 1
220 1 // Pause here (3000 ms), to time-out all the slaves
221 1 // (This is the means by which we synchronise the network)
222 1 for (i = 0; i < 100; i++)
223 1 {
224 2 Hardware_Delay_T0(30);
225 2 SCU_A_MASTER_Watchdog_Refresh();
226 2 }
227 1
228 1 // Currently disconnected from all slaves
229 1 Num_active_slaves = 0;
230 1
231 1 // After the initial (long) delay, all (operational) slaves will have timed out.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -