Author Topic: A more efficient blink for AVR processors  (Read 15773 times)

0 Members and 2 Guests are viewing this topic.

Offline GiantGnomeTopic starter

  • Contributor
  • Posts: 25
  • Country: dk
A more efficient blink for AVR processors
« on: March 23, 2014, 01:52:14 pm »
I have decided to make my life more miserable and have started trying to wrap my mind around assembler programming for the AVR core. I have used the ]AVRA assembler for the reason that it was the first thing, that popped up in the Ubuntu Software Center.

As a first shot, I have attempted to implement the classic blink example. You put the clock speed and the number of milliseconds in the top of the program, and you are ready to go. The program is very space efficient (42 bytes), and if my cycle accounting is done right, it should be precise to the
extent of your clock speed precision.  To compare to the arduino blink example, which compiles to over a kilobyte and does not look to be precise to the microsecond.

Is there any grey-bearded assembly sage out there with any advice about this code, ie. other than to stay away from assembly in the first place?

Is there anyone out there with another example of super efficient assembler code for 'common' microcontroller tasks?

Code: [Select]
; My first piece of assembler code. It is made to mimic the blink
; example from the Arduino environment. The arduino example compiles
; to around 1Kb - this is 42 bytes. And should be very
; precise in the timing.
; It is possible to reduce the size of the program at the cost of
; precision by removing some of the nop's in the delay subroutine.
.nolist;
.include "m88def.inc";
.list;


; SETTING CLOCK SPEED - currently at 16 MHz
.equ clockCyclesPerMilliSecond = 16*1000
; The delay to put between blinks in milliseconds
.equ delayMilliseconds = 1000
; The direction register, the port and the bit to set the pin of the
; LED to flash
; Currently at PB5 (Arduino pin 13)
.equ DDR = DDRB
.equ PORT = PORTB
.equ BIT = 5

; SETTING UP REGISTERS
.DEF my_register = R16

; From some example. Not sure if this is needed... It works without it,
;     so it is currently removed to save 2 bytes of program space :-)
; rjmp setup

; setup
setup:
    SBI     DDR,BIT         ; Set pin to output

loop:
    sbi     PORT,BIT        ; 2 cycles - set pin HIGH
    rcall   Delay           ; 3 cycles (the call itself)
    cbi     PORT,BIT        ; 2 cycles - set pin LOW
    rcall   Delay           ; 3 cycles (the call itself)
    rjmp    loop            ; 2 cycles (the jump itself) - repeat
   
Delay:
    nop
    ; Delay consists of two loops - the inner loop loops for a
    ; millisecond, the outer counts the number of milliseconds-
    ; From every inner loop, there is subtracted the number of
    ; cycles to complete the outer loop (8). From the first time, there
    ; is also subtracted the number of cycles to call, setup and return
    ; from the subroutine as well as the cycles for switching the pin,
    ; half of the rjmp command and the nop in the start of this function
   
    ; inner loop : 4 cycles
    ; outer loop : 8 cycles
    ; pin switching, calling, returning and looping : 16 cycles
   
    ; Since precision is made by cutting the number of times the
    ; inner loop runs, it is important that the number of cycles
    ; in the outer loop and the one-time-fluff is divisble by 4.
   
    ldi     ZH,HIGH((clockCyclesPerMilliSecond-8-16)/4)
    ldi     ZL,LOW((clockCyclesPerMilliSecond-8-16)/4)
    ; A lot of nops and grief could be saved by only supporting a
    ; maximum of 255 millisecond delay.
    ldi     YL,LOW(delayMilliseconds)
    ldi     YH,HIGH(delayMilliseconds)
   
    delayloop:
            sbiw    ZL, 1       ; 2 cycles
            brne    delayloop   ; 2 cycles
       
        sbiw    YL,1                                     ; 2 cycles
        ldi     ZH,HIGH((clockCyclesPerMilliSecond-8)/4) ; 1 cycle
        ldi     ZL,LOW((clockCyclesPerMilliSecond-8)/4)  ; 1 cycle
        nop ; added to make a number of cycles divisible by 4 1 cycle 
        nop ; added to make a number of cycles divisble by 4  1 cycle
        brne    delayloop                                ; 2 cycles
   
    nop ; added to make a number of cycles divisible by 4 ; 1 cycle
    ret ;                                                   3 cycles
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: A more efficient blink for AVR processors
« Reply #1 on: March 23, 2014, 01:55:12 pm »
Quote
super efficient

The answer depends on your definition of "efficiency".
================================
https://dannyelectronics.wordpress.com/
 

Offline GiantGnomeTopic starter

  • Contributor
  • Posts: 25
  • Country: dk
Re: A more efficient blink for AVR processors
« Reply #2 on: March 23, 2014, 02:05:05 pm »
Well, lets keep it to speed efficient, memory efficient and/or program space efficient. Maybe power efficient also. No softies like readability or such :-)

My blink example is quite space efficient, and uses no RAM, if I understand it correctly. Speed optimization does not make sense in a blink example, but it could probably be way more power efficient by utilizing some of the power saving features of the AVRs.

Maybe that is how I should spend my sunday  :)

Other idea for types of efficiency?
 

Offline Rasz

  • Super Contributor
  • ***
  • Posts: 2616
  • Country: 00
    • My random blog.
Re: A more efficient blink for AVR processors
« Reply #3 on: March 23, 2014, 02:11:18 pm »
pcik one
Well, lets keep it to speed efficient, memory efficient and/or program space efficient. Maybe power efficient also. No softies like readability or such :-)

pick one, maybe two if you are lucky

your post suspiciously reminds me of this :)
« Last Edit: March 23, 2014, 02:13:18 pm by Rasz »
Who logs in to gdm? Not I, said the duck.
My fireplace is on fire, but in all the wrong places.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: A more efficient blink for AVR processors
« Reply #4 on: March 23, 2014, 02:19:44 pm »
 -, and uses no RAM,-

that would depend on your definition of ram.
================================
https://dannyelectronics.wordpress.com/
 

Offline GiantGnomeTopic starter

  • Contributor
  • Posts: 25
  • Country: dk
Re: A more efficient blink for AVR processors
« Reply #5 on: March 23, 2014, 03:15:04 pm »
-, and uses no RAM,-

that would depend on your definition of ram.

That would be, SRAM. Sorry about that. Is it correctly understood, that when I use only registers and program space, I avoid using SRAM? I have acquired a handful of attiny13a's with only 32 bytes of SRAM and 1kB of program memory,  which encourages me to be somewhat frugal with memory use. As I can figure, the attiny13a couldn't hold the blink example without doing some optimization on it. It compiled to 1084 bytes.

your post suspiciously reminds me of this :)


Other than using inline assembly in arduino, it also reminds me of my project :-). I have used mostly information from here to piece together the instructions: http://www.avr-asm-tutorial.net/avr_en/index.html.
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: A more efficient blink for AVR processors
« Reply #6 on: March 23, 2014, 04:06:58 pm »
I'll be the first one to encourage to learn assembly, but I wouldn't use it to do tight loops for timing, although it will work it has no real practical application since you are just using the cpu constantly so you can't do anything other than to blink that LED.

Since the AVR chip doesn't have a performance counter (counts cycles executed by the processor) I would recommend to use timers and counters instead of looping cycles. Not only it will be more accurate (if done right) but you can still use your cpu for other things.
   
Some links that might be of use:
   
http://www.seanet.com/~karllunt/interval.html
http://www.wrightflyer.co.uk/Using%20AVR%20Counter.pdf

Only time I would use code cycle delays are for communications where a NOP delay here and there might make all the difference in the world.
 

Offline zapta

  • Super Contributor
  • ***
  • Posts: 6190
  • Country: us
Re: A more efficient blink for AVR processors
« Reply #7 on: March 23, 2014, 04:41:40 pm »
Is there any grey-bearded assembly sage out there with any advice about this code, ie. other than to stay away from assembly in the first place?

No grey grey-bearded assembly sage here, more like an Arduino newbe, but here are my 2c:

Premature optimization is one of the seven deadly sins of programming.

http://blogs.msdn.com/b/ericgu/archive/2006/06/26/647877.aspx

If your goal is a blinking program, then the stock Arduino example is just fine and fits in memory, problem solved.  If you have another goal that requires higher level of efficiency, you can still do a lot using efficient C++ code and examine the output of gcc using (IIRC)  something like 'avr-objdump -S <pass to the .elf file generated by the Arduino IDE>'

You probably better spend your time learning writing efficient C++ code. I had to do just the same recently when implementing a protocol proxy/injector based on Arduino Mini Pro. All code is in C++, 20kbs two way bit banging, protocol decoding and generation, application specific logic, 115Kbs continuous serial output stream, using high level libraries like sprintf, using 'inline' everywhere, and still the program is less than 8KB in size (my AVR has 32K).  (my arduino project is here https://github.com/zapta/linbus/tree/master/prototype/arduino )

These little AVR's and the Arduino IDE are very capable and gained my respect.
 

Offline zapta

  • Super Contributor
  • ***
  • Posts: 6190
  • Country: us
Re: A more efficient blink for AVR processors
« Reply #8 on: March 23, 2014, 04:56:43 pm »
I'll be the first one to encourage to learn assembly, but I wouldn't use it to do tight loops for timing, although it will work it has no real practical application since you are just using the cpu constantly so you can't do anything other than to blink that LED.

I think this is the main obstacle that new programer face when they want to go from the blinking led example to more complex programs. The delay() function is basically a dead end for the reason you mentioned.  I wrote several Arduino program recently (my firsts) and came up with a simple model for multi tasking.  Maybe I will find time to do a writeup, don't know.  The rules are very simple

1. Don't use delay and other long blocking functions.
2. Implement each task has having these two methods  void setup(); and void loop();
3. In the main setup() call exactly once the setup of each of your tasks (and same for loop).

Now you have not an arduino but an arbitrary number of parallel arduinos.

A blinking task can be implemented for example as:

setup() {
  init the led output
}

loop() {
  if (time in millis % 1000 > 500) {
     set led ON
  } else {
    set led OFF
  }
}

I would rename the arduino's delay function to evilEvilEvilDelay().   It definitely is.  ;-)
 

Offline madires

  • Super Contributor
  • ***
  • Posts: 7765
  • Country: de
  • A qualified hobbyist ;)
Re: A more efficient blink for AVR processors
« Reply #9 on: March 23, 2014, 05:01:21 pm »
Here we go:
- use the pico power version of the AVR
- check which timer keeps running in which sleep mode, also take care about the clock source
- setup timer for the delay
- in the corresponding ISR toggle a flag and update the blink pin based on the flag
- sleep
 

Offline vvanders

  • Regular Contributor
  • *
  • Posts: 124
Re: A more efficient blink for AVR processors
« Reply #10 on: March 23, 2014, 05:04:06 pm »
+1 on using a timer and learning sleep modes. Low power usage is just as hard(if not harder) than performance and extremely useful in battery situations.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: A more efficient blink for AVR processors
« Reply #11 on: March 23, 2014, 05:07:49 pm »
Quote
The rules are very simple

An excellent programming practice is to break those rules.

Quote
1. Don't use delay and other long blocking functions.

It depends on your application.

Quote
I would rename the arduino's delay function to evilEvilEvilDelay(). 

There are no evil / stupid routines or approaches, only evil / stupid programmers utilizing those routines and approaches inappropriately.
================================
https://dannyelectronics.wordpress.com/
 

Offline nuhamind2

  • Regular Contributor
  • *
  • Posts: 138
  • Country: id
Re: A more efficient blink for AVR processors
« Reply #12 on: March 23, 2014, 06:11:01 pm »
For the best granularity nothing beat a simple nop. In my graduation project (an AVR VGA adapter) I use nop for short delay and for dummy code (in which i'm gonna replace with a more usefull code),for long delay I use loop.
 

Offline dfmischler

  • Frequent Contributor
  • **
  • Posts: 548
  • Country: us
Re: A more efficient blink for AVR processors
« Reply #13 on: March 23, 2014, 06:25:59 pm »
I wrote many thousands of lines of assembly language before 1990 or so.  And my beard would be gray if I didn't shave it off every day or so.

It looks to me like your program is using RAM to store return addresses on the stack and return through them.

Knowing how to write assembly language will give you a good mindset for writing other languages.  And your ideas about performance/timing are essentially identical to the ones used by people writing code for early microprocessors, but they don't scale up when the systems start getting more complicated (e.g. multiple issue, cache memory, virtual memory, real-time task scheduling, etc).

I wrote a lot of assembly to do low-level things with hardware (e.g. device drivers), or to interface to system software that had no high-level call procedures, or to implement whole systems on hardware platforms with small memories.  I even wrote a few cross-assemblers and a linker in PDP-11 assembler (and I wrote a cross-assembler in TI-990 assembly).  Programmers fought over CPU architecture because it mattered when your code depended on it.  Fortran-66 was the most portable language for the minicomputers when I got into the industry.  I wrote something a lot like a compiler in Fortran once because it needed to run on DEC, DG, TI and IBM systems; it ran really slowly, though.  The C language was not popular except on Unix until sometime in the early-mid 80's.  Source language debugging tools were rare, too.

Then all that changed.  You could get a C compiler for almost anything, and if you wrote your code carefully it would run on almost any platform.  You could get a cross-compiler for your micro of choice that would run on a low-cost development system, and your program would fit in the target memory.  And your program would mostly run fast enough.  You could write a little bit of assembler to fix speed problems if you had to.  I can't think of any good reason to write a large program in assembler now.
« Last Edit: March 23, 2014, 06:38:31 pm by dfmischler »
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: A more efficient blink for AVR processors
« Reply #14 on: March 23, 2014, 07:07:57 pm »
I can't think of any good reason to write a large program in assembler now.

Same reason as in the 80's embedded processors have the same limitations as our old microprocessors. Some only have 2K of programming space, granted they run on batteries and for a long time as well.

The Z80 is still on it's prime for home automation and other embedded aplications, specially since it was originally designed for just that. 6502's are also still in production and everywhere.

Although it seems PICs and AVRs are taking over. But there are a lot of embedded processors everywhere you look. The other day I was looking at the datasheet for an NFC chip PN5321/C1 and it has an 80C51 microcontroller built in with 40KB Rom program on it. Also another chip AK2117  (single chip digital multimedia) for mp3 and video players, also has an integrated 80C51.

Anyways, the smaller and more portable and less power the most likely you don't have a lot of coding space on them. So I think there is still a place for assembly when you are working on very spartan MCUs integrated in the die of some chip.


Edit: and I also programmed in Vax assembler and it's the only chip that had queuing instructions that I've ever encountered, and yes my beard as a lot of grey on it ;)
« Last Edit: March 23, 2014, 07:50:56 pm by miguelvp »
 

Offline T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 21686
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: A more efficient blink for AVR processors
« Reply #15 on: March 23, 2014, 10:57:12 pm »
Meh, I'd rather have Z80, or HC08/11 or something like that, than RISC.  It's just too verbose; you spend several lines just doing anything (setting up and reading an array, for instance).  At least it's not as bad as 6502 must've been, back in the day -- having to pull everything through a single accumulator register, ewww. :o

I do love that R0-R15 are basically universal accumulators (though the difference between R0-R15 and R16-R25(-R31) is annoying at times).  That's more register bits and (needless to say) more orthogonality than 8086.

MSP430 and MIPS32 (i.e., PIC32) are other instruction sets I should investigate.  They look comparable (RISC-ey) while being richer (bigger instructions, at least in the case of MIPS), without being overly complex (look at all the instruction parameters on an ARM -- take your pick as far as model).

And let's not forget 8051 that's still around... :P

Tim
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: A more efficient blink for AVR processors
« Reply #16 on: March 24, 2014, 02:48:07 am »
As someone pointed out, you're using some RAM for the stack.  It's a good thing you used one of the AVRs that initializes the SP for you.

Without changing the general logic, I see a couple of changes:
1) Uses the "output to PINx" to toggle pins feature.
2) jump to your Y reload instead of including it twice.
3) replace doubled no-ops with two-cycle no-ops like "rjmp ."

Code: [Select]
.equ PORT = PINB
.equ BIT = 5


setup:
    SBI     DDR,BIT         ; Set pin to output

loop:
    sbi     PORT,BIT        ; 2 cycles - set pin HIGH
    rcall   Delay           ; 3 cycles (the call itself)
    rjmp    loop            ; 2 cycles (the jump itself) - repeat
   
Delay:
    nop
   
    ldi     ZH,HIGH((clockCyclesPerMilliSecond-8-16)/4)
    ldi     ZL,LOW((clockCyclesPerMilliSecond-8-16)/4)

DelayOuter:
    ldi     YL,LOW(delayMilliseconds)
    ldi     YH,HIGH(delayMilliseconds)
   
    delayloop:
            sbiw    ZL, 1       ; 2 cycles
            brne    delayloop   ; 2 cycles
       
        sbiw    YL,1                                     ; 2 cycles
rjmp delay2 ;;; Two cycle delay
delay2: brne    DelayOuter ; reload and restart inner loop
   
    nop ; added to make a number of cycles divisible by 4 ; 1 cycle
    ret ;                                                   3 cycles

On a broader level:
Using extra nops in your top-level Delay routine (at enter and exit, especially) is silly.  You're talking 125ns out of a human-visible 500ms...
Likewise the double no-op in the outer delay loop.
I would be inclined not to use Y and Z in a delay loop; since they are "important" for other special functions.  There's no good real reason to use double-byte math here
Likewise, and as implied by your comments, I'd be inclined to make the inner loop longer so that the outer loop would be useful with a single-byte counter (1/50th second or something.)  Assuming you don't go to a timer-based approach.
 

Offline dfmischler

  • Frequent Contributor
  • **
  • Posts: 548
  • Country: us
Re: A more efficient blink for AVR processors
« Reply #17 on: March 24, 2014, 12:36:08 pm »
I can't think of any good reason to write a large program in assembler now.
Same reason as in the 80's embedded processors have the same limitations as our old microprocessors.

In 1981 I got a job writing code for a Motorola 6800 system.  I think the hardware design was a bit "recycled".  There was room for up to 8K of EPROM (2716s) and 16K of RAM (2114s).  They could have built the same system with Z80, 8080, or 6502; I don't know if an 8051 would have worked at the time.  All of these had essentially the same trade-offs for implementation language (assembly) and memory size (small).  The 16-bit micros (8086, 68000) were pretty new, and not considered cost competitive for our needs, nor were the tools much better than for the 8-bitters yet.  Today, there are many more choices and smart engineering usually involves picking a micro and tools that allow better productivity and maintainability of the firmware, unless the production quantity is really huge.  And there are getting to be fewer and fewer applications that do not need real networking, etc.

 

Offline GiantGnomeTopic starter

  • Contributor
  • Posts: 25
  • Country: dk
Re: A more efficient blink for AVR processors
« Reply #18 on: March 24, 2014, 08:11:25 pm »
First of all thank you for a good patient post  :)
Without changing the general logic, I see a couple of changes:
1) Uses the "output to PINx" to toggle pins feature.
2) jump to your Y reload instead of including it twice.
3) replace doubled no-ops with two-cycle no-ops like "rjmp ."
Okay, let me see if I understand correctly:
1) As far as I could gather, the PINx is the "Input Pins Address", which I figured to mean that it was for input, not output? So when I do SBI to PINB, it actually toggles HIGH/LOW, rather than just setting HIGH?
2) I gather, that you refer to me reloading Z twice? I know it is rather anal (1 lousy ms), but I wanted to try my hand at cycle-counting, which is more of an academic exercise. But as you said, the precision is not really necessary for this example.
3) Ah, so you can use the rjmp without actually jumping anywhere to get two cycles in one command word. Nice little trick!

Using extra nops in your top-level Delay routine (at enter and exit, especially) is silly.  You're talking 125ns out of a human-visible 500ms...
Likewise the double no-op in the outer delay loop.

Again, yes I know. It does not REALLY matter.

Likewise, and as implied by your comments, I'd be inclined to make the inner loop longer so that the outer loop would be useful with a single-byte counter (1/50th second or something.)  Assuming you don't go to a timer-based approach.

Ah, this was my first idea. I really wanted to use that. But then I could not use the function to actually set an arbitrary number of milliseconds for the delay, right?

As someone pointed out, you're using some RAM for the stack.  It's a good thing you used one of the AVRs that initializes the SP for you.

Okay, this I had a hard time understanding, so I have to read a bit. Is it only when I do subroutines (RCALL / RET) - where RCALL PUSHes the position to the stack and RET POPs it back? So the program as it is now uses 2 byte (1 16bit word) of memory?

So if I should ever encounter a (n AVR) processor, I should stay away from subroutines (or be really clever)?

Again thank you (all of you) for the help.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: A more efficient blink for AVR processors
« Reply #19 on: March 24, 2014, 09:00:03 pm »
- o when I do SBI to PINB, it actually toggles HIGH/LOW, rather than just setting HIGH?-

You could benefit from reading the datasheet - it is all documented there clearly.
================================
https://dannyelectronics.wordpress.com/
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: A more efficient blink for AVR processors
« Reply #20 on: March 24, 2014, 11:19:36 pm »
So while answering about capabilities of different architectures for timing purposes, I pointed out that Intel chips have a Time Stamp Counter that is a very stable clock and you only have to read the value to know how much time has lapsed (provided you know the frequency of your CPU, that you could measure with some external clock that would have to be precise to begin with)

https://www.eevblog.com/forum/beginners/why-is-blinky-not-stable/msg412403/#msg412403

So I did put a link to the Wiki page on the Time Stamp Counter http://en.wikipedia.org/wiki/Time_Stamp_Counter
And noticed that the AVR32 does have a program counter registers.

So looking at the AVR32 Technical Reference Manual
http://www.atmel.com/Images/doc32001.pdf

It referred me to the AVR32 Architecture Document for details
http://www.atmel.com/images/doc32000.pdf

The technical reference manual mentions the configuration register needed to turn on the performance counters and to check if it's present bit 4 has to be 1 on CONFIG0.

In the Architecture Document it states:
Quote
7. Performance counters

7.1 Overview
A set of performance counters let users evaluate the performance of the system. This is useful when scheduling code and performing optimizations. Two configurable event counters are provided in addition to a clock cycle counter. These three counters can be used to collect information about for example cache miss rates, branch prediction hit rate and data hazard stall cycles.

The three counters are implemented as 32-bit registers accessible through the system register interface. They can be configured to issue an interrupt request in case of overflow, allowing a software overflow counter to be implemented.
A performance counter control register is implemented in addition to the three counter registers. This register controls which events to record in the counter, counter overflow interrupt enable and other configuration data.

So, if you do have a performance counter on your chip, you can use one of the oscillators to measure how many ticks your processor can do in 1 second and store that. Or if you trust the processor not to deviate then just use your clockCyclesPerMilliSecond

Feel free to do this in assembly but let me just write a c loop for demonstration

Code: [Select]
// Note: clockCyclesPerMillisecond could be computed using precision oscillators instead of hard coding
// the known CPU frequency.
unsigned long clockCyclesPerMillisecond= 16*1000;
unsigned long ticksPerblink = 1000 * clockCyclesPerMillisecond;
unsigned long begin_time = getPerformanceCounter();
unsigned long current_time = 0L;

while(1) {
    current_time = getPerformanceCounter();
    if ((current_time-begin_time) > ticksPerblink ) {
         // inc by ticksPerblink because any extra ticks that passed will be ignored next loop
        begin_time += ticksPerblink ;
        flipLight();
    }
    // do other stuff here.
}

But note that  in the loop you could do other processes too, this will work well for assembler as well.

As for the first link content, I think I will get myself a Galileo to experiment with the RDTSC instruction on an arduino like board with a pentium on it :)
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: A more efficient blink for AVR processors
« Reply #21 on: March 25, 2014, 12:14:29 am »
Quote
the AVR32 does have a program counter registers.

Would be difficult for a mcu to not have a program counter.
================================
https://dannyelectronics.wordpress.com/
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: A more efficient blink for AVR processors
« Reply #22 on: March 25, 2014, 12:17:50 am »
Quote
the AVR32 does have a program counter registers.

Would be difficult for a mcu to not have a program counter.

That you can access in code?
And by that I don't mean doing a jump, but to be able to read it so you know the cycles the mcu has been ticking

Edit: Arrgh, so I made a typo and say program counter instead of performance counter. sheesh
« Last Edit: March 25, 2014, 12:21:52 am by miguelvp »
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: A more efficient blink for AVR processors
« Reply #23 on: March 25, 2014, 12:19:25 am »
I have a simpler approach:

Code: [Select]
  tmp = systick_get(); //get systick's current value
  do_my_things();
  tmp = systick_get() - tmp; //how much ticks have elapsed

You can implement systick differently on different chips.
================================
https://dannyelectronics.wordpress.com/
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: A more efficient blink for AVR processors
« Reply #24 on: March 25, 2014, 12:39:35 am »
I have a simpler approach:

Code: [Select]
  tmp = systick_get(); //get systick's current value
  do_my_things();
  tmp = systick_get() - tmp; //how much ticks have elapsed

You can implement systick differently on different chips.

Simpler is right, if you want to time the delta for do_my_things() then that's fine.

But that doesn't keep any time at all for controlling the blinky, just a delta won't help the OP much.

 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf