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

counting 16-bit data using interrupt & asm code

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



Joined: 13 Jul 2013
Posts: 4

View user's profile Send private message

counting 16-bit data using interrupt & asm code
PostPosted: Sat Jul 13, 2013 5:37 am     Reply with quote

This may be very simple to you. But I cannot do a counting more than 8-bit. I have tried using the following code for PIC16F84A. Can anyone help me in this regard. Thanks in advance.


Code:
long EVENT;

   int save_w;
   #locate save_w=0x4f
   int save_status;
   #locate save_status=0x20

   #byte status = 3
   #bit zero_flag = status.2
   #bit INTF = 0xb.1
   #bit T0IF = 0xb.2

#INT_GLOBAL
void isr()  {
   #asm
   //store current state of processor
   MOVWF save_w
   SWAPF status,W
   BCF   status,5
   BCF   status,6
   MOVWF save_status
   // code for isr
   BCF   T0IF//INTF
   INCF  EVENT,F
   BTFSC zero_flag
   INCF  (&EVENT+1),F

   // restore processor and return from interrupt
   SWAPF save_status,W
   MOVWF status
   SWAPF save_w,F
   SWAPF save_w,W
   #endasm
}

void main()
{
   lcd_init();
   delay_ms(10);
   
   EVENT=0;

   setup_counters(RTCC_INTERNAL,RTCC_DIV_32);
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);
   
   while(TRUE)
   {
         lcd_putc("\fDISPLAY TEST LINE 1");
         
         PRINTF(lcd_putc,"\nADR-%3U ,16B-%5LU",&EVENT+1,EVENT);
         //output_toggle(PIN_A1);//B0
         delay_ms(1000);     
   }
}
temtronic



Joined: 01 Jul 2010
Posts: 9165
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Jul 13, 2013 8:10 am     Reply with quote

comments...
1) get rid of all the assembler, it is NOT needed! CCS C is very powerful, and 99.99999% of all 'basic' programs do not need embedded assembler.

2) look at the examples that CCS supplies in the example folder.One of them is a 'stopwatch' type program...it has information you need.

3)you need to put an 'increment a long variable' in the int_rtcc ISR NOT the int_global ISR. Don't think the latter is possible though I've never tried.

4) please read the FAQ sections of the CCS C Help files(pressing F11 while project is open, opens the Help info). There are examples and information on all you are doing there.

5) your program should be about 10-15 lines long, all in C.

hth
jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Jul 13, 2013 10:05 am     Reply with quote

If you want to study how ASM works in CCS, my suggestion is to make
a C program that does the same thing, and insert a small #asm block
after the C code. Then compile and look at the .LST file and the .SYM
files. Look for differences between the ASM generated by the compiler
(which presumably is correct) and your ASM code. Then if you're wrong,
then try to write ASM code that produces the same result as CCS.

Example of test program to study how to increment an int16 in an isr:
Code:

#include <16F84A.H>
#fuses XT, NOWDT, PUT
#use delay(clock=4M)

int16 event;
#byte status = 3
#bit zero_flag = status.2

#int_rtcc
void rtcc_isr(void)
{
event++;   // This is CCS's code

// This is your proposed code:
#asm
INCF  EVENT,F
BTFSC zero_flag
INCF  (&EVENT+1),F
#endasm
}


//===================================
void main()
{

while(1);
}

temtronic, if the guy wants to learn how to do asm in #int_global then let him. It's an advanced topic, but it's still a legitimate topic.
ge bd



Joined: 13 Jul 2013
Posts: 4

View user's profile Send private message

PostPosted: Sat Jul 13, 2013 11:32 am     Reply with quote

Thanks for the suggestions. let me try the things.
ge bd



Joined: 13 Jul 2013
Posts: 4

View user's profile Send private message

PostPosted: Sat Jul 13, 2013 9:13 pm     Reply with quote

Code:
#int_rtcc
void rtcc_isr(void)
{
event++;   // This is CCS's code

// This is your proposed code:
#asm
INCF  EVENT,F
BTFSC zero_flag
INCF  (&EVENT+1),F
#endasm
}

I tried with the above but found in asm code INCF (&EVENT+),F work on address next to the C code i.e. in C it work on 1B but in asm it works on 1C.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Jul 13, 2013 10:09 pm     Reply with quote

Try this:
Code:

#define BYTE_PTR(x) &(int8 *)(x)
 
#int_rtcc
void rtcc_isr(void)
{
event++;   // This is CCS's code

// This code does the same thing.
#asm
INCF  EVENT,F
BTFSC zero_flag
INCF BYTE_PTR(EVENT) + 1, F
#endasm
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19350

View user's profile Send private message

PostPosted: Sun Jul 14, 2013 12:56 am     Reply with quote

You will find that the handling of offsetting in assembler addressing, is one of the really annoying things, with I'd say almost 'negative documentation' (what there is makes things less clear...).

Historically, using assembler, was at times necessary, and it still is for something like handling the register saving in INT_GLOBAL. However the number of times it is needed has fallen to nearly zero, and the simple increment is much easier coded by just letting C do it. The actual code generated is the same, provided you ensure that the variable is stored in the right memory page.
You need to ensure 'event' is in the low memory page, or either the assembler, or C, will start having to get involved in page switching....

So the 'simplest CCS version' of your interrupt code, is:
Code:

#locate save_w=0x4F
#locate save_status=0x20
int16 event;
#locate event=0x51
#byte status = getenv("SFR:STATUS")

#INT_GLOBAL
void isr()
{
#asm
   //store current state of processor
   MOVWF save_w
   SWAPF status,W
   BCF   status,5
   BCF   status,6
   MOVWF save_status
   // code for isr
#endasm
   event++;
   clear_interrupt(INT_TIMER0);
#asm
   // restore processor and return from interrupt
   SWAPF save_status,W
   MOVWF status
   SWAPF save_w,F
   SWAPF save_w,W
#endasm
}

#locate, generates an int8 variable if one doesn't exist.
Use SFR names, just helps to describe what you are doing.

Unfortunately, use of SFR names, only appeared with V4(ish), and CCS has never updated their examples, so ex_glint.c, show the 'old way'. Also, by default, the compiler wakes using 8bit RAM addressing only (unless *=16 is specified), so they don't bother to ensure the counter is in the bottom page of RAM. A 'caveat'....

It is a case of a rather outdated example.

Best Wishes
ge bd



Joined: 13 Jul 2013
Posts: 4

View user's profile Send private message

PostPosted: Sun Jul 14, 2013 4:30 am     Reply with quote

Thanks to all of you for the suggestions. Now its working for the present purpose. 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