1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
list P = 18F452
#include P18F452.INC
 
MOVLF macro R, K
    movlw 	K
    movwf 	R
endm
 
    ; 定义了几个寄存器
    R1  	EQU 20H
    R2  	EQU 21H
    R3  	EQU 22H
    R4 		EQU 23H
 
    ORG 	0008H  ;中断向量入口
    GOTO 	SELECT ;跳转到中段服务选择子程序
 
	org		0000h  ;PIC上电时从0000h单元开始执行
	goto	main  ;跳转到主程序
 
	org		0030h  ;主程序定位
main
	clrf	TRISD  ;设定D口方向为输出
    CLRF	TRISC ;设定C口方向为输出
    CLRF	PORTC ;C口置零
    BSF 	TRISB, INT0 ; 设定int0中断源对应引脚为输入
    CLRF 	PORTD
    CLRF	INTCON ;先将中断控制寄存器清零
    BSF 	INTCON, GIE ; 允许全局中断
    BSF  	INTCON, TMR0IE ; 允许TMR0定时器中断
    BSF		INTCON, INT0IE ; 允许int0中断
    MOVLF  	T0CON, 07H ; 设定定时器0的计数模式
 
    ; 给定时器装入初值,定时器为特殊的双缓冲结构,
    ; 注意初值的装入顺序为先高后低
    MOVLF 	TMR0H, 0C2H
    MOVLF  	TMR0L, 0F7H
    BSF  	T0CON, TMR0ON ; 打开定时器开始计数
 
LOOP ; PIC汇编的标号不需要冒号':'
   	;SLEEP  ; 进入Sleep模式
   	GOTO LOOP ; 转啊转
 
 
SELECT ; 中断服务选择程序,这里的测试顺序决定了中断优先级
   	BTFSC   INTCON, TMR0IF ; 测试定时器溢出位,为0则跳过一条指令
   	GOTO   	TMR0_ISR ; TMR0IF为1时,跳转到定时器服务程序
   	;NOP
   	BTFSS   INTCON, INT0IF ; 测试外部中断int0的标志位,为0则跳一步
   	RETFIE ; 中断返回,会涉及到出栈操作
   	GOTO   	INT0_ISR ; 跳转到int0服务程序
 
TMR0_ISR ; 定时器服务程序
   	BTFSS   INTCON, TMR0IF  ; 重新测试溢出位,防止干扰信号触发中断
   	RETFIE
   	BCF  	INTCON, TMR0IF  ; 清除溢出位
   	;BSF  	INTCON, GIE ; 
   	INCF   	PORTD, F ; D口加1
   	MOVLF 	TMR0H, 0C2H ; 计数器初值进行重装
   	MOVLF  	TMR0L, 0F7H
 
   	RETFIE ; 中断返回
 
 
INT0_ISR ; 外部中断int0服务程序
   	;CALL 	delay
   	BTFSS   INTCON, INT0IF  ; 重新测试溢出位,防止干扰信号触发中断
   	RETFIE
   	BCF   	INTCON, INT0IF ; 清除溢出位
   	; 下面的几行通过更改定时器的分频比来改变定时间隔,每次减半
   	MOVFF  	T0CON, R1
   	DECF   	R1, W
   	ANDWF   07H
   	MOVWF   T0CON
   	; D口加1
   	INCF   	PORTD
   	;MOVLF  R1, 0005H
   	;MOVF 	PORTD, W
   	;SUBWF 	R1, W
   	;BNZ 	NEXT
   	;BSF 	PORTC, 0002H
   	;CALL 	DELAY
   	;BCF 	PORTC, 0002H
NEXT
 
   	RETFIE ; 中断返回
 
SPEAKER
  	BSF  PORTC, 0002H
  	RETURN
DELAY  ; 软件延时
	movlw	0xFF
	movwf 	R1
L3
	movlw	0x1f
	movwf	R2
L2
	movlw	0x1f
	movwf	R3
L1
	decf	R3, F
	bnz		L1
	decf		R2, F
	bnz		L2
	decf		R1, F
	bnz		L3
	return
 
end

  PIC的汇编实在诡异,有点被颠覆的感觉,原来汇编指令还可以这么来设计,原来汇编指令怎么设计都可以。最OOXX的一条指令就一个实现短转移的指令叫做BRA,意为BRAanch,看到这条指令的时候,我都诧异了,奶罩能做什么?哇塞!居然还能跳转!?奶罩居然可以无条件跳转?!Orz……另外PIC指令把单词缩写运用的淋漓尽致,譬如指令BTFSS,是一条位测试加条件跳转指令:BTFSS = Bit + Test + FileRegister + Skip + Set,用法:BTFSS R1, 0003h, 寄存器R1的第3位为1时跳过下一条指令。真是震撼!

  最后附上PIC18的中断体系硬件结构图,出自陈育斌老师的手笔:

PIC18中断体系硬件结构示意图

PIC18中断体系硬件结构示意图

Tags: ,.
你好!除了代码,此处没有多少原创之物,皆为本人搜集、整理、总结之记录与心得,欢迎转载分享!转载时请尽量注明出处,将不胜感激。祝你健康、快乐!
Home

RFC: Request For Comments. Orz..

Be the first to comment on this entry.

Name(required)
Mail (required),(will not be published)
Website(recommended)