Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

At-Tiny13 power consumption

Status
Not open for further replies.

int3

New Member
hi,

I'm trying to switch the tiny13 in my circuit to power down mode. The following asm-code assembled with AvrStudio causes a current consumption of 0.2uA, which according to the datasheet is what is to be expected:


Code:
CSEG
rjmp start
start: nop
nop
cli
ldi r16 ,LOW (RAMEND) // initialize stack pointer
out SPL ,r16

ldi r16 ,0b00110000 // set SE and SM1 bits (power down mode)
out MCUCR ,r16
sleep


however, the same code in C, on the same circuit and same setup, compiled with avr-gcc produces a current consumption of 2.6uA:

Code:
#include <avr/io.h>
#include <stdint.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>

int main(void)
{


cli();
DDRB=0xff; // PB1-5 = Output
DDRB&=~(1<<4); // PB4 = Input
PORTB|=(1<<4); // Pullup for input

MCUCR=0b00110000;

// asm("sleep");
sleep_cpu();

while(1)
{
}

return 0;
}

Now I need to know what causes the extra 2.4uA when using avr-gcc.
Commenting out the PORTB stuff (leaving the ports undefined) makes no difference btw and neither does defining all ports as output or disabling the pullup resistor for PB4. I've also tried using the asm sleep function instead of avr-libc's sleep_cpu() function, but to no avail.

Any help would be greatly appreciated, I've already posted this in several other forums, but so far nobody has been able to figure out whats going on here.

thanks in advance,

Dominik
 
The way I would try to figure it out would be to disassemble both hex files and then compare both the asm files, to see what the c compiler is doing OR not doing. If you can't do this, post both hex files and I can do it for you.

If it works in assembly, it is obvious that the error is in your c code.
I myself not experienced with c, could not help you there.

Best of Luck
 
Look in sleep.h and see what the function sleep_cpu() really does. Does it expect a parameter to choose one of the sleep modes?
 
That's hardly the same code.
The ASM code inits the stack and immediately slams the chip into sleep mode without setting any I/O modes. From a power downed state the I/O lines automatically come up as inputs in a high Z state. Assuming there's no capacitive coupling to a nearby clock line or internal coupling this is the lowest power state the I/O module can be in. The C code inits PortB as outputs then changes pin4 to an input and enables the pullup so you end up with most of the pins in output mode, the extra current is probably internal leakage current on the I/O lines.
 
Last edited:
I think the pullups on AVRs are about 47k if that's connected to a reverse biased diode you may be looking at leakage current from that, really depends on the rest of the circuit.
 
Is there an echo in here?
CCD, that's exactly what I've already posted.

It's only 2ua of current though, a pullup resistor with a strong pulldown would draw more current than that even at a low VCC so it has to be inherant leakage in something either internally on the driven pins or externally via a diode or high value resistance. If the external circuit won't act abnormally and there is low chance of coupling to the I/O line from noise sources then leave the I/O lines high Z when you go into sleep. If there is a high chance of noise from the external circuit or environment in sleep mode though the AVR will draw some current, mainly at higher frequencies. AVRs are great chips but for super lower power draw you have to be very careful about connection to the outside world when entering sleep mode. If you HAVE to maintain a logic state on an I/O pin in sleep mode they tend to leak a lot 1ua per driven pin acording to the PDF.
 
From a power downed state the I/O lines automatically come up as inputs in a high Z state.

Ok, but shouldn't they be doing the same when I leave out the initialization part in my C program, i.e.:

Code:
#include <avr/io.h>
#include <stdint.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>

int main(void)
{
  MCUCR=0b00110000;
  sleep_cpu();  // or alternatively asm("sleep");
  while(1)
 {
 }
return 0;
}

but I still read 2.6uA. And how do I switch them explicitly to high-Z state?


@johnsmith123: Thanks a lot for the help, I have attached both files in case you want to take a look at them (had to rename them to *.doc, because the extension type was not accepted).
 

Attachments

  • asm.hex.doc
    92 bytes · Views: 150
  • c.hex.doc
    259 bytes · Views: 173
no interrupts enabled

you don't have interrupts enabled.
What will cause the micro to wake up from sleep mode?
there are no I/O lines being initialized in both these codes.
There must be some code missing in both these files.

you should be able to figure this out from these two files:

Code:
from c.hex
	   .cseg
         .org	0
;----------------------------------------------
Reset:    rjmp   Start        ; 
          rjmp   ReStart      ; 
          rjmp   ReStart      ; 
          rjmp   ReStart      ; 
          rjmp   ReStart      ; 
          rjmp   ReStart      ; 
          rjmp   ReStart      ; 
          rjmp   ReStart      ; 
          rjmp   ReStart      ; 
          rjmp   ReStart      ; 
;----------------------------------------------
Start:    clr    r1           ; 
          out    SREG, r1     ; 
          ldi    YL, 0x9F     ; set up stack pointer
          out    SPL, YL      ; 
;----------------------------------------------
          ldi    r17, 0x00    ; clr ram
          ldi    XL, 0x60     ; 
          ldi    XH, 0x00     ; 
          ldi    ZL, 0x54     ; 
          ldi    ZH, 0x00     ; 
          rjmp   avr0016      ; 

avr0014:  lpm    r0, Z+       ; 
          st     X+, r0       ; 
avr0016:  cpi    XL, 0x60     ; 
          cpc    XH, r17      ; 
           brne  avr0014      ; 
;----------------------------------------------
          ldi    r17, 0x00    ; fill ram with value in r1
          ldi    XL, 0x60     ; probably just to waste time
          ldi    XH, 0x00     ; c compilers do this alot
          rjmp   avr001E      ; 
avr001D:  st     X+, r1       ; 
avr001E:  cpi    XL, 0x60     ; 
          cpc    XH, r17      ; 
           brne  avr001D      ; 
;----------------------------------------------
main:
          rcall  avr0024      ; 
          rjmp   avr0028      ; 
;----------------------------------------------
ReStart:  rjmp   Reset        ; restart program
;----------------------------------------------
avr0024:  ldi    r24, 0x30    ; enable sleep mode 
          out    MCUCR, r24   ; (power-down mode) 
          sleep               ; 
avr0027:  rjmp   $            ; loop forever
avr0028:  cli                 ; 
avr0029:  rjmp   $            ; loop forever
;----------------------------------------------
         .exit

this one from asm.hex:

Code:
         .cseg
         .org	0
;----------------------------------------------
          rjmp   Start        ;
Start:  
	   nop                 ; 
          nop                 ; 
          cli                   ; interrupts off
          ldi    r16, 0x9F    ; set up stack pointer
          out    SPL, r16     ; 
          ldi    r16, 0x30    ; enable sleep mode 
          out    MCUCR, r16   ; (power-down mode) 
          sleep               ;
;----------------------------------------------
.exit
 
Last edited:
Are you sure you're flashing the right hex file? The flash dialog does NOT automatically adjust to a new project and will happily burn the pointed to hex from some completely unrelated project if you're not careful. I've done it twice on test code when I was trying a few variations but used a different project file to test it, I forgot to change the .hex file that the STK500 programmer was flashing to the one that the current project was compiling under. If you want to make sure, rip the hex file from the chip De-asm it and see if it's close to the do nothing C code.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top