ATTINY1616 - Final Implementation Questions

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

After a few long days I've completed a prototype board. Coming from a PIC16F15323 to the ATTINY1616 I've noticed a few ups and downs.

 

The peripherals appear to be well thought out with greater configuration than the PIC, but the CLC equivalent having only three inputs is annoying. The pins don't have the same versatility of the PIC, for example TMRDx4 pins are all hard wired.

 

First question is on the event system and how you're expected to utilise this fully when there's only slots for 6 events?!? Unless I have it wrong timer B types requires input via the event system and only supports sync mode slots, so no sleeping the CPU. This correct? It does say TMRB supports async operation in single shot mode but I'm confused how it'll work in async if the input side for the event system is sync.

 

Second question is whether it's possible to read Vdd without using another pin. On PIC's the DAC can be set to use Vdd, then it's piped into the ADC which in turn uses Vref and a read is possible. From scouring the datasheet the DAC's on this AVR only support internal Vrefs. The ADC supports Vdd but will max out above the max Vref value (4.4v if I recall correctly).

 

I may have some further questions but I'll stick them here rather than create new threads all the time.

 

Thanks!

 

Andrew

Attachment(s): 

This topic has a solution.
Last Edited: Wed. Apr 22, 2020 - 01:35 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can get the Vdd voltage, but your internal reference has to be below what you expect Vdd to ever be. Using v1V1 is a pretty safe thing, and ends up giving about the same final result as choosing a higher vref and you do not have to worry about using a vref that exceeds vdd.

 

 

    ... tiny817 ...

 

    VrefAdc0::set( VrefAdc0::v1.1 ); //set adc0 vref (vref peripipheral)

    Adc0 adc0(
        adc0.DIV16,     //prescale
        adc0.ACC64,     //get 64 vals each read
        adc0.DLY64,     //init delay
        adc0.VDDREF,    //VREFSEL = Vdd
        adc0.INTREF     //MUXPOS = intref = adc0 vref = 1.1v
    );
    //ADCres = 1023*Vin/Vrefsel
    //Vrefsel = 1023*Vin/ADCres
    //Vdd = 1023*1.1/ADCres

    for(;;){
        uint16_t v = adc0.single()/64;
        Print( lcd, "adv val: %u \r", v );      // adc val: 236
        v = (1023*1.1*100)/v;
        Print( lcd, "%u.%u \r", v/100, v%100 ); // 4.76
        Rtc::wait(1_sec);
    }

    ...

 

 

 

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

snoopy33 wrote:
First question is on the event system and how you're expected to utilise this fully when there's only slots for 6 events?!?

 

Looking at your config picture, it seems you are always routing signals to the LUT inputs via the event system. Is that really needed? You can connect many peripheral outputs directly to the LUT inputs, this way you can free up some event channels.

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

El Tangas wrote:

snoopy33 wrote:

First question is on the event system and how you're expected to utilise this fully when there's only slots for 6 events?!?

 

 

Looking at your config picture, it seems you are always routing signals to the LUT inputs via the event system. Is that really needed? You can connect many peripheral outputs directly to the LUT inputs, this way you can free up some event channels.

For the LUT's that was the minimum I could make it. Strangely only one comparator is available directly (AC0).

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

curtvm wrote:

You can get the Vdd voltage, but your internal reference has to be below what you expect Vdd to ever be. Using v1V1 is a pretty safe thing, and ends up giving about the same final result as choosing a higher vref and you do not have to worry about using a vref that exceeds vdd.

 

 

    ... tiny817 ...

 

    VrefAdc0::set( VrefAdc0::v1.1 ); //set adc0 vref (vref peripipheral)

    Adc0 adc0(
        adc0.DIV16,     //prescale
        adc0.ACC64,     //get 64 vals each read
        adc0.DLY64,     //init delay
        adc0.VDDREF,    //VREFSEL = Vdd
        adc0.INTREF     //MUXPOS = intref = adc0 vref = 1.1v
    );
    //ADCres = 1023*Vin/Vrefsel
    //Vrefsel = 1023*Vin/ADCres
    //Vdd = 1023*1.1/ADCres

    for(;;){
        uint16_t v = adc0.single()/64;
        Print( lcd, "adv val: %u \r", v );      // adc val: 236
        v = (1023*1.1*100)/v;
        Print( lcd, "%u.%u \r", v/100, v%100 ); // 4.76
        Rtc::wait(1_sec);
    }

    ...

 

Unsure what you've done here. If you set the ADC to ref 1.1v then any Vdd read over 1.1v is going to chomp?

 

 

 

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

>Unsure what you've done here. If you set the ADC to ref 1.1v then any Vdd read over 1.1v is going to chomp?

 

The adc reference is Vdd (REFSEL=VDD).

The input to be measured (MUXPOS =INTREF) is the adc0 vref from the Vref peripheral set to 1V1.

You have a known voltage of 1.1v on the mux pin input from the Vref peripheral, the reference voltage (Vdd) is unknown, the adc result is known, and the resolution is known.

Only 1 unknown and a formula, so can do.

 

The use of the term 'adc vref' has two meanings- one is the adc reference selection, the other is the Vref peripheral output voltage. Is a little hard to write about it without having to distinguish the term at each use.

 

 

adcVref = Vdd (REFSEL)

Vin = Vref peripheral 1.1v routed to adc (MUXPOS)

 

RES = 1023*Vin/adcVref

RES = 1023*1.1/Vdd

Vdd = 1023*1.1/RES

 

if adc RES == 512, that means the voltage measured (1.1v) is half Vdd, so Vdd must be 2.2v.

if adc RES == 256, so 1.1v is a quarter of Vdd, so Vdd must be 4.4v

 

work it out-

Vdd = 1023*1.1/512 = 2.19v

Vdd = 1023*1.1/256 = 4.39v

 

Or maybe another way to think about it- the ratio of RES/1023 is the same as the ratio 1.1/Vdd, so when RES increases you get closer to a ratio of 1 which also means as RES goes up Vdd has to decrease to maintain the same ratio. Since Vdd will be in a range of maybe 3-5v, RES will also be limited to a range of 1.1/3 to 1.1/5  *1023, but 375-225 would still give 150 counts for a range of 2v, and will be accurate enough for most needs.

 

Last Edited: Tue. Apr 21, 2020 - 08:54 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Huh, regardless of measuring Vref (1.1), when it comes to measuring Vdd the ADC still needs a voltage higher than Vdd as a reference otherwise the max value will be 1 << ADC_RESOLUTION.

 

1023*Vdd/Vdd = 1023 :)

 

Which is why I was saying on PIC's the DAC can have it's reference set as Vdd, so the ADC uses Vref as it's reference and measures the DAC which has a value set to ensure DAC < Vref.

 

Last Edited: Tue. Apr 21, 2020 - 08:50 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

snoopy33 wrote:
when it comes to measuring Vdd the ADC still needs a voltage higher than Vdd as a reference

Not necessarily.

 

A common approach (not specific to AVR), is to use Vdd as reference, and "measure" Vref

 

That gives you a ratio of Vref to Vdd. Since Vref is known, Vdd can be deduced.

 

EDIT

 

curtvm must have been typing the same thing simultaneously

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Tue. Apr 21, 2020 - 09:00 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

>the ADC still needs a voltage higher than Vdd as a reference

 

Vdd IS the reference, you just don't know its value. That's why a known value such as the one from the Vref peripheral is measured, as long as its lower than Vdd.

 

You will figure it out eventually.

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

Oh, now I get it. laugh

Brain is obviously pickled this morning!

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

snoopy33 wrote:
Oh, now I get it.

Jolly good.

 

If your issue is now resolved, please mark the solution - see Tip #5 in my signature, below.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

snoopy33 wrote:

...Brain is obviously pickled this morning!

Oh, why did visions of Hannibal just flash by!

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

Last Edited: Thu. Apr 23, 2020 - 04:22 PM