ADC e microcontrollore Atmega8535

Sezione dedicata ai Microcontrollori e ai Sistemi Embedded

Re: ADC e microcontrollore Atmega8535

Postby fram » 20 May 2013, 18:30

Scusi se faccio tante domande , ho trovato una formula che mi dice come calcolare il modulo dieci di un numero:
avendo un numero=X ho che il modulo dieci lo calcolo:
X:10=q dove q=Q,d(Q=parte intera)
X-10*Q=Y dove Y è il modulo10 di X
faccio un esempio:calcolo il modulo 10 di 25
25:10=2,5
25-10*2=5
ho quindi che il modulo 10 di 25 è 5
è giusta questa formula per quello che mi serve???
fram
 
Posts: 34
Joined: 09 May 2013, 14:29

Re: ADC e microcontrollore Atmega8535

Postby fram » 21 May 2013, 16:49

@deluca
Salve, non riesco a capire il pezzo di codice che mi ha postato la volta scorsa. mi può aiutare a capire come faccio a fare il modulo 10 del valore chemi viene fornito dal registro x5 dell'ADC. se so come si fa poi posso svolgere il codice.
grazie per l'aiuto.
fram
 
Posts: 34
Joined: 09 May 2013, 14:29

Re: ADC e microcontrollore Atmega8535

Postby deluca » 21 May 2013, 19:27

@fram,
visto che stai studiando e ti stai impegnando... e visto che non è semplice per un neofita scrivere in asm,
ti regalo il codice completo che ho scritto per rispolverare il sempre insostituibile vecchio assembly.
E' chiaro che dovrai reimpostare, nel caso necessitasse, i pin per la gestione del display LCD.

Fammi sapere i risultati della compilazione.... io vado con la versione 4.19 build 730 di AvrStudio.

Code: Select all
;******************************************
; Autore: Giovanni De Luca - INFN-LNS
; Lettura temperatura in °C in Assembly
; Sensore utilizzato LM35 sul canale(0)
; Display LCD 16x2
; Data: 16-05-2013
;******************************************

.include   "m8535def.inc"
      .DSEG
v:                  .Byte    2
volt:               .Byte    2
volt_d:               .Byte    1      
      .CSEG
.ORG   0

_Reset:
      ldi      yl,Low(RAMEND)
      out      SPL,yl
      ldi      yh,high(RAMEND)
      out      SPL+1,yh
      sbiw   yl,32

      call   LcdIni ;inizializza LCD

;----Start Adc
      ldi      zl,0x86
      out      ADCSRA,zl

;----Cursor Off
      ldi      r24,0xC
      call   _LCtr
L0000:

;----Leggi Adc(0)                                             
      ldi      zl,Low(0)
      in      zh,ADMUX
      andi   zh,0xe0
      Or      zl,zh
      out      ADMUX,zl
      call   _Adc
      sts      v,zl
      sts      v+1,zh

;----Volt = V * 5                                             
      lds      r24,v
      lds      r25,v+1
      ldi      zl,Low(5)
      ldi      zh,high(5)
      call   Mp16u
      sts      volt,zl
      sts      volt+1,zh

;----Volt_d = Volt mod 10                                     
      lds      zl,volt
      push   zl
      ldi      zl,Low(10)
      pop      r24
      call   Div8u
      mov      zl,r22
      sts      volt_d,zl

;----Volt = Volt / 10
      lds      r24,volt
      lds      r25,volt+1
      ldi      zl,Low(10)
      ldi      zh,high(10)
      call   Di16u
      sts      volt,zl
      sts      volt+1,zh

;----Posiziona il Cursore a 1 , 1
      ldi      r24,0x7F
      push   r24
      ldi      zl,Low(1)
      pop      r24
      add      r24,zl
      call   _LCtr

;----Mostra su LCD il risultato
      ldi      zl,Low(S000*2)
      ldi      zh,high(S000*2)
      call   _LSc
      lds      zl,volt
      lds      zh,volt+1
      call   _W2Str
      call   _LBW
      ldi      zl,Low(S001*2)
      ldi      zh,high(S001*2)
      call   _LSc
      lds      zl,volt_d
      call   _B2Str
      call   _LBW
      ldi      zl,Low(S002*2)
      ldi      zh,high(S002*2)
      call   _LSc

;----WaitMs 100 prima della prox conversione
      ldi      zl,Low(100)
      call   _Wms

      rjmp   L0000 ;torna al main e do-looppa
L0001:

;----Fine del programma
L0002:
      jmp   L0002

; String constants:
S000:   .db   "Temp:", 0
S001:   .db   ".", 0
S002:   .db   " C ", 0


;-------[ Inizializza LCD
LcdIni:   in      zl,DDRC
      ori      zl,0xf0
      out      DDRC,zl
      sbi      DDRC,3
      sbi      DDRC,2
      cbi      PORTC,3
      cbi      PORTC,2
      ldi      zl,0x10
      rcall   _Wms
      ldi      r24,0x03
      rcall   _LOut
      ldi      zl,0x05
      rcall   _Wms
      rcall   _LEN
      ldi      zl,0x06
      rcall   _Wus
      rcall   _LEN
      cbi      PORTC,4
      rcall   _LEN
      ldi      r24,0x28
      rcall   _LCtr
      ldi      r24,0x06
      rcall   _LCtr
      ldi      r24,0x0c
      rcall   _LCtr
      ldi      r24,0x01
      rcall   _LCtr
      ldi      zl,0x03
      rcall   _Wms
      ret

_Lch:   sbi      PORTC,3
      rjmp   _LNib
_LCtr:   cbi      PORTC,3
_LNib:   mov      r21,r24
      Swap   r24
      rcall   _LOut
      mov      r24,r21
_LOut:   in      r23,PORTC
      andi   r23,0x0f
      Swap   r24
      andi   r24,0xf0
      Or      r24,r23
      out      PORTC,r24
      rcall   _LEN
      ret

;------[ LcdEN
_LEN:   sbi      PORTC,2
      Nop
      Nop
      Nop
      Nop
      cbi      PORTC,2
      push   zl
      ldi      zl,0x04
      rcall   _Wus
      pop      zl
      ret

;------[ Lcd Byte & Word
_LBW:   ld      r24,Z+
      tst      r24
      breq   _LBW1
      rcall   _Lch
      rjmp   _LBW
_LBW1:   ret

;------[ Lcd String constants
_LSc:   lpm
      tst      r0
      breq   _LSc1
      mov      r24,r0
      rcall   _Lch
      adiw   zl,1
      rjmp   _LSc
_Lsc1:   ret

;------[ Adc
_Adc:   sbi      ADCSRA,0x06
_Adc1:   sbic   ADCSRA,0x04
      rjmp   _Adc1
      in      zl,ADCL
      in      zh,ADCH
      sbi      ADCSRA,0x04
      ret

;------[ IntToStr
_B2str:   clr   zh
      clt
      rjmp   _W2st4
_W2str:   clt
      rjmp   _W2st4
_I2str:   clt
      sbrs   zh,0x07
      rjmp   _W2st4
      Com      zl
      Com      zh
      subi   zl,-0x01
      sbci   zh,-0x01
      Set
_W2st4:   push   yl
      push   yh
      push   r6
      clr      r6
      st      -Y,r6
_N2str:   ldi      r21,0x10
      Sub      r22,r22
_N2st1:   lsr      r6
      rol      zl
      rol      zh
      rol      r22
      rol      r6
      cpi      r22,0x0a
      brcs   _N2st2
      sbci   r22,0x0a
      inc      zl
_N2st2:   dec      r21
      brne   _N2st1
      subi   r22,-0x30
      st      -Y,r22
      mov      r22,zl
      Or      r22,zh
      brne   _N2str
_N2st5:   brtc   _N2st3
      ldi      zl,0x2d
      st      -Y,zl
_N2st3:   mov      zl,yl
      pop      r6
      mov      zh,yh
      pop      yh
      pop      yl
      ret

;-----[ Waitms
_Wms:   ldi      r20,0x14
_Wms1:   ldi      r21,0x85
_Wms2:   dec      r21
      brne   _Wms2
      dec      r20
      brne   _Wms1
      dec      zl
      brne   _Wms
      ret

;-----[ Waitus
_wus:   ldi      r22,25
_wus1:   dec      r22
      brne   _wus1
      dec      zl
      brne   _wus
      ret

;------[ 8/8 unsigned division
Div8u:  Sub     r22,r22
        ldi     r23,0x09
        rjmp    Div81
Div80:  rol     r22
        cp      r22,zl
        brcs    Div81
        Sub     r22,zl
Div81:  rol     r24
        dec     r23
        brne    Div80
        Com     r24
        mov     zl,r24
        ret

;------[ 16x16 hardware multiplay
Mp16u:   mul      zl,r24
      movw   r22,r0
      mul      zl,r25
      add      r23,r0
      mul      zh,r24
      add      r23,r0
      movw   zl,r22
      ret

;------[ 16/16 unsigned division
Di16u:   mov      r22,zl
      mov      r23,zh
      mov      zl,r24
      mov      zh,r25
      clr      r24
      Sub      r25,r25
      ldi      r20,0x11
d16u1:   rol      zl
      rol      zh
      dec      r20
      brne   d16u2
      ret
d16u2:   rol      r24
      rol      r25
      Sub      r24,r22
      sbc      r25,r23
      brcc   d16u3
      add      r24,r22
      Adc      r25,r23
      clc
      rjmp   d16u1
d16u3:   sec
      rjmp   d16u1

Ciao
Il mio sito: http://www.delucagiovanni.com ......e la chat: chat/
User avatar
deluca
Site Admin
 
Posts: 1104
Joined: 19 Jun 2011, 10:44
Location: 95123 - Catania (Italy)

Re: ADC e microcontrollore Atmega8535

Postby fram » 22 May 2013, 17:48

@deluca
Salve, grazie per il programma che ha postato, l'ho studiato ed ho visto che stavo procedendo bene con il mio programma. la mia oramai è una curiosità e mi piacerebbe sapere come svolgere il modulo 10 che è l'unico che non riesco a capire, se mi dice cosa fa vedo di scrivere il codice come sto facendo per gli altri punti che servono. è l'unico punto che non capisco, non riesco a capire come mi fa trasformare il risultato dell'ADC in valore da visualizzare.
grazie.
fram
 
Posts: 34
Joined: 09 May 2013, 14:29

Re: ADC e microcontrollore Atmega8535

Postby js-bascom » 22 May 2013, 21:33

il modulo 10 che è l'unico che non riesco a capire
Semplicemente continua a sottrare 10 dal numero, quando il risutalto e' meno di 10 hai la risposta. (almeno io la capisco in questo modo. :-) )
ie 35 modulo 10 e' 5
John Samperi
Ampertronics Pty. Ltd.
www.ampertronics.com.au
* Electronic Design * Custom Products * Contract Assembly
User avatar
js-bascom
 
Posts: 176
Joined: 23 Mar 2013, 02:53
Location: Sydney, AUSTRALIA Ex Nunziata, Mascali (CT)

Re: ADC e microcontrollore Atmega8535

Postby fram » 29 May 2013, 16:28

@deluca
Salve, mi servirebbe avere un chiarimento:
come già detto in precedenza sto utilizzando l'ADC di un atmega8535 per realizzare un termometro, leggendo bene il datasheet ho visto come fare la conversione del risultato che ho dall'adc ora la posto:
ADC Conversion Result After the conversion is complete (ADIF is high), the conversion result can be found in the ADC Result Registers (ADCL, ADCH).
For single ended conversion, the result is:

ADC=Vin*1024/Vref

where VIN is the voltage on the selected input pin and VREF the selected voltage reference
(see Table 84 on page 219 and Table 85 on page 220). 0x000 represents analog
ground, and 0x3FF represents the selected reference voltage minus one LSB

Io ho settato l'ADC Vref=2.56 e Vin mi viene fornita dal sensore LM35 che da 10mV/°C
Ho solo un dubbio facendo un esempio T=25,5°C ho una Vin=250mV
applicando la formula ho che ADC=102 invece di 25,5 devo aggiungere una divisione per 4??
grazie buona giornata
fram
 
Posts: 34
Joined: 09 May 2013, 14:29

Re: ADC e microcontrollore Atmega8535

Postby fram » 14 Jun 2013, 09:39

mi dite se cosi l'ADC è settato in modo corretto:
;###Configuro l'ADC###

ldi temp, (1<<ADEN)|(1<<ADPS2)|(1<<ADPS0) ;Abilito l'ADC,
out ADCSRA, temp ;prescaling=32(f=125KHz),SFIOR=0 (free-running)
ldi temp,192
out ADMUX, temp



Start_ADC:

sbi ADCSRA, ADSC ;Start of conversion (first sample)
in ta, ADCL ;Prendo il risultato in ADCH e lo metto in ta
fram
 
Posts: 34
Joined: 09 May 2013, 14:29

Re: ADC e microcontrollore Atmega8535

Postby js-bascom » 14 Jun 2013, 10:06

Nota che io uso i Macros dell'AVR001 nei prossimi pezzetti di codice (STORE, SETB etc.)

Per iniziare faccio una conversione inutile a non faccio uso del risultato
Code: Select all
;ADC definitions
#define   ADC_0 (0<<MUX2|0<<MUX1|0<<MUX0)
#define   ADC_1 (1<<MUX0)
#define   ADC_2 (1<<MUX1)
#define   ADC_3 (1<<MUX1|1<<MUX0)
#define   ADC_4 (1<<MUX2)
#define   ADC_5 (1<<MUX2|1<<MUX0)
#define   ADC_6 (1<<MUX2|1<<MUX1)
#define   ADC_7 (1<<MUX2|1<<MUX1|1<<MUX0)

;Set up ADC
   ldi      temp,(1<<ADEN|1<<ADPS2)      ;Enable ADC at:32 divider, no ints.
   STORE   ADCSRA,temp
   ldi      temp,(1<<REFS0|ADC_0)      ;Conversion on channel 0, AVCC reference.
   STORE   admux,temp
   SETB   ADCSRA,ADSC,temp2         ;Start 1st conversion to init the adc
WAIT_ADC_init:
   SKBS   ADCSRA,adif,temp2
   rjmp   WAIT_ADC_init            ;Wait for conversion complete
   SETB   ADCSRA,adif,temp2         ;Clear conversion flag

Code: Select all
   ldi      temp,(1<<REFS0|ADC_0)   ;Conversion on channel 0, AVCC reference.
   STORE   admux,temp
   SETB   ADCSRA,ADSC,temp2      ;Start conversion

WAIT_CH0:
   SKBS   ADCSRA,adif,temp2
   rjmp   WAIT_CH0            ;Wait for conversion complete
   SETB   ADCSRA,adif,temp2         ;Clear conversion flag

   LOAD   temp,adcl,temp2         ;Get last conversion result
   LOAD   temp1,adch
negli ultimi tempi uso l'ADSC invece di adif per vedere quando la conversione e finita, un po' piu' semplice, ma no trovo un esempio al momento.
John Samperi
Ampertronics Pty. Ltd.
www.ampertronics.com.au
* Electronic Design * Custom Products * Contract Assembly
User avatar
js-bascom
 
Posts: 176
Joined: 23 Mar 2013, 02:53
Location: Sydney, AUSTRALIA Ex Nunziata, Mascali (CT)

Re: ADC e microcontrollore Atmega8535

Postby fram » 14 Jun 2013, 12:07

Credo di avere impostato bene l'adc..ora mi da un problema:fa la prima lettura ed è ok, poi quando fa la seconda lettura azzera il risultato poi la terza lettura lo da giusto e cosi.. come mai??
P.S. per portare il valore digitalizzato dall'adc (atmega8535) nel valore corretto da visualizzare devo applicare la formula Vin=ADC*Vref/1024???
avendo vref=2,56 Vin=ADC/4???
fram
 
Posts: 34
Joined: 09 May 2013, 14:29

Re: ADC e microcontrollore Atmega8535

Postby fram » 14 Jun 2013, 19:22

Ho risolto alcuni problemi....quello che non riesco a fare è trasformare il valore dell'adc ADCH in valore BCD, sapreste aiutarmi???
grazie...
fram
 
Posts: 34
Joined: 09 May 2013, 14:29

Re: ADC e microcontrollore Atmega8535

Postby js-bascom » 15 Jun 2013, 04:48

Vuoi dire convertrie il valore hex proveniente dal' ADC a numeri es. 0x03FF stampabile con quattro numeri 1 0 2 3 ?

Se questo e' il caso forse questo potra esserti di aiuto, lo uso da molti anni pero' e stato convertito da altri tipi di micros forse non e' il migliore esempio ma funziona.
Attachments
h2d_d2h16.zip
(1.02 KiB) Downloaded 386 times
John Samperi
Ampertronics Pty. Ltd.
www.ampertronics.com.au
* Electronic Design * Custom Products * Contract Assembly
User avatar
js-bascom
 
Posts: 176
Joined: 23 Mar 2013, 02:53
Location: Sydney, AUSTRALIA Ex Nunziata, Mascali (CT)

Re: ADC e microcontrollore Atmega8535

Postby fram » 17 Jun 2013, 09:48

Grazie per l'informazione ma trasformare il codice BCD in codice ASCII l'ho gia fatto.
quello che volevo capire è come trasformare il valore che ho nel registro ADCH in BCD, cioè:
avendo una temperatura di 25,5 °C il sensore LM35 mi fornisce una tensione 255mV e l'ADC la converte mettendola nel registro ADCH.
Per portare il valore che ho in ADCH in modo da avere 25,5(BCD) non capisco come fare.mi sapete aiutare???
fram
 
Posts: 34
Joined: 09 May 2013, 14:29

Re: ADC e microcontrollore Atmega8535

Postby deluca » 17 Jun 2013, 16:16

@fram
beh!, adesso non ricordo ma....
scusa ma non ti avevo già spiegato come fare?
............come convertire il valore binario letto dall'adc per poi visualizzarlo sul display?

guarda nei post precedenti, hai visto il codice che avevo scritto prima ? è tutto lì
Ciao
Il mio sito: http://www.delucagiovanni.com ......e la chat: chat/
User avatar
deluca
Site Admin
 
Posts: 1104
Joined: 19 Jun 2011, 10:44
Location: 95123 - Catania (Italy)

Re: ADC e microcontrollore Atmega8535

Postby Dom » 02 Nov 2016, 20:35

Salve, sono nuovo del forum, un saluto a tutti.
Ho letto la discussione e purtroppo non sono riuscito a venire a capo del mio problema.
Sto usando la scheda STK500 con AVRStudio7, premesso questo praticamente nel momento in cui provo il codice sul controllore atmega8535, con collegato al piedino PA0 (ADC0) il sensore LM35, in uscita, su PORTC (che sarà la porta del LCD) e che momentaneamente collegata agli 8 led che si trovano sulla scheda, non ho alcuna variazione dei led (che dovrebbero rappresentare il binario del valore di temperatura approssimato all'unità). A prescindere se la configurazione mi dava un risultato esatto o meno, il punto è che almeno qualcosa sulla porta a mio avviso doveva uscire dalla conversione;
posto il mio codice che simula un main dove aspetto 10 ms, richiamo la macro "rilevatemp"
alla fine di questo processo dovrei avere in "data_lcd" il valore della conversione per poi dopo 2 secondi mandarlo su PORTC;

Code: Select all
.include "init_lcd.inc"
.include "wait.inc"
.include "wait_1ms.inc"
.include "stampa.inc"
.include "wait_for.inc"
.DEF tmp=r16
.DEF varCont=r17
.DEF data_lcd=r18
.EQU size=16
.EQU E= PORTA7
.EQU RS= PORTA6
.EQU RW= PORTA5




.CSEG
.ORG $0000      rjmp START ; Reset Handler
.ORG INT0addr   reti ; jmp EXT_INT0 ; IRQ0 Handler     
.ORG INT1addr   reti ; jmp EXT_INT1 ; IRQ1 Handler     
.ORG OC2addr   reti ; jmp TIM2_COMP ; Timer2 Compare Handler     
.ORG OVF2addr   reti ; jmp TIM2_OVF ; Timer2 Overflow Handler
.ORG ICP1addr   reti ; jmp TIM1_CAPT ; Timer1 Capture Handler        
.ORG OC1Aaddr   reti ; jmp TIM1_COMPA ; Timer1 CompareA Handler     
.ORG OC1Baddr   reti ; jmp TIM1_COMPB ; Timer1 CompareB Handler     
.ORG OVF1addr   reti ; jmp TIM1_OVF ; Timer1 Overflow Handler     
.ORG OVF0addr   reti ; jmp TIM0_OVF ; Timer0 Overflow Handler     
.ORG SPIaddr   reti ; jmp SPI_STC ; SPI Transfer Complete Handler     
.ORG URXCaddr   reti ; jmp USART_RXC ; USART RX Complete Handler     
.ORG UDREaddr   reti ; jmp USART_UDRE ; UDR Empty Handler   
.ORG UTXCaddr   reti ; jmp USART_TXC ; USART TX Complete Handler     
.ORG ADCCaddr   rjmp ADC_complete ; ADC Conversion Complete Handler        
.ORG ERDYaddr   reti ; jmp EE_RDY ; EEPROM Ready Handler     
.ORG ACIaddr   reti ; jmp ANA_COMP ; Analog Comparator Handler     
.ORG TWIaddr   reti ; jmp TWSI ; Two-wire Serial Interface Handler     
.ORG INT2addr   reti ; jmp EXT_INT2 ; IRQ2 Handler     
.ORG OC0addr   rjmp TIM0_COMP ; Timer0 Compare Handler     
.ORG SPMRaddr   reti ; jmp SPM_RDY ; Store Program Memory Ready Handler     

.org    INT_VECTORS_SIZE

msg0:   .db "WELCOME",0
msg1:   .db "ATMEL-MONITORING SYSTEM",0


start:
   
    INIT_SP:
   ldi tmp,low(ramend)
   out   SPL,TMP
   ldi   tmp,high(ramend)
   out SPH,tmp

   INIT_IO:
   ldi   tmp,0xff
   out DDRC,tmp ;imposto portC come output, 0-7 bit data LCD
   ldi tmp,0xE0
   out DDRA,tmp;imposto i piedini di uscita per E,RS,RW,

   

   INIT_TimerCounter0:
   ;inizializzo TimerCounter0,CTC_normal_mode_OC0-Disconnected,(inizialmente off_no clock source)
   ldi   tmp,(1<<WGM01)|(0<<WGM00)|(0<<COM00)|(0<<COM01)|(0<<CS00)|(0<<CS01)|(0<<CS02)
   out   TCCR0,tmp
   ldi   tmp,0xFF
   out   OCR0,tmp;inizialmente il valore di OCR0 sara pari a max

   init_ADC:
   ldi tmp, (1<<REFS1)|(1<<REFS0)|(1<<ADLAR);internal 2,56 vref, aggiustamento a sinistra;dovrò leggere solo ADCH
   out ADMUX,tmp
   ldi tmp, (1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(0<<ADIE)|(1<<ADPS1)|(1<<ADPS0);ADIE clred, interrupt disable                       ADC_complete, 125kHz ADC
   out   ADCSRA,tmp
   

   sei ;enableglobalinterrupts

   ;inizializzo LCD
   ;init_lcd
   ;stampa,msg0

main:
   wait_for,0,10 ;ripetizioni x*y;tempo base 1ms (quando un parametro è 0 conta l'altro)
   rcall rilevatemp
   wait_for,100,20 ;attendo 2s
   
   out   PORTC,data_lcd; valore in uscita

   rjmp main



rilevaTemp:
   ldi tmp, (1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(1<<ADIE)|(1<<ADPS1)|(1<<ADPS0);avvio conv. con ADSC e abilito ADIE interr.
   out ADCSRA,tmp
   ret


   ;INTERRUPTS

   ADC_complete:
   ;in   data_lcd,ADCL
   in data_lcd,ADCH
   ldi   tmp,(0<<ADIE);disabilito interrupt
   out   ADCSRA,tmp
   reti
   
   TIM0_COMP:
   ldi varcont,0
   reti

Dom
 
Posts: 1
Joined: 02 Nov 2016, 19:29

Previous

Return to Microcontrollori e microprocessori

Who is online

Users browsing this forum: No registered users and 21 guests

cron