CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Reading 16bit registers on 8bit mcu

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Pret



Joined: 18 Jul 2006
Posts: 92
Location: Iasi, Romania

View user's profile Send private message

Reading 16bit registers on 8bit mcu
PostPosted: Thu Mar 14, 2013 5:15 pm     Reply with quote

I was curious on how can you read an 16bit timer (while it runs), store it in a 16bit variable and having consistent high and low byte. As I read into a random datasheet (say 18F26k22), I've seen that they made a trick with a hidden buffer on the high byte of the 16bit timer register. That's neat and it works fine.

But what if I'm using CCP on capture mode, being set on falling edge, without any interrupts. Just want to know how much time occurred since last falling edge. But reading the CCP register (say CCP_2) and store it in a local var, exposes the same issue.

For instance:
Code:
int16 capt = CCP_2;

Now, how can I know for sure if high and low byte of the capt are consistent? What if a new capture occurred just between reading the low and reading the high?

A solution that I'm thinking is:
Code:
int16 capt = CCP_2;
while(CCP_2 != capt) capt = CCP_2;

... meaning that I'm reading it in loop as long the values are not equal.

Is there any "right" way to do this?
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Thu Mar 14, 2013 6:21 pm     Reply with quote

you just did it the right way as far as i'm concerned

with or without INTS on - this will never fail

IMHO the optimum solution as you never have to kill global or an individual INTs

i regard killing global ints as a serious crime ,
when more than one actual, individual int is enabled.

Very Happy Very Happy Very Happy Very Happy
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Thu Mar 14, 2013 6:49 pm     Reply with quote

Could you consider this?

When a capture occurs, an int flag is set.
Clear the int flag before reading the timer.
If the int flag is set after reading the timer, another capture has occured.
You don't have to be actually using the int routines to use of the flags.

Mike
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Fri Mar 15, 2013 2:15 am     Reply with quote

Killing GLOBAL INTs, is perfectly acceptable, for reading a 16bit value updated in an interrupt. Remember it is only for a couple of instructions.
Microchip in their own examples and application notes use both methods for accessing values updated inside interrupts.

However it is not the way to handle this, since in this case it a hardware value, which will still update when interrupts are disabled. The read and test, _is_ the only way to go. Depending on the circumstances, you might want to do the update the other way round, so:
Code:

unsigned int16 capt;

do
   capt = CCP_2;
while (capt!=CCP_2);


Both will give exactly the same results. The most efficient of all, will actually be:
Code:

int16 capt;

while(CCP_2 != capt)
   capt = CCP_2;


There is no 'point' in reading the value again, if it does already match...

Best Wishes
Pret



Joined: 18 Jul 2006
Posts: 92
Location: Iasi, Romania

View user's profile Send private message

PostPosted: Fri Mar 15, 2013 4:32 am     Reply with quote

Yes, in this case it has nothing to do with interrupts.

Ttelmah, in your last example, it will definitely will create heart attacks on Lint or a second viewer for that uninitiated value, even it makes sense not to initialize it.

Though, I think your last example is not fully proof. You have to read it twice. For instance, if your random value for capt matches with a single read of a faulty (inconsistent) read of CCP_2? It's possible, right? Basically you might simply guess the wrong value of CCP_2.
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Fri Mar 15, 2013 4:38 am     Reply with quote

That's why I slightly prefer the first way.
It does depend on circumstances. In a loop that reads the value, the second is the more efficient, and since the value then should never be uninitialised, it avoids the extra read if it hasn't changed.

Best Wishes
Pret



Joined: 18 Jul 2006
Posts: 92
Location: Iasi, Romania

View user's profile Send private message

PostPosted: Fri Mar 15, 2013 4:48 am     Reply with quote

Yes, but I still believe your very last version is not fully proof. Because with your uninitialized value you can simply guess a faulty read of CCP_2, and it moves on as the right value...
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Fri Mar 15, 2013 5:09 am     Reply with quote

Pret wrote:
Yes, but I still believe your very last version is not fully proof. Because with your uninitialized value you can simply guess a faulty read of CCP_2, and it moves on as the right value...

Am I missing something?

As I see it the first falling edge, initialises the system.
Any read of the CCP_x before the first falling edge has to be meaningless.
The coding must take this into account.

Mike

EDIT Have you considered using the CCP_x interrupt flag, or is it a non-starter?
Pret



Joined: 18 Jul 2006
Posts: 92
Location: Iasi, Romania

View user's profile Send private message

PostPosted: Fri Mar 15, 2013 5:52 am     Reply with quote

We are not worrying about the meaning of CCP_x in application, we are worrying about the read of the 16bit register in a consistent manner, regarding its low and high byte. Using the interrupt flag seems to be a solution as well, but I find reading the register twice a more elegant manner.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group