tiny167 and ADC

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello all!

I´ve a problem programming an ATTiny167, and in particular its ADC.

The part is used in a miniature sensor and it suits perfectly its needs (2 PWM channels, 5 SE ADC channels and an UART), with plenty of memory available for programming. I´m commanding it remotely via an RS232 terminal and everything work fine, except.....

now I´m fighting against the ADC, that works fine for the 1st measurement, but then it seems to work (as the flags are changing) but the mux reg is ignored and the data registers are not updated

here is the initialization code of the ADC module. Device is clocked at 8MHz, with its internal oscillator and no dividers; ADC  is in single conversion mode and interrupts are disabled, so the various routines are polling-based

 

 ldi  r16,0x87        ;ADC on, no int, ck/128
 sts  ADCSRA,r16  ;ADC ctrl reg A
 ldi  r16,0x00        ;unipolar, free run
 sts  ADCSRB,r16  ;ADC ctrl reg B
 ldi  r16,0xC8        ;adc7,6,3 disconnected
 sts  DIDR0,r16     ;Digital in disable reg 0
 ldi  r16,0x30        ;adc9,8 disconnected
 sts  DIDR1,r16     ;Digital in disable reg 1
 ldi  r16,0x0E        ;avcc as ref, right adj, gnd in
 sts  ADMUX,r16    ;ADC ctrl reg A

 

here is the main part of the code, that reads several diagnostic channels of the ADC module and then the 2 analog inputs of the sensor

 

 ldi  r16,0x0E         ;set gnd (0x0e)
 sts  ADMUX,r16     ;ADC mux reg
 call adcrd
 ldi  r16,0x0D         ;set avcc/4 (0x100)
 sts  ADMUX,r16     ;ADC mux reg
 call adcrd
 ldi  r16,0x0B         ;set temp
 sts  ADMUX,r16     ;ADC mux reg
 call adcrd
 ldi  r16,0x08         ;set pwm1 
 sts  ADMUX,r16     ;ADC mux reg
 call adcrd
 ldi  r16,0x09         ;set pwm2
 sts  ADMUX,r16     ;ADC mux reg

 call adcrd

 

and here is the routine that starts a conversion and reads the ADC (data is stored in 3 registers, to be converted in ASCII and send via the UART)

 

adcrd:
 call addly
 ldi  r16,0xD7                   ;start conv + reset adif

 nop

 nop

 nop
 sts  ADCSRA,r16              ;ADC ctrl reg A
adcr1:
 lds  cbyte,ADCSRA           ;read adc status
 sbrc cbyte,ADSC              ;completed conversion?
 rjmp adcr1
 lds  scrc1,ADCH               ;read msb
 lds  scrc2,ADCL                ;read lsb
 mov  scrc3,scrc2              ;copy lsb
 swap scrc2  
 ret

 

checking this code with the simulator included in AVR Studio 4.19, it works and the ADC starts the conversion (setting ADSC) and then finishes it (clearing ADSC and setting ADIF), as required. Running the code on a Tiny167 it works too, as the uC is not hanging, but the problem is that only the 1st conversion gives correct results, then all the others show the same value as the 1st, independently of the settings of ADMUX. Repeating the test with a different ADC clock divider (64x) did not change the behavior, same using ADIF to detect the end the conversion. I tried a more drastic remedy, switching off the ADC after each conversion and then on again for the next one, but the ADC data registers are always storing the 1st conversion.

Any idea of what´s wrong? Am I so lucky to fight against a damaged Tiny167?

Thank you in advance for help.

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your code is hard to read and I can't find addly.
.
MG

I don't know why I'm still doing this hobby

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Replace the "magic values"  using official BIT_NAMEs from the datasheet.   This will be self-documenting.

Remove your "unnecessary comments".    Write informative comments when applicable.

 

Paste the "tidied up" code in a proper CODE window in your message.

 

Yes,  it will take 10 minutes out of your life.   You will probably spot your problem in the process.

If not,   we will be happy to help with "readable code"

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
 lds  scrc1,ADCH               ;read msb
 lds  scrc2,ADCL                ;read lsb

Wrong order.

 

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
Paste the "tidied up" code in a proper CODE window in your message.

How to properly post code - illustrated instructions: http://www.avrfreaks.net/comment...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello again!

Here is addly: it´s a small delay routine, to give time to the mux and other analog signals to settle, before starting a conversion

 

;delay routine for adc (use scrc3)
addly:
    ldi       scrc3,0x00
adr1:
    dec     scrc3
    brne   adr1
    ret

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Believe me.   10 minutes of your life is a good investment.

 

Then you will get every point answered in one go.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Please pay attention to the instructions for posting source code!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just swapped the reading of ADCH and ADCL and the ADC is converting correctly all the channels

Thank you so much, sternst....and thanks to all the others for the suggestions about the format: I´ll remember them for next post