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 support@ccsinfo.com

Setting timer 1 with #asm code

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



Joined: 15 Sep 2008
Posts: 8

View user's profile Send private message

Setting timer 1 with #asm code
PostPosted: Sat Oct 11, 2008 3:35 am     Reply with quote

Hi,

I am using a PIC18F6722 with compiler V4.008.

I am trying to use timer 1 to overflow at at half its normal count by preloading it with 0x8000 every time the timer 1 isr is triggered. So as not to introduce count errors i want to just set the msb of TMR1H using an asm instruction. The code is as follows but it does not load the value. Any ideas why the asm instruction does not work?
Code:
#INT_TIMER1
void timer1_isr()
{
      #ASM
         MOVLW  0x80
         MOVWF  0xFCF
      #ENDASM
}


I have also tryed this which also doesn't work
Code:
#INT_TIMER1
void timer1_isr()
{
      #ASM
         BSF  0xFCF, 7
      #ENDASM
}


If I use the CCS built in function set_timer1(32768) it works but it clears the lower 8 bits also which I don't want to happen.[/code]
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Sat Oct 11, 2008 4:46 am     Reply with quote

I suggest to consult the PIC18 manual. You have to disable 16 Bit accesses to read or write TMR1H allone. (RD16 = 0).

By the way, there is no need to use assembler code. You can perform the same operations in C code when defining the respective registers with #byte.

Regards,
Frank
Ttelmah
Guest







PostPosted: Sat Oct 11, 2008 4:58 am     Reply with quote

Generally, it is much easier to just use a bit define.
It is worth doing the define, even for the assembler version (define the timer high register, and use this by name), since then the assembler will automatically handle things like bank switching if needed (not applicable in your case).
Code:

#bit TMRMSB=0xFCF.7

TMRMSB=TRUE;

The reason it doesn't work, is that the timer is in 16bit mode. As such, you can't read/write the high byte on it's own. You need to read the LSB, update the bit in the buffer register, and then write the LSB.
Probably easiest to set it to 8bit mode for the operation. However you then also need to be aware, that updating either timer register, will then car the prescaler, so you will still lose accuracy a little.
So:
Code:

#byte T1CON=0xFCD
#bit RD16=T1CON.7
#bit TMRMSB=0xFCF.7

RD16=FALSE;
TMRMSB=TRUE;
RD16=TRUE;

The alternative, is to read the 16bit value, set the top bit of this, and write it back.

Best Wishes
delphy_boy



Joined: 15 Sep 2008
Posts: 8

View user's profile Send private message

PostPosted: Sat Oct 11, 2008 6:16 am     Reply with quote

Thanks guys, i will give this a go.

Much appreciated
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sat Oct 11, 2008 1:32 pm     Reply with quote

Compiler version 4.008 is bad and should never have been released. Save everybody a lot of time and revert to v3.249 or upgrade to a newer version (the v4 compiler started to work for the old features around the mid v4.03x versions). See the sticky 'V4 comments' thread for more info.

Why not use the C function setup_timer_1? I don't see why assembler would be preferred over this function. Am I missing something?

A much larger problem are the:
- non-constant delays introduced by other interrupts being active at the same time.
- The 40-something instruction time delay before the interrupt function is entered.
To work around these problems you could read the timer1 and add your desired offset:
Code:
setup_timer_1( 0x8000 + get_timer1() );
Ttelmah
Guest







PostPosted: Mon Oct 13, 2008 3:03 am     Reply with quote

The 'idea' of just setting the top bit, is quite sensible, and potentially requires only one instruction, rather than having to read/modify/write the whole 16bit value, and involve quite a lot of instructions.
However the hardware in part 'intervenes', so in 8 bit mode, updating the top register, will still reset the counter prescaler, and the compiler by default uses the registers in 16bit mode, requiring the extra overhead of changing modes as well.
I must admit, if I was wanting the 'best' performance, I'd probably switch the counter to 8bit mode permanently, and not use the internal timer functions at all, once the clock was running.
Agree wholeheartedy with the comments about 4.008. The odds of getting any program to actually work 'right' with this, are low...

Best Wishes
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