|
|
View previous topic :: View next topic |
Author |
Message |
bilko
Joined: 17 Oct 2003 Posts: 24 Location: Dorset, UK
|
Constant array problem |
Posted: Mon Mar 06, 2006 2:02 pm |
|
|
This works:
Code: | #include <18F4520.h>
#device *=16
#include <18F4520reg.h>
// Fuses: LP,XT,HS,RC,EC,EC_IO,H4,RC_IO,PROTECT,NOPROTECT
// Fuses: BROWNOUT_NOSL,BROWNOUT_SW,NOBROWNOUT,BROWNOUT,WDT1,WDT2,WDT4
// Fuses: WDT8,WDT16,WDT32,WDT64,WDT128,WDT,NOWDT,BORV25,BORV27,BORV42
// Fuses: BORV45,PUT,NOPUT,CPD,NOCPD,NOSTVREN,STVREN,NODEBUG,DEBUG
// Fuses: NOLVP,LVP,WRT,NOWRT,WRTD,NOWRTD,IESO,NOIESO,FCMEN,NOFCMEN
// Fuses: PBADEN,NOPBADEN,CCP2B3,CCP2C1,WRTC,NOWRTC,WRTB,NOWRTB,EBTR
// Fuses: NOEBTR,EBTRB,NOEBTRB,CPB,NOCPB,LPT1OSC,NOLPT1OSC,MCLR,NOMCLR
// Fuses: XINST,NOXINST,INTRC,INTRC_IO,WDT256,WDT512,WDT1024,WDT2048
// Fuses: WDT4096,WDT8192,WDT16384,WDT32768
#fuses H4,PROTECT
#fuses BROWNOUT,WDT,WDT256,BORV27
#fuses PUT,NOCPD,STVREN,NODEBUG //PowerUpTimer EEPROMCodeProtect StackOverflowReset
#fuses LVP,NOWRTD,NOWRTC,NOWRTB //LowVoltProg, DataWrite, CodeWrite, BootBlockWrite
#fuses NOIESO,NOFCMEN //IntExtOscSwitchOver FailSafeOscMon
#fuses NOPBADEN,CCP2C1,EBTR,EBTRB //PBAdEnab CCP2pinSelect TablRdProtect BootRdProtect
#fuses NOCPB,NOLPT1OSC,NOMCLR //BootBlockProtect T1OscEnab MclrEnab
#fuses NOXINST //ExtendInstructSet
//Watchdog period = 4mS typ
#use delay(clock=32000000)
#use rs232(baud=57600, xmit=PIN_C6, rcv=PIN_C7)
#include <limits.h>
#include <stdlib.h>
//#include <stdio.h>
//#include <math.h>
#include "5000.h"
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)
void main()
{
const int8 const NUMV=35;
const int16 const TTABLE[NUMV]={
60955,59516,57740,55597,53074,50178,46947,43442,39751,35974,32214,28571,
25123,21931,19029,16433,14143,12142,10409,8919,7643,6554,5627,4838,4167,
3597,3112,2698,2345,2044,1785,1564,1373,1208,1066};
int ii;
for(ii=0;ii<10;ii++) printf(" %lu\r\n", TTABLE[ii]);
while(1);
}
|
BUT if I use the same code in my application which uses High and low priority interrupts etc etc. When I access the constant array I only get the low byte. IE if ii=0 TTABLE[ii] returns 27.
Suggestions gratefully received
Bill |
|
|
Calamar
Joined: 07 Sep 2003 Posts: 60 Location: Buenos Aires (Argentina)
|
|
Posted: Mon Mar 06, 2006 2:09 pm |
|
|
Colud you post the don't working code ? _________________ Best Regards
Daniel H. Sagarra
La Plata (Argentina) |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Mar 06, 2006 2:33 pm |
|
|
A very common mistake in CCS is to leave off the "L" in the printf
format statement. You've got it done correctly below, but is it done
correctly in all printf statements in the program that you're testing ?
for(ii=0;ii<10;ii++) printf(" %lu\r\n", TTABLE[ii]);
A few other comments:
That line is not needed with 18F devices. It's only relevant for 16F.
Quote: | #fuses LVP,NOWRTD,NOWRTC,NOWRTB |
You're using the LVP fuse. Are you really using a Low Voltage
programmer ? It's fairly rare to do so. If not, change it to NOLVP.
Code protection is not needed during development. Change it to
NOPROTECT.
Quote: | #fuses BROWNOUT,WDT,WDT256,BORV27 |
You have enabled the watchdog timer but you don't have any lines
of code to re-start the watchdog. Your PIC will thus periodically reset.
Quote: | #use rs232(baud=57600, xmit=PIN_C6, rcv=PIN_C7) |
At this baud rate, it's possible that your code might not fetch incoming
characters at a sufficient rate (due to an oversight), and thus the UART
receiver would lock up. Prevent this by adding the ERRORS parameter. |
|
|
bilko
Joined: 17 Oct 2003 Posts: 24 Location: Dorset, UK
|
|
Posted: Tue Mar 07, 2006 4:33 am |
|
|
Thanks to PCM Programmer. I have removed the *=16 and modified the fuse settings as suggested. My comms are interrupt driven so should be no problem at 57600 baud.
This is the code that (still) does not work. Including some printfs for debugging. As I said before TTABLE[ii] returns lower 8 bits only.
This code did work when used on PIC18F452, it does not seem to like PIC18F4520, though I have been through several versions of the PCH compiler since changing chip.
Code: | signed int16 bat_temp()
//Return battery temperature DegC * 10
//Farnell 732-266 -- Betatherm 100K6A3721
//100K at 25C
{
const int8 const NUMV=35;
//Values of output*64 for temperatures -20, -15, -10 ... 150
const int16 const TTABLE[NUMV]={
60955,59516,57740,55597,53074,50178,46947,43442,39751,35974,32214,28571,
25123,21931,19029,16433,14143,12142,10409,8919,7643,6554,5627,4838,4167,
3597,3112,2698,2345,2044,1785,1564,1373,1208,1066};
int8 ii,dd;
int16 ad;
for(ii=0;ii<5;ii++) {
ad=TTABLE[ii];
printf(tx1, " %lu\r\n", ad);
}
ad=ADx(A_BATT);
if (ad>TTABLE[0]) return(-210);
if (ad<=TTABLE[NUMV-1]) return(1510);
dd=NUMV/4;
ii=NUMV/2;
printf(tx1, "%lu: ",ad);
printf(tx1, "%u=%lu ",ii,TTABLE[ii]);
while ( !((ad<=TTABLE[ii]) && (ad>TTABLE[ii+1])) ) {
//printf(tx1, "%u=%lu ",ii,TTABLE[ii]);
if (ad>(int16)TTABLE[ii]) ii-=dd; else ii+=dd;
if (dd>1) dd=dd>>1;
}
return( -200 + 50L*ii +
(50*(signed int32)(TTABLE[ii]-ad))/(TTABLE[ii]-TTABLE[ii+1]) );
}
|
|
|
|
Ttelmah Guest
|
|
Posted: Tue Mar 07, 2006 5:05 am |
|
|
Add ERRORS anyway.
Being 'interrupt driven', does not make it much less likely that there will be missed characters. Indeed if the interrupts get disabled (for instance, if you do a program memory write, or have routines accessed both in the interrupt handler, and in the main code), you are _sure_ to get missed characters...
Best Wishes |
|
|
bilko
Joined: 17 Oct 2003 Posts: 24 Location: Dorset, UK
|
|
Posted: Tue Mar 07, 2006 5:40 am |
|
|
Thanks for the input but I don't have a "#use RS232()" in my application and being an old fashioned type I write all my interrupt handlers in assembly.
Bill |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Mar 07, 2006 12:32 pm |
|
|
Can you post a test program so that I can drop it into MPLAB,
compile it, and run it in the simulator (using UART1 for output)
and see the problem ?
Currently, you're getting data from your ADx() function, which
I assume calls read_adc(), etc.
Can you comment out that line and set "ad" to some sample
data that will show the problem. For example:
Preferably post an entire test program (a short one) that I can
copy and paste right into MPLAB and immediately compile without
having to do any editing or guessing. For example, I had to guess
that tx1() is something like this:
Code: | void tx1(char c)
{
putc(c);
} |
Also post your compiler version. This will be a number such as 3.191
or 3.245, etc., and you can find it at the top of the .LST file, which is
in your project folder. |
|
|
Ttelmah Guest
|
|
Posted: Tue Mar 07, 2006 4:05 pm |
|
|
bilko wrote: |
Thanks for the input but I don't have a "#use RS232()" in my application and being an old fashioned type I write all my interrupt handlers in assembly.
Bill |
Whoa a second. There is an issue relating to accesses to the table read registers, and all the 18 chips, if an interrupt occurs at one point in the instruction sequence. This is 'fixed' by CCS, disabling interrupts round these operations, if they are also used in the interrupt handlers, but if you are doing the handlers in assembler, this fix will not be present. You may actually be creating the problem, by using your own code.
A PCM Programmer says, you need to post a complete program demonstrating the problem.
Best Wishes |
|
|
bilko
Joined: 17 Oct 2003 Posts: 24 Location: Dorset, UK
|
|
Posted: Wed Mar 08, 2006 9:54 am |
|
|
It's not the interrupt.
This works WITHOUT #org line but if it is present the problem manifests itself.
Code: |
#include <18F4520.h>
#fuses H4,PROTECT
#fuses BROWNOUT,NOWDT,WDT256,BORV27
#fuses PUT,NOCPD,STVREN,NODEBUG //PowerUpTimer EEPROMCodeProtect StackOverflowReset
#fuses LVP,NOWRTD,NOWRTC,NOWRTB //LowVoltProg, DataWrite, CodeWrite, BootBlockWrite
#fuses NOIESO,NOFCMEN //IntExtOscSwitchOver FailSafeOscMon
#fuses NOPBADEN,CCP2C1,EBTR,EBTRB //PBAdEnab CCP2pinSelect TablRdProtect BootRdProtect
#fuses NOCPB,NOLPT1OSC,NOMCLR //BootBlockProtect T1OscEnab MclrEnab
#fuses NOXINST //ExtendInstructSet
//Watchdog period = 4mS typ
#use delay(clock=32000000)
#use rs232(baud=57600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#include <limits.h>
#include <stdlib.h>
//#org 0x4000, 0x4FFF
void fff()
{
const int8 const NUMV=35;
const int16 const TTABLE[NUMV]={
60955,59516,57740,55597,53074,50178,46947,43442,39751,35974,32214,28571,
25123,21931,19029,16433,14143,12142,10409,8919,7643,6554,5627,4838,4167,
3597,3112,2698,2345,2044,1785,1564,1373,1208,1066};
int ii;
for(ii=0;ii<10;ii++) printf(" %lu\r\n", TTABLE[ii]);
}
void main()
{
fff();
while(1);
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Mar 08, 2006 1:04 pm |
|
|
What is your compiler version ? |
|
|
Ttelmah Guest
|
|
Posted: Thu Mar 09, 2006 3:23 am |
|
|
I'd agree with the question about 'version'. The code gives OK results for me, on 3.242.
Also shows though the 'move the goalposts' method of some posters. The original question was apparently raising a problem with interrupts,yet the final problem actually looks like it is something like a bank switching issue.
Best Wishes |
|
|
bilko
Joined: 17 Oct 2003 Posts: 24 Location: Dorset, UK
|
|
Posted: Thu Mar 09, 2006 4:12 am |
|
|
Compiler version is PCH 3.245
Sorry if you feel I've moved the goalposts. I did not know where they were when I started this thread!
Bill |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Mar 09, 2006 1:13 pm |
|
|
I don't have your hardware, so I compiled it with PCH 3.245 and ran
it with the MPLAB simulator. I used the "UART1" feature to display the
output in the Output window. It worked OK. This with the #org line
enabled. Here is the result:
Quote: |
60955
59516
57740
55597
53074
50178
46947
43442
39751
35974
|
You said that you're only getting the lower 8 bits. So does that mean you
only see values from 0 to 255 displayed, instead of 16-bit values as
shown above ?
Can you run the program in MPLAB simulator with UART1 output just
as I've done, and tell us what happens ? See this post which explains
how to use UART1:
http://www.ccsinfo.com/forum/viewtopic.php?t=23408&start=1
(The comment about flaky behavior doesn't apply to MPLAB 7.20 and
later).
If you can it make it work in the simulator as I have, but it still fails
on your board, then the problem is likely to be a PIC or board level
hardware issue.
-------------------
One more thing: I noticed you still have the LVP fuse setting.
Are you using a Low Voltage programmer ? Most programmers
are high voltage. This includes Microchip ICD2, the CCS ICD,
PicStart-Plus, Promate, Warp-13a, etc. It's very rare to have a LVP
programmer.
This fuse setting is important because if it's in LVP mode and the
PGM pin goes high, the PIC will go into programming mode. It will
give the appearance of a "random" lockup. So it's essential to use
the NOLVP fuse.
-------------
Also, are you using an ICE ? |
|
|
bilko
Joined: 17 Oct 2003 Posts: 24 Location: Dorset, UK
|
|
Posted: Wed Mar 22, 2006 11:17 am |
|
|
If anyone is still interested I have found the solution.
My code works fine if I set all the EBTRx fuses to NOT protected.
Obvious (sort of) when one RTFM, trouble is the FM is very long!
This brings up another thing in that PCH does not seem to know about the following fuses and their inverse (at least, maybe more):
CP0 CP1 CP2 CP3
WRT0 WRT1 WRT2 WRT3
EBTR0 EBTR1 EBTR2 EBTR3
Bill |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Mar 22, 2006 12:54 pm |
|
|
Quote: |
This brings up another thing in that PCH does not seem to know
about the following fuses and their inverse (at least, maybe more):
CP0 CP1 CP2 CP3
WRT0 WRT1 WRT2 WRT3
EBTR0 EBTR1 EBTR2 EBTR3 |
CCS has a way to do this. In the case where a CCS fuse setting
has sub-fields, you can set the sub-fields by assigning a binary value
to the main fuse setting. See the example shown in bold below.
The EBTR fuse has 4 bits (EBTR0 to EBTR3 in the data sheet), so if
you want to set both EBTR0 and EBTR2 to a value of 1, you can do it
by setting EBTR to 0x05 as shown below.
Quote: |
#include <18F4520.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#fuses EBTR=0x05
#use delay(clock=4000000)
//=========================
void main()
{
while(1);
} |
Here's the fuse list from the .LST file. Notice that the 4-bit wide EBTR
field in Config Word 7 is set to the value specified in the #fuses statement
above.
Quote: |
Configuration Fuses:
Word 1: 0100 XT NOIESO NOFCMEN RESERVED
Word 2: 1E1E BROWNOUT NOWDT BORV25 PUT WDT32768
Word 3: 8300 PBADEN CCP2C1 NOLPT1OSC MCLR RESERVED
Word 4: 0081 STVREN NODEBUG NOLVP NOXINST RESERVED
Word 5: C00F NOPROTECT NOCPD NOCPB
Word 6: E00F NOWRT NOWRTD NOWRTC NOWRTB
Word 7: 4005 NOEBTRB
|
|
|
|
|
|
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
|