|
|
View previous topic :: View next topic |
Author |
Message |
ge bd
Joined: 13 Jul 2013 Posts: 4
|
counting 16-bit data using interrupt & asm code |
Posted: Sat Jul 13, 2013 5:37 am |
|
|
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: 9226 Location: Greensville,Ontario
|
|
Posted: Sat Jul 13, 2013 8:10 am |
|
|
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
|
|
Posted: Sat Jul 13, 2013 10:05 am |
|
|
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
|
|
Posted: Sat Jul 13, 2013 11:32 am |
|
|
Thanks for the suggestions. let me try the things. |
|
|
ge bd
Joined: 13 Jul 2013 Posts: 4
|
|
Posted: Sat Jul 13, 2013 9:13 pm |
|
|
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
|
|
Posted: Sat Jul 13, 2013 10:09 pm |
|
|
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: 19515
|
|
Posted: Sun Jul 14, 2013 12:56 am |
|
|
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
|
|
Posted: Sun Jul 14, 2013 4:30 am |
|
|
Thanks to all of you for the suggestions. Now its working for the present purpose. best wishes. |
|
|
|
|
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
|