home | area personale         schemi | tutorial | robotica | pic micro | recensioni         forum | chat irc         faq | contatti         store | Ordina PCB
username
password
cerca

 
FORUM: Pic Micro
Tutto quanto riguarda questi microprocessori... progetti, suggerimenti, aiuti, discussioni...ecc


adc 16f628a analog to digital conversion
     
Autore Messaggio opzioni
acilde




una ogni 10 livelli


postato il:
01.05.2021, alle ore 17:14
adc 16f628a analog to digital conversion 

avevo in mente di fare un vu meter con un pic con molti led a due canali
ma mi trovavo nei cassetti solo pic 16f268a / 648A
solo che non avendo adc e non volendo usare il deltasigma
io con l'aiuto di praz abbiamo tirato fuori questo.
Volevo sapere da qualche esperto di assembler se vedeva cose strane che non possono andar bene.

 ; 26/04/2021
;adc 12 bit x 2 canali con pic 16f628a by acilde & praz   ^_^
; license GPL v3.0

;  --|C|-- = C = capacitor connected to constant current generator(ccg)  and GND   
; constant current generator(ccg) connected from +Vsupply - pin1- C(not GND)
;  +Vsupply---ccg---pin1---|C|---GND


; Q=I*t  V=Q/C=I*t/C    I=C*DV/DT  DV=I/C*Dt  

; Vramp/t = 1mV/us (4,095V/4095us)   Fosc=4Mhz F=Fosc/4=1Mhz   T=1/F=1us
; if C=100nF I=100uA

;Linear ramp INPUT = pin1 =Vref  
; Reset C  , npn-bjt connected from pin1 (collector) and GND (emitter)
;base npn-bjt to pin3 - 1.2 Kohm from pin3 to +Vdd - 2,2K from pin3 to GND  
; +Vdd----1,2K--(pin3+base bc547)--2,2K--GND
; npn-bjt can be replaced by  n-mosfet (better)

;Vmax from GND and pin1 = Vdd+0,3 ( see Microchip 16f628a pdf )

;Analog input configuration

;two mode analog input:

; single channel analog input, config CMCON   CM<2:0> = 001
;pin 18 =AN1 (analog input)

; two MULTIPLEXED analog input channels, config CMCON   CM<2:0> = 101
;pin 2 =AN3 (analog input)    CIS=1
;pin 17 =AN0 (analog input)   CIS=0
;pin 18 =AN1 ( CONNECT to + Vdd)



list p=16f628A ; list directive to define processor
#include <p16F628A.inc> ; processor specific variable definitions
errorlevel -302 ; suppress message 302 from list file

__CONFIG _CP_OFF & _LVP_OFF & _BOREN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON &_INTOSC_OSC_NOCLKOUT

; Use _INTOSC_OSC_NOCLKOUT for
; internal 4 MHz osc and no ext reset, use pin Ra5 as an input
; Use _HS_OSC for a 16 MHz ext crystal.
; Use _XT_OSC for 4 MHz ext crystal. Page 95 in spec sheet.


cblock 0x20 ; Begin General Purpose-Register

ADRESL ;8bit low A/D conversion
ADRESH; 4 bit high A/D conversion
OVERFLOWADC ;flag A/D OVERFLOW (bit0)
GODONE   ; flag A/D start-end conversion (bit0)
delayCnt  ; 
delayCnt1 ;
endc

;***** VARIABLE DEFINITIONS
w_temp EQU 0x71 ; variable used for context saving
status_temp EQU 0x72 ; variable used for context saving

;**********************************************************************
ORG 0x000 ; processor reset vector
goto LABEL_setup ; go to beginning of program

; interrupt vector location
ORG 0x004 ; interrupt vector location
BCF T1CON,TMR1ON ;stop timer1 <<<  interrupt, fermo "subito" timer1 (eseguita in 1 +x cicli)****<<<
movwf w_temp ; save off current W register contents
movf STATUS,w ; move status register into W register
movwf status_temp ; save off contents of STATUS register
BCF T2CON,TMR2ON ;stop timer2


; isr code can go here 
BCF INTCON,GIE ;Global interrupt disable
; All interrupts are disabled

CLRF OVERFLOWADC

;test if TMR1 >4095 , yes? OVFLOW
MOVLW 0x0F ;15 ->3840  
SUBWF TMR1H,W ; F - W -> W    test high byte   adcH>=3840 
BTFSC STATUS,C ; Test TMR1H>=15  C=1 
GOTO LABEL_TESToverflow
GOTO LABEL_TEST_CMIF ;test interrupt comparator

LABEL_TESToverflow
BTFSS STATUS,Z  ; Test from C=1:   if Z=1 ADRESH=15 , else ADRESH=16        
GOTO LABEL_OVFLOW

LABEL_TEST_CMIF ;test interrupt comparator
BTFSS PIR1,CMIF ;  CMIF , SCATTATO COMP?
GOTO LABEL_OVFLOW ;NO -> OVERFLOW:SE SIAMO QUI E' PERCHE' E' SCATTATO TMR2 
;else

;---read tmr1---
; read input ANx
MOVF TMR1H, W ;Read high byte
MOVWF ADRESH ; adc value high byte  *******<<<
MOVF TMR1L, W ;Read low byte
MOVWF ADRESL ;  adc value low byte *******<<<
GOTO LABEL_DONE

LABEL_OVFLOW
;set bit OVERFLOWADC =1
MOVLW 0x01 ;
MOVWF OVERFLOWADC  ;   ***********<<<
; SET ADC =4095
MOVLW 0x0F ;ADRESH=15
MOVWF ADRESH
MOVLW 0xFF ;ADRESL=255
MOVWF ADRESL

 ; test CMCON,CIS if required in main program (2 analog channels )

LABEL_DONE:         

BCF GODONE,1  ;(0) A/D conversion value valid
BCF PIR1,CMIF ;Clear pending interrupts COMP 
BCF PIR1,TMR2IF ;Clear pending interrupts TMR2
BSF INTCON,GIE ;Global interrupt enable
LABEL_CONTINUE ;Continue with code
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
; end of A/D conversion

retfie ; return from interrupt

;**********************************************************************

LABEL_setup ; init PIC16F628A
;two mode analog input:
; setup port 
banksel TRISB
clrf TRISB     ; setup PORTB (OR CONFIG required by  YOUR PROGRAM)
banksel TRISA
movlw b'00101111' ; setup PORTA (bit 2=input ramp, bit 4=Reset C )
movwf TRISA       ; setup PORTA CMCON (1 AN ch set CM<2:0> = 101 , 2 AN ch set CM<2:0> = 001)
                      ;CMCON   CM<2:0> = 101 RA1=AN1=one analog ch input, RA0 = D, RA3 = D
                      ;CMCON   CM<2:0> = 001 RA1=AN1 to +5V, RA0 & RA3 = two MPX analog ch input  (CIS = 0/1, AN0/AN3 )
banksel BANK 0
clrf PORTB      ; setup PORTB (OR CONFIG required by  YOUR PROGRAM )

movlw b'00010000' ;RA4 = H  reset C (discharge)
movwf PORTA


LABEL_SETUP_tmr2
banksel T2CON ; Reg. 0x12
movlw b'00000010'; prescaler 1:16
movwf T2CON

LABEL_init_comparators
MOVLW 0x01 ;Init comparator mode
MOVWF CMCON ;CM<2:0> = 001

BSF INTCON,6 ; PEIE Enable peripheral interrupts
BSF INTCON,7 ; GIE Global interrupt enable
BCF PIR1,6 ; CMIF Clear pending interrupts

LABEL_enable_interrupt
banksel PIE1
BCF PIE1,TMR1IE ; off INTERRUPT for timer1   - NO timer1 interrupt!!! ***<<<<<<<
BSF PIE1,1 ; TMR2IE   INTERRUPT for timer2 enabled

banksel BANK 0

goto MAIN_PROGRAM

main_adc


LABEL_READ_AD

;LABEL_setup_TMR1 ;necessario metterlo qui per avere offset timer1 costante
; banksel T1CON ; Reg. 0x10
; movlw b'00000001'; internal clock, async, prescaler 1:1
; movwf T1CON ;

;start A/D

BSF GODONE,1  ; (1) A/D conversion cycle in progress
;start C discharge
BSF PORTA, 4 ;for capacitor discharge

; delay reset C
CALL Delay_100uS ;  0,1mS 

BCF PIR1,CMIF ; CMIF Clear pending interrupts
BANKSEL PIE1
BSF PIE1,CMIE ; CMIE Enable comparator interrupts
BANKSEL BANK 0
; timer1 & timer2
CLRF TMR2 ;TMR2=0
;offset timer1
movlw b'11111111' ;preset TMR1H=255
MOVWF TMR1H

movlw b'11111100' ;preset TMR1L=252 (timer1 stopped in x cycles)
MOVWF TMR1L
;offset timer1 end



LABEL_setup_TMR1 ;necessario metterlo qui per avere offset timer1 costante
banksel T1CON ; Reg. 0x10
movlw b'00000001'; internal clock, async, prescaler 1:1
movwf T1CON ;





BCF PORTA,4 ; start C charge  
BSF T2CON,2 ; TMR2ON
BSF T1CON,0 ; TMR1ON (0CLK)
  ;TMR1H=0 TMR1L=0 TMR2=0


LABEL_WAIT_INT
BTFSC GODONE,1
goto LABEL_WAIT_INT ;aspetta interrupt per ottenere ADRESH , ADRESL , OVERFLOWADC
GOTO END_READ_AD 

MAIN_PROGRAM ;  BEGIN  MAIN PROGRAM

; WRITE YOUR CODE HERE 
;and use 
GOTO LABEL_READ_AD
END_READ_AD  
; for read analog value


; END MAIN PROGRAM

;-----------------------------------------------------------------------------
; Delay 100 uS = (5+(3*Constant))*OSC/4
;-----------------------------------------------------------------------------
Delay_100uS ; Call = 2 cycles
movlw d'31' ; 1 cycle
movwf delayCnt ; 1 cycle
LABEL_DEC
decfsz delayCnt,f ; 
goto LABEL_DEC ; 1+2 cycles
    return ; 2 cycles


END ; directive 'end of program' 



clikka sulle mie stelline per vedere i miei progetti
I motori di ricerca sono tuoi amici( G0o9\e non proprio...) , usarli prima di chiedere non sarebbe male.
La terra è l'aereo che ci trasporta nel cielo
ma dal quale non possiamo scendere (almeno per ora) , perchè danneggiarlo?
acilde




una ogni 10 livelli


postato il:
15.05.2021, alle ore 16:03

(nell'immagine le linee azzurre che collegano: Current source, SW, Capacitor, e il + di Comparator dove si incrociano ci andava un pallino di connessione)
in pratica ho usato tipo questo schema e ci abbiamo costruito il software.

marsram mi ha mandato un messaggio dicendo:

BCF INTCON,GIE
BSF INTCON,GIE
non servono a niente-.
GIE è spento automaticamente alla chiamata di interrupt e si ripristina da solo con il retfie.

Qualcun altro con ulteriori suggerimenti?

A disposizione per ogni domanda.



clikka sulle mie stelline per vedere i miei progetti
I motori di ricerca sono tuoi amici( G0o9\e non proprio...) , usarli prima di chiedere non sarebbe male.
La terra è l'aereo che ci trasporta nel cielo
ma dal quale non possiamo scendere (almeno per ora) , perchè danneggiarlo?
acilde




una ogni 10 livelli


postato il:
15.07.2021, alle ore 19:39
adc 16f628a
il programma in questione che ho proposto dell'adc fatto con il 16f628a, nella gestione dell'interrupt
le istruzioni
BCF INTCON,GIE
BSF INTCON,GIE
adirittura creano problemi , specialmente BSF INTCON,GIE inserita prima di RETFIE
sembra mi crei problemi di STACK OVERFLOW,
quindi direi che NON CI DEVONO ESSERE ( a meno che uno non sia sicuro di quello che otterrà nei suoi programmi).



clikka sulle mie stelline per vedere i miei progetti
I motori di ricerca sono tuoi amici( G0o9\e non proprio...) , usarli prima di chiedere non sarebbe male.
La terra è l'aereo che ci trasporta nel cielo
ma dal quale non possiamo scendere (almeno per ora) , perchè danneggiarlo?
marsram




una ogni 100 livelli
una ogni 10 livelli


postato il:
15.07.2021, alle ore 21:25
In questi micro con un solo vettore di interrupt, quando viene chiamata una interruzione, lo switch GIE viene portato automaticamente a 0 per evitare che una altra fonte di interruzione possa interropmpere la gestione in corso.
Quindi bcf INTCON,GIE all'apertura della gestione dell'interruzione non serve a niente: GIE è già a 0.

L'azione di RETFIE è identica a RETURN, ma aggiunge automaticamente il ripristino di GIE=1 in modo che, terminata la gestione di una interruzione, se ne possa ativare una successiva.

Se setti GIE PRIMA dell'uscita dalla gestione dell'interruzione, dai modo ad un a altra chiamata di interrupt di riportare il P.C. al vettore di interrupt PRIMA della coretta uscita con RETFIE. Il che, ovviamente, manda in palla lo stack...

Se vuoi, si può aggiungere che :
- chiamare tutte le label LABEL_xxx è per lo meno bizzarro.
- c'è una riga banksel BANK 0 che non serve aniente
- e, in generale, il tutto è scritto in modo abbastanza poco comprensibile
acilde




una ogni 10 livelli


postato il:
24.12.2021, alle ore 19:29
domanda: Il simulatore Proteus emula le funzioni dei comparatori nei pic?


clikka sulle mie stelline per vedere i miei progetti
I motori di ricerca sono tuoi amici( G0o9\e non proprio...) , usarli prima di chiedere non sarebbe male.
La terra è l'aereo che ci trasporta nel cielo
ma dal quale non possiamo scendere (almeno per ora) , perchè danneggiarlo?
segui questo thread con grixFC, per questa funzione devi aver installato il software grixFC

torna su
     

Come utente anonimo puoi leggere il contenuto di questo forum ma per aprire una discussione
o per partecipare ad una discussione esistente devi essere registrato ed accedere al sito




 

 
 
indietro | homepage | torna su copyright © 2004/2022 GRIX.IT - La community dell'elettronica Amatoriale