|
|
View previous topic :: View next topic |
Author |
Message |
achilles03
Joined: 23 Apr 2010 Posts: 7 Location: Huntsville, AL
|
Problems with code written in version 2? (v4 vs. v2) |
Posted: Mon May 03, 2010 12:19 pm |
|
|
I've run across a program originally written for version 2 of the CCS compiler. It's almost exactly what I want, only I would like to make a few minor changes.
When I compile the original program with the v4 compiler, it compiles without errors, and the program begins executing on a 16F628A, but freezes when it gets to a subroutine that relies heavily on interrupts. The original HEX file generated with the v2 compiler does not freeze and operates normally.
Any suggestions as to what might be causing this problem?
Thanks in advance!
Dave |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon May 03, 2010 12:23 pm |
|
|
Quote: |
I've run across a program originally written for version 2 of the CCS compiler.
|
Post a link to the program if possible. |
|
|
achilles03
Joined: 23 Apr 2010 Posts: 7 Location: Huntsville, AL
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon May 03, 2010 1:48 pm |
|
|
This code is very primitive stuff, left from the early days of CCS I guess.
At a minimum, you can get rid of his interrupt routine wrapper, including
getting rid of the #org, and substitute a standard CCS interrupt wrapper.
You'll notice I've removed his code that attempts to save and restore
the state of the machine, and I've let CCS do it. That's the best way.
The rest of his ASM code could be converted to standard C, but I don't
want to volunteer to do that.
Code: |
#int_timer0
void tone()
{
#asm
movf base,w //2.0us Lets reset the timer first
decfsz dink,f //2.4us Do we need to extend the loop time?
goto nodink //2.8us
addlw 0xff //3.2us Yes ... W = W + (-1)
movwf timr0 //3.6us At the end of this instruction
// timer0 is one less than the value
// of timr0 at the end of the 3.6us
// instruction below.
movf r_val,w //4.0us Now lets update the sine wave
call getsin //4.4us Get wave profile from table
movwf portb //6.4us portb is updated at 6.4us in both places
movf base_dink,w //6.8us we need to restore (reinit) dink
movwf dink //7.2us
goto incloop //7.6us
nodink: movwf timr0 //3.6us No loop time dink needed
movf r_val,w //4.0us Now lets update the sine wave
call getsin //4.4us
movwf portb //6.4us
// We now have two running times.
// The first value to the right of the instruction indicates when that
// instruction starts if no loop dink was needed.
//
// The second value indicates when that instruction starts if a loop dink
// was required.
//
// However, since the timer and sine wave were updated at the same time
// regardless of which path we take (3.6us and 6.4us), the diverging times
// here will not effect the sine wave frequency. We only need to keep
// track of the time to be sure we get out of the interrupt before the
// next loop is due to begin (i.e. timr0 rolls to 0xff), and so we can
// calculate processor load (see below).
//
incloop:
incf r_val,w //8.4-6.8 set pointer to next sine wave value
andlw 0x1f //8.8-7.2 0,1,2,...,31,0,1,...
movwf r_val //9.2-7.6
incf loop_ctr,f //9.6-8.0 Inc loop_ctr -- used to time bit length
goto done
getsin:
addwf 02,f
// r-val volts
retlw 7 // 0 2.33
retlw 6 // 1 2
retlw 5 // 2 1.67
retlw 4 // 3 1.33
retlw 3 // 4 1
retlw 2 // 5 .67
retlw 1 // 6 .33
retlw 1 // 7 .33
retlw 1 // 8 .33
retlw 1 // 9 .33
retlw 2 // 10 .67
retlw 3 // 11 1
retlw 4 // 12 1.33
retlw 5 // 13 1.67
retlw 6 // 14 2
retlw 7 // 15 2.33
retlw 9 // 16 3
retlw 10 // 17 3.33
retlw 11 // 18 3.67
retlw 12 // 19 4
retlw 13 // 20 4.33
retlw 14 // 21 4.67
retlw 15 // 22 5
retlw 15 // 23 5
retlw 15 // 24 5
retlw 15 // 25 5
retlw 14 // 26 4.67
retlw 13 // 27 4.33
retlw 13 // 28 4.33
retlw 11 // 29 3.67
retlw 10 // 30 3.33
retlw 9 // 31 3
done:
nop
#endasm
}
|
I don't know if this will be enough to make it work, because there is still
a lot of weird stuff throughout his code, where he sets Bank Select
registers with #asm code. |
|
|
achilles03
Joined: 23 Apr 2010 Posts: 7 Location: Huntsville, AL
|
|
Posted: Mon May 03, 2010 8:36 pm |
|
|
Hm, thanks for the suggestion. That didn't seem to work... it still hanging right before it transmits.
As a quick overview, the program is a packet radio transmitter (AX.25), which uses an interrupt routine to generate a sine wave using a network of resistors connected to output pins. The sine wave varies from 1200Hz to 2200Hz depending on the bit being transmitted. The interrupt routine goes through adjusts the output on 4 or 5 pins to form the wave at the desired frequency (1200 or 2200).
Any other suggestions given the background of the program?
Thanks in advance!
Dave |
|
|
achilles03
Joined: 23 Apr 2010 Posts: 7 Location: Huntsville, AL
|
|
Posted: Mon May 03, 2010 9:35 pm |
|
|
Scratch my last post. The program now makes it further! ...but still hangs, only after generating a tone.
I only changed the "#ORG 0x04, 0x45" to "#int_timer0". When it starts to transmit, it now starts to generate an audio tone, but stays stuck in the tone. Test tones generate two distinct tones, but it sounds like they aren't the intended 1200 and 2200 Hz... they sound lower than the intended tones.
So now it generates tones (it didn't before), but stays stuck... does this give you any ideas what the new hang-up might be?
Thanks in advance!
Dave |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue May 04, 2010 1:11 pm |
|
|
Quote: | I only changed the "#ORG 0x04, 0x45" to "#int_timer0". |
But that's not what I suggested. I gave you a complete routine to
substitute for their interrupt routine.
By only adding the #int_timer0 line, you are telling the compiler to use
the entry portion of the CCS interrupt handler. You left the rest of
original code unchanged. This means the original code will exit the
interrupt by executing it's own RETFIE line, instead of going through the
exit portion of the CCS interrupt handler.
This means that the all the "machine state" registers that CCS saves
in the entry portion of the interrupt handler are NOT restored upon exit.
I'm surprised it works at all.
I don't guarantee that the routine that I posted will work or that it will fix
all your problems, but I think it will work a lot better than just tacking
#int_timer0 on to the front of their routine. |
|
|
achilles03
Joined: 23 Apr 2010 Posts: 7 Location: Huntsville, AL
|
|
Posted: Tue May 04, 2010 3:11 pm |
|
|
PCM programmer wrote: | Quote: | I only changed the "#ORG 0x04, 0x45" to "#int_timer0". |
But that's not what I suggested. I gave you a complete routine to
substitute for their interrupt routine.
By only adding the #int_timer0 line, you are telling the compiler to use
the entry portion of the CCS interrupt handler. You left the rest of
original code unchanged. This means the original code will exit the
interrupt by executing it's own RETFIE line, instead of going through the
exit portion of the CCS interrupt handler.
This means that the all the "machine state" registers that CCS saves
in the entry portion of the interrupt handler are NOT restored upon exit.
I'm surprised it works at all.
I don't guarantee that the routine that I posted will work or that it will fix
all your problems, but I think it will work a lot better than just tacking
#int_timer0 on to the front of their routine. |
When I substitute the whole routine, it generates ~1020Hz tone, but continues generating the tone without transmitting any data. That's certainly better than before (it didn't even generate a tone). But it stays stuck in the tone generation. When I try test tones in the configuration mode (1200 and 2200 Hz), I get 1020Hz for both...
Does that give any clues to what's causing the "second" hangup?
Thanks again for the help! I really appreciate it!
Dave |
|
|
|
|
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
|