| Author |
Message |
|
|
Posted: Mar 20, 2012 - 11:38 AM |
|

Joined: Oct 04, 2011
Posts: 14
|
|
In my interrupt routine I need to change a bit ISC00 in register EICRA: set it if it was cleared or clear if it was set(to switch falling/rising edge of interrupt). What is the shortest way to do it? Do I really need to write such a piece of code:
Code:
sbrc EICRA, ISC00
sbi EICRA, ISC00
sbrs EICRA, ISC00
cbi EICRA, ISC00
or something like this? Maybe I can use less number of instructions?
In PICs exists a special instruction to do this, but, I think, there is no such instruction in AVR, is it? |
|
|
| |
|
|
|
|
|
Posted: Mar 20, 2012 - 11:41 AM |
|


Joined: Jul 18, 2005
Posts: 62365
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
| Well EOR can toggle bits but to use it you need to RMW and have a register prefilled with the "flip mask" so it's probably no better. |
_________________
|
| |
|
|
|
|
|
Posted: Mar 20, 2012 - 11:59 AM |
|

Joined: Feb 12, 2005
Posts: 16329
Location: Wormshill, England
|
|
|
Code:
in r24,EICRA ;1
eori r24,(1<<ISC00) ;1
out EICRA,r24 ;1
This looks like 3 cycles to me. If your EICRA is out of IN/OUT range, it will only be 5 cycles.
Your SBRC will not work. You have to put the value in a register first. SBIC will work but ends up with more cycles.
David. |
|
|
| |
|
|
|
|
|
Posted: Mar 20, 2012 - 12:02 PM |
|


Joined: Jul 18, 2005
Posts: 62365
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
Nice try David but when did the AVR suddenly spring an EORI instruction? Like I say I can see no alternative to:
Code:
ldi temp, (1<<ISC00) ;1
in r24,EICRA ;1
eor r24, temp ;1
out EICRA,r24 ;1
|
_________________
|
| |
|
|
|
|
|
Posted: Mar 20, 2012 - 01:14 PM |
|


Joined: Feb 19, 2001
Posts: 25923
Location: Wisconsin USA
|
|
|
Quote:
Code:
sbrc EICRA, ISC00
sbi EICRA, ISC00
sbrs EICRA, ISC00
cbi EICRA, ISC00
Note that even if SBIS/SBIC is used and the register is within range, your fragment doesn't work--if it is clear you set it then test for set...and clear it.
There is a recent thread where a similar operation is needed (for ICP edge select). In that code fragment I tested the >>pin state<< as an inference for the edge select. Then I set the entire register to the desired value.
If you don't "know" what all the other bits are, then you read the register and operate on the bit.
As you found, toggling an I/O bit on an AVR8 can be painful. In practice it rarely comes up, and newer AVR models have a toggle feature for the port bits. |
|
|
| |
|
|
|
|
|
Posted: Mar 20, 2012 - 04:15 PM |
|

Joined: Jun 19, 2002
Posts: 957
Location: SF Bay area
|
|
|
Quote:
(to switch falling/rising edge of interrupt)
Doesn't that turn out to be the same as interrupting on ANY change of state (and then checking for low/high of the bit) |
|
|
| |
|
|
|
|
|
Posted: Mar 21, 2012 - 06:08 AM |
|

Joined: Aug 07, 2007
Posts: 1478
Location: Czech
|
|
|
Quote:
sbrc EICRA, ISC00
I think it should be
Quote:
sbic EICRA, ISC00
|
|
|
| |
|
|
|
|
|
Posted: Mar 23, 2012 - 09:44 AM |
|

Joined: Oct 04, 2011
Posts: 14
|
|
I choosed MCU ATmega128, and I need to implement reaction for switching sensor on (rising edge) and off (falling edge). As I can see, it can be done by hardware interrupts only with INT0 - INT7 pins, because datasheet says:
Quote:
"The External Interrupts can be triggered by a falling or rising edge or a low level."
So - I can not use interrupt on change state of pin in this device. And I wrote my program to check values of registers, with no dependency on falling or rising edge.
Then, about code example, given at the beginning. Of course, I realize, it can not work, I wrote it very quickly just to show the idea. Thanks for pointing on my mistakes and for example of eor instruction. I think it will be the most suitable for me - with slight changes:
Code:
ldi temp, (1<<ISC00) ;1
lds r24,EICRA ;1
eor r24, temp ;1
sts EICRA,r24 ;1
|
Last edited by themaster on Mar 23, 2012 - 11:08 AM; edited 1 time in total
|
| |
|
|
|
|
|
Posted: Mar 23, 2012 - 10:10 AM |
|


Joined: Jul 18, 2005
Posts: 62365
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
Quote:
but I need understandable code
How on earth is using SBRC any more or less "understandable" than using EOR ? |
_________________
|
| |
|
|
|
|
|
Posted: Mar 23, 2012 - 10:14 AM |
|

Joined: Feb 12, 2005
Posts: 16329
Location: Wormshill, England
|
|
With the INTn interrupts you can specify, low_level/any/falling/rising edge.
In practice you start with falling edge, then in the ISR() change falling_edge to rising_edge.
The subsequent ISR() changes it back.
This will give you the fastest response.
However you can equally well select any_edge at the start. Then determine which edge in the ISR().
Just get your program logic correct and do not worry about speed or efficiency.
Once it is working correctly you can tidy it up if necessary.
Incidentally, if you go down the 'any' route, you might just as well use PCINT interrupts (if available). You can service several pins at once!
David. |
|
|
| |
|
|
|
|
|
Posted: Mar 23, 2012 - 11:14 AM |
|

Joined: Oct 04, 2011
Posts: 14
|
|
It is just what I decided to do, David. But I think Atmega128 can not react on ANY edge. Datasheet says:
Code:
ISCn1 ISCn0
0 0 Low level
0 1 Reserved
1 0 Falling edge
1 1 Rising edge
No "any edge"!
Or, maybe, I just do not know something? |
|
|
| |
|
|
|
|
|
Posted: Mar 23, 2012 - 11:51 AM |
|

Joined: Feb 12, 2005
Posts: 16329
Location: Wormshill, England
|
|
The mega128 is an 'older' AVR. It does not have PCINT either !
David. |
|
|
| |
|
|
|
|
|
Posted: Mar 23, 2012 - 12:34 PM |
|

Joined: Oct 04, 2011
Posts: 14
|
|
Yes, I just found, that Atmega1280 has PCINT...
By the way, can assembler avr-as write how much memory occupies my firmware? I found linker option for creating map file, but it is quite difficult to realise is my program small enough to place in choosen MCU? Other assemblers (avra, for example) can do it. It is sometimes usable, because cheeper MCU don not have so much flash... |
|
|
| |
|
|
|
|
|
Posted: Mar 23, 2012 - 12:36 PM |
|


Joined: Jul 18, 2005
Posts: 62365
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
|
Quote:
By the way, can assembler avr-as write how much memory occupies my firmware?
avr-size should be run at the end of every build. The firmware size is the sum of .text and .data
(but if you manage to fill a 128K chip with assembler I'll eat my hat!) |
_________________
|
| |
|
|
|
|
|
Posted: Mar 23, 2012 - 12:51 PM |
|

Joined: Oct 04, 2011
Posts: 14
|
|
| Of course, no. But I think to use, for example. 4k chips - and it becomes more actually, isn't it? |
|
|
| |
|
|
|
|
|