Normaal gezien kan je dat allemaal uit de datasheets halen van de PIC, ik weet het, het is een hele boterham om te lezen. Om je enigzins op weg te zetten, kijk eens naar mijn code op
http://studwww.ugent.be/~...esis/code/PIC/PIC_PSD.asm daar heb ik de A/D van een PIC16F877A gebruikt om een sensor uit te lezen.
Enkele codefragmenten die voor je interessant zijn:
De header:
code:
1
2
3
4
5
6
7
8
9
10
| list p=16f877a
include "p16f877a.inc"
; Predefine your configuration Word
;__CONFIG Configuration Word
;_CP_OFF Code Protection
;_WDT_OFF WatchDog Timer
;_HS_OSC HS mode, external 20Mhz clock used
__CONFIG _CP_OFF & _WDT_OFF & _WDT_OFF & _HS_OSC |
Initieel schakelde ik de A/D uit:
code:
1
2
3
4
5
6
| ; initial: disable A/D converter
BANK0
clrf PORTA
BANK1
movlw B'01000100' ; 01xx0100 (ADFM = 1, read the 8 MSB in register ADRESH)
movwf ADCON1 |
En ten slotte het fragment die de Analoge waarde inleest:
code:
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
| ; enable ADC convertor for all analog pins:
BANK1
movlw B'01000100' ; 01xx0100 (ADFM = 1, read the 8 MSB in register ADRESH)
movwf ADCON1
; PSD0 measuring:
BANK0
; bsf VPSD0 ; activate PSD0
movlw B'10001000' ; select conversion clock (Fosc/64) and select input channel (PSD0)
movwf ADCON0
movlw D'025' ; delay 25ms, see time chart in datasheet of GP2D12X
call Delay_1ms
bsf ADCON0,ADON ; turn on the ADC module
; wait during acquisition time
movlw D'0020' ; delay 50 us
call Delay_1us
; start ADC conversion
bsf ADCON0,GO_DONE ; set the go/done bit (start conversion)
ADC_loop_PSD0
btfsc ADCON0,GO_DONE ; if GO/DONE becomes low skip next statement (wait until conversion is done)
goto ADC_loop_PSD0
movf ADRESH,W ; WREG = ADRESH(analog value)
movwf TXDATA_PSD0 ; TXDATA_PSD0 = WREG
bcf VPSD0 ; disable PSD0
bcf ADCON0,ADON ; turn off the ADC module |
Ik vermoed dat dit voor de PIC16F873A wel iets gelijkaardigs zal zijn, maar hoe dan ook zal je voor de initialisatie van bepaalde registers in de datasheets moeten kijken naar wat je precies wil doen.
En de template die je post kan werken met interrupts enzo, het is eenvoudiger uit te gaan van een eenvoudiger template (zonder interrupts, geen lkr file nodig), zelf geschreven voorbeeld (voor de PIC16F877A, met delay-routines):
code:
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
110
111
112
113
114
115
116
117
118
119
120
121
| list p=16f877a
include "p16f877a.inc"
; Predefine your configuration Word
;__CONFIG Configuration Word
;_CP_OFF Code Protection
;_WDT_OFF WatchDog Timer
;_HS_OSC HS mode, external 20Mhz clock used
__CONFIG _CP_OFF & _WDT_OFF & _WDT_OFF & _HS_OSC
; variables in ram, ram starts on 0x20
cblock 0x20
MS_COUNT ; counting in steps of 1ms
US_COUNT ; counting in steps of 1us
endc
;defines:
#define BANK0 banksel PORTA
#define BANK1 banksel TRISA
#define BANK2 banksel EEDATH
#define BANK3 banksel EECON1
ORG 00h ; start program counter
; initialise RAM variables
; disable A/D converter
BANK0
clrf PORTA
BANK1
movlw 0x06
movwf ADCON1
; initialise pins (OUTPUT)
BANK1
bcf TRISD,H'0006'
bcf TRISC,H'0001'
bcf TRISA,H'0005'
; initialise pins (INPUT)
bsf TRISA,H'0001' ; A0 pin
bsf TRISA,H'0000' ; A1 pin
bsf TRISE,H'0001' ; A2 pin
bsf TRISA,H'0002' ; A3 pin
bsf TRISA,H'0003' ; A4 pin
bsf TRISA,H'0004' ; A5 pin
bsf TRISB,H'0004' ; CSExt pin
; initialise the state of the output pins
BANK0
bcf PORTD,H'0006'
bcf PORTC,H'0001'
bcf PORTA,H'0005'
Main
BANK0
bsf PORTC,H'0001'
bsf PORTD,H'0006'
btfsc PORTB,H'0004'
goto LoopA
btfss PORTB,H'0004'
goto LoopB
goto Main
LoopA
bsf PORTA,H'0005'
goto Main
LoopB
bcf PORTA,H'0005'
movlw D'250'
call Delay_1ms
movlw D'250'
call Delay_1ms
movlw D'250'
call Delay_1ms
movlw D'250'
call Delay_1ms
goto Main
; delay subroutines:
Delay_1us ; uses approximatly US_COUNT*5 cycli = US_COUNT*1us
; use by "movlw D'<VALUE>' call Delay_1us, VALUE < 256
BANK0
movwf US_COUNT
us_loop
nop ; 1 cyclus
nop ; 1 cyclus
decfsz US_COUNT,F ; 1 cyclus
goto us_loop ; 2 cycli
return
delay_4cycli
addlw 0xFF ; add -1
btfss STATUS,Z
goto delay_4cycli
return
Delay_1ms ; uses approximatly MS_COUNT*5000 cycli, 20 Mhz clock, so 1 cycli @ 20/4 Mhz = 200ns => 5000*200ns = 1ms
; use by "movlw D'<VALUE>' call Delay_1ms, VALUE < 256
BANK0
movwf MS_COUNT ; put register w in MS_COUNT
ms_loop
movlw D'250'
call delay_4cycli ; 1 + 250*4 = 1001 cycli
movlw D'250'
call delay_4cycli ; 1001 cycli
movlw D'250'
call delay_4cycli ; 1001 cycli
movlw D'250'
call delay_4cycli ; 1001 cycli
movlw D'248'
call delay_4cycli ; 248*4 = 992 cycli
; 4*1001 + 992 = 4996 cycli
nop ; 1 cyclus
decfsz MS_COUNT,F ; decriment MS_COUNT by 1 and test for zero, 1 cyclus
goto ms_loop ; 2 cycli
; 4996 + 4 = 5000 cycli = 1ms
return
end |
[
Voor 41% gewijzigd door
Verwijderd op 25-04-2007 22:42
]