📄 timer.lst
字号:
C166 COMPILER V3.10b, TIMER 27/11/97 13:31:46 PAGE 1
DOS C166 COMPILER V3.10b, COMPILATION OF MODULE TIMER
OBJECT MODULE PLACED IN TIMER.OBJ
COMPILER INVOKED BY: C:\C166EVAL\BIN\C166.EXE TIMER.C CD DB M167 WL(3)
stmt level source
1 /******************************************************************************
2 C167CR CAN Ap. Note project
3 Timing functions
4
5 This is an example program showing how to use the CAN interface on the Keil
6 MCB167 evaluation board.
7
8 Copyright (c) 1997 Keil Software
9 ******************************************************************************/
10 #include <reg167.h>
11 #include <intrins.h>
12 #include "timer.h"
13
14 /* The following macro calculates the value to write to an interrupt control
15 register. The arguments are:
16 ir: Interrupt request (0 or 1)
17 ie: Interrupt enable (0 or 1)
18 ilvl: Interrupt priority level (0, 1, ... 15)
19 glvl: Group level (0, 1, 2, or 3)
20 */
21 #define CALC_IC(ir,ie,ilvl,glvl) ((ir) << 7 | (ie) << 6 | (ilvl) << 2 | glvl)
22
23 static unsigned long timer_val;
24
25 /* The following three macros control the frequency of the timer interrupt.
26 CPU_FREQUENCY_HZ must be the actual CPU frequency.
27 The prescaler will divide this frequency by
28 2 raised to the (PRESCALE_SELECTION + 2) power. PRESCALE_SELECTION must be
29 an integer >= 0 and <= 7.
30 The timer counts down. When it underflows from 0x0000 to 0xFFFF, it is
31 reloaded with RELOAD_VALUE (It is reloaded from the CAPREL register,
32 which has been initialized with RELOAD_VALUE.), and generates an interrupt.
33
34 If you change the values of any of these macros, you need to also change
35 TIMER_UNITS_PER_SECOND in timer.h to match the new timer interrupt
36 frequency. A compile-time check that TIMER_UNITS_PER_SECOND is the
37 correct value follows these macros.
38 */
39 #define RELOAD_VALUE 624 /* value for CAPREL register */
40 #define PRESCALE_SELECTION 3 /* value for T6I field of T6CON register */
41 #define CPU_FREQUENCY_HZ 20000000 /* CPU frequency in Hertz */
42
43 /* Check that the intended timer interrupt frequency, TIMER_UNITS_PER_SECOND,
44 is equal to the calculated timer interrupt frequency.
45 Generate an error message if it is not.
46 */
47 #if CPU_FREQUENCY_HZ != \
48 TIMER_UNITS_PER_SECOND * (4L << PRESCALE_SELECTION) * (RELOAD_VALUE + 1L)
#error TIMER_UNITS_PER_SECOND does not match calculated value.
#endif
51
52
53 /******************************************************************************
54 Initialize the timer.
55
56 Return: nothing.
57 -----------------------------------------------------------------------------*/
58 void
59 init_timer(void)
C166 COMPILER V3.10b, TIMER 27/11/97 13:31:46 PAGE 2
60 {
61 1 CAPREL = RELOAD_VALUE;
62 1 T6 = RELOAD_VALUE;
63 1 T6CON = 0x80c0 | PRESCALE_SELECTION;
64 1
65 1 /* interrupt set up */
66 1 T6IC = CALC_IC(0, 1, 10, 0); /* enable interrupt at priority level 10, group level 0 */
67 1 }
68
69
70 /******************************************************************************
71 Gets the timer value.
72
73 Returns: Elapsed time since the timer was initialized, in
74 TIMER_UNITS_PER_SECOND * seconds.
75 -----------------------------------------------------------------------------*/
76 unsigned long
77 timer(void)
78 {
79 1 long temp;
80 1
81 1 /* This code was written for a 16-bit processor (Siemens C167CR), so the
82 1 32-bit variable timer_val cannot be processed (copied, incremented, etc.)
83 1 in a single machine instruction. The _atomic_() and _endatomic_()
84 1 "functions" tell the compiler to generate an ATOMIC machine instruction
85 1 to protect the sequence of instruction processing timer_val from being
86 1 interrupted. If the timer interrupt (which increments timer_val) occurred
87 1 after one word of timer_val had been copied but before the other word had
88 1 been copied, the copied value could be erroneous. The problem would
89 1 probably occur only sporadicaly, and be maddeningly difficult to find.
90 1 */
91 1
92 1 _atomic_(0);
93 1 temp = timer_val;
94 1 _endatomic_();
95 1 return temp;
96 1 }
97
98
99 /******************************************************************************
100 Interrupt service routine for the timer interrupt.
101 -----------------------------------------------------------------------------*/
102 void
103 timer_interrupt(void) interrupt 0x26
104 {
105 1 /* See comment in timer() function above discussing interruptability of
106 1 operations on timer_val.
107 1 This operation (incrementing timer_val in the interrupt service
108 1 routine) also needs to be uninterruptable, if any higher-priority
109 1 interrupt handlers make use of the time. Otherwise, such an interrupt
110 1 could catch timer_val half-updated and get an erroneous time.
111 1 */
112 1 _atomic_(0);
113 1 timer_val++;
114 1 _endatomic_();
115 1 }
116
C166 COMPILER V3.10b, TIMER 27/11/97 13:31:46 PAGE 3
ASSEMBLY LISTING OF GENERATED OBJECT CODE
; FUNCTION init_timer (BEGIN RMASK = @0x8000)
; SOURCE LINE # 59
; SOURCE LINE # 61
0000 E6257002 MOV CAPREL,#0270H
; SOURCE LINE # 62
0004 E6247002 MOV T6,#0270H
; SOURCE LINE # 63
0008 E6A4C380 MOV T6CON,#080C3H
; SOURCE LINE # 66
000C E6B46800 MOV T6IC,#068H
; SOURCE LINE # 67
0010 CB00 RET
; FUNCTION init_timer (END RMASK = @0x8000)
; FUNCTION timer (BEGIN RMASK = @0x40F0)
; SOURCE LINE # 77
; SOURCE LINE # 78
; SOURCE LINE # 92
0012 D110 ATOMIC #02H
; SOURCE LINE # 93
0014 F2F60000 R MOV R6,timer_val
0018 F2F70200 R MOV R7,timer_val+02H
;---- Variable 'temp' assigned to Register 'R6/R7' ----
; SOURCE LINE # 94
; SOURCE LINE # 95
001C F046 MOV R4,R6
001E F057 MOV R5,R7
; SOURCE LINE # 96
0020 CB00 RET
; FUNCTION timer (END RMASK = @0x40F0)
; FUNCTION timer_interrupt (BEGIN RMASK = @0x8000)
; SOURCE LINE # 103
; SOURCE LINE # 112
0022 D110 ATOMIC #02H
; SOURCE LINE # 113
0024 248F0000 R SUB timer_val,ONES
0028 348F0200 R SUBC timer_val+02H,ONES
; SOURCE LINE # 114
; SOURCE LINE # 115
002C FB88 RETI
; FUNCTION timer_interrupt (END RMASK = @0x8000)
MODULE INFORMATION: INITIALIZED UNINITIALIZED
CODE SIZE = 46 --------
NEAR-CONST SIZE = -------- --------
FAR-CONST SIZE = -------- --------
HUGE-CONST SIZE = -------- --------
XHUGE-CONST SIZE = -------- --------
NEAR-DATA SIZE = 4 --------
FAR-DATA SIZE = -------- --------
XHUGE-DATA SIZE = -------- --------
IDATA-DATA SIZE = -------- --------
SDATA-DATA SIZE = -------- --------
BDATA-DATA SIZE = -------- --------
HUGE-DATA SIZE = -------- --------
BIT SIZE = -------- --------
INIT'L SIZE = -------- --------
END OF MODULE INFORMATION.
C166 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -