Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

A/D converter met pic 16f873A (in ASM)

Pagina: 1
Acties:
  • 432 views sinds 30-01-2008
  • Reageer

  • bazzzzzz
  • Registratie: Januari 2007
  • Laatst online: 21-11 10:00
Hey,

Ik ben begonnen aan de volgende uitdaging. De A/D converter van de pic gebruiken. Erg leuk idee maar echt gemakkelijk gaat het nog niet. Voor zover ik het tot nu toe snap geef je eerst een commando zodat de pic begint met de A/d conversie. En dan kan je in ADRESL en ADRESH de least significant bits en de highest significant bits uit kan lezen. Hoe vertaal ik dit naar de ASM code? Het ideaalst zou zijn als iemand een voorbeeldje heeft.

De bedoeling is om eerst gewoon het signaal van mijn voeding uit te lezen(tussen 0 en 5 volt) en dit later uit te bouwen tot een vu meter met creatieve effecten

alvast bedankt voor de reacties!

  • naftebakje
  • Registratie: Februari 2002
  • Nu online
Op de site van microchip kan je ongetwijfeld application note's vinden, waarin je werkende code zal aantreffen; maar zo'n programma kan je erg gemakkelijk zelf in elkaar steken. Neem de datasheet, het hoofdstuk over de A/D convertor, lees dat enkele keren door terwijl je de code tikt, dan moet het wel lukken.
Een beetje eigen inzet, wat tijd (half uurtje als je het ASM programmeren al wat onder de knie hebt) en de datasheet, meer heb je niet nodig :Y)

[ Voor 8% gewijzigd door naftebakje op 16-04-2007 22:15 ]

Als de boer zijn koeien kust, zijn ze jarig wees gerust. Varkens op een landingsbaan, leiden nooit een lang bestaan. Als de boer zich met stront wast, zijn zijn hersens aangetast. Als het hooi is in de schuur, zit het wijf bij den gebuur.


  • bazzzzzz
  • Registratie: Januari 2007
  • Laatst online: 21-11 10:00
ik heb inmiddels dit gevonden op de site van microchip:

http://ww1.microchip.com/downloads/en/DeviceDoc/31023a.pdf

daarmee moet ik ook al een eind komen denk ik. Dan zit ik nog met het verwerken van de date aangezien het nog gedeeld enzovoort moet worden(naja als ik het binair uitlees zou ik er gewoon 8 leds aan kunnen hangen)

ik zal morgen wel ff klooien met breadboardje en als het niet lukt gooi ik wel weer de code hierneer

  • naftebakje
  • Registratie: Februari 2002
  • Nu online
Voor uitlezen lijkt het me idd het handigst om 8-bits uit te lezen en die rechtstreeks op een poort te zetten, dan zie je meteen hoe en of het werkt.

Als de boer zijn koeien kust, zijn ze jarig wees gerust. Varkens op een landingsbaan, leiden nooit een lang bestaan. Als de boer zich met stront wast, zijn zijn hersens aangetast. Als het hooi is in de schuur, zit het wijf bij den gebuur.


  • bazzzzzz
  • Registratie: Januari 2007
  • Laatst online: 21-11 10:00
hehe tis heel erg maar de intialisatie van de pic in mplab loopt al niet lekker. De config staat wel goed lijkt mij:
__CONFIG _CP_OFF & _DEBUG_OFF & _WRT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _PWRTE_OFF & _WDT_OFF & _HS_OSC

Alleen het soort oscilator twijfel ik over want op de 873a kan je er 2 aansluiten zag ik ergens in een schema. Deze informatie komt uit het 16f873a.ini bestand van mplap maar waar kan ik al het bank select gedoe en dergelijke vinden? Want je moet toch ook nog het begin en alles van je programma aangeven?

  • naftebakje
  • Registratie: Februari 2002
  • Nu online
Ziet er goed uit, je oscillator staat op HS dus je gebruikt een kristal van 16MHz of meer. In de datasheet vind je de nodige uitleg.
Voor het begin van je programma enzo kan je de template's gebruiken die bij MPLAB meegeleverd zijn, dat moet ergens 16f873A.ASM ofzo zijn, daarin staat alles klaar om te beginnen programmeren.

Voor het bank select gedoe kan je "banksel (register)" gebruiken, dan wordt er naar de bank die (register) bevat gesprongen, vergeet niet terug te keren naar bank0 als je variabelen gebruikt ("banksel porta" ofzo), variabelen zijn ook "bankgevoelig".

Als de boer zijn koeien kust, zijn ze jarig wees gerust. Varkens op een landingsbaan, leiden nooit een lang bestaan. Als de boer zich met stront wast, zijn zijn hersens aangetast. Als het hooi is in de schuur, zit het wijf bij den gebuur.


  • bazzzzzz
  • Registratie: Januari 2007
  • Laatst online: 21-11 10:00
20mhz kristal gebruik ik. Dus mijn keus voor HS was goed. Templates daar kan ik wat mee, ik zal eens gaan zoeken. Bedankt:D

  • bazzzzzz
  • Registratie: Januari 2007
  • Laatst online: 21-11 10:00
hmmmmmmmmmmm die template is neit erg fantastisch:
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
;**********************************************************************
;   This file is a basic code template for object module code         *
;   generation on the PICmicro PIC16F873A. This file contains the     *
;   basic code building blocks to build upon.  As a project minimum   *
;   the 16F873A.lkr file will also be required for this file to       *
;   correctly build. The .lkr files are located in the MPLAB          *  
;   directory.                                                        *
;                                                                     *
;   If interrupts are not used all code presented between the         *
;   code section "INT_VECTOR and code section "MAIN" can be removed.  *
;   In addition the variable assignments for 'w_temp' and             *
;   'status_temp' can be removed.                                     *                         
;                                                                     *
;   If interrupts are used, as in this template file, the 16F873A.lkr *
;   file will need to be modified as follows: Remove the lines        *
;     CODEPAGE   NAME=vectors  START=0x0      END=0x4      PROTECTED  *
;   and                                                               *
;     SECTION    NAME=STARTUP  ROM=vectors                            *
;   and change the start address of the page0 section from 0x5 to 0x0 *                                                               *
;                                                                     *
;   Refer to the MPASM User's Guide for additional information on     *
;   features of the assembler and linker (Document DS33014).          *
;                                                                     *
;   Refer to the respective PICmicro data sheet for additional        *
;   information on the instruction set.                               *
;                                                                     *
;**********************************************************************
    list        p=16f873a   ; list directive to define processor
    #include    <p16f873a.inc>  ; processor specific variable definitions
    
    __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _RC_OSC & _WRT_OFF & _LVP_ON & _CPD_OFF

; '__CONFIG' directive is used to embed configuration data within .asm file.
; The labels following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.


;***** VARIABLE DEFINITIONS (examples)

; example of using Shared Uninitialized Data Section
INT_VAR     UDATA_SHR   0x71   
w_temp      RES     1       ; variable used for context saving 
status_temp RES     1       ; variable used for context saving
pclath_temp RES 1       ; variable used for context saving


; creating copies of interupt context saving variables in bank1
INT_VAR1    UDATA_SHR   0xF1
w_temp1     RES     1       ; variable used for context saving 


; example of using Uninitialized Data Section
TEMP_VAR    UDATA_SHR   0x20        ; explicit address specified is not required
temp_count  RES 1       ; temporary variable (example)


;**********************************************************************
RESET_VECTOR    CODE    0x000       ; processor reset vector
    nop             ; nop required for icd
    movlw   high  start     ; load upper byte of 'start' label
    movwf   PCLATH          ; initialize PCLATH
    goto    start           ; go to beginning of program


INT_VECTOR  CODE    0x004       ; interrupt vector location
    movwf   w_temp          ; save off current W register contents
    movf    STATUS,w        ; move status register into W register
    bcf STATUS,RP0      ; select bank0
    movwf   status_temp     ; save off contents of STATUS register
    movf    PCLATH,w        ; move pclath register into w register
    movwf   pclath_temp     ; save off contents of PCLATH register


; isr code can go here or be located as a call subroutine elsewhere

    bcf STATUS,RP0      ; select bank0
    movf    pclath_temp,w       ; retrieve copy of PCLATH register
    movwf   PCLATH          ; restore pre-isr PCLATH register contents
    movf    status_temp,w       ; retrieve copy of STATUS register
    movwf   STATUS          ; restore pre-isr STATUS register contents
    swapf   w_temp,f
    swapf   w_temp,w        ; restore pre-isr W register contents
    retfie              ; return from interrupt


MAIN    CODE
start

    nop             ; code starts here (example)

; remaining code goes here

    END                       ; directive 'end of program'

Ik haal de code tusen " INT_VECTOR" en "MAIN" weg(staat bovenaan beschreven) ik gebruik immers geen intrerupts. Dan gooi ik er ff code in zodat ik een led laat knippern op PORTC,1 dan wil ik het builden maar krijg ik de error:

Error[149] C:\PIC\873A TEMPLATE.ASM 41 : Directive only allowed when generating an object file. Dit slaat op de "INT_VAR" Ik verdenk mplab ervan dat ik de instellingen ergens niet goed heb staan want het builden zou toch gewoon moeten kunnen?

En deze error heb ik 6 keer(allemaal dezelfde slaat alleen telkens ergens anders op)

  • bazzzzzz
  • Registratie: Januari 2007
  • Laatst online: 21-11 10:00
[schopje] is er iemand die mij verder kan helpen of een wat uitgebreidere template heeft? Ik vraag me op dit moment een beetje af waar het probleem nu eigenlijk inzit

  • bazzzzzz
  • Registratie: Januari 2007
  • Laatst online: 21-11 10:00
sorry ik schop hem nog een keer omhoog :$ Na nog een aantal pogingen vraag ik me toch echt af wat er fout gaat? Iemand die me teminst op het goede spoor kan brengen?

  • jerbro
  • Registratie: September 2001
  • Niet online
Heb je de aanwijzingen die in het grote blok commentaar boven het programma gevolgd, en de 'linker file' toegevoegd aan je project?

Verwijderd

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 ]


  • bazzzzzz
  • Registratie: Januari 2007
  • Laatst online: 21-11 10:00
@pikachuf erg bedankt! Het staat inderdaad allemaal in de datasheet maar als ik de hexfiles in de pic zet en vervolgens test dan gebeurt er niets. Vandaar het idee dat er ergens iets fout ingesteld staat.

Ik zal met jou code eens verder gaan:D dan zou het toch moeten lukken lijkt mij:)
Pagina: 1