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

Constant array problem
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
bilko



Joined: 17 Oct 2003
Posts: 24
Location: Dorset, UK

View user's profile Send private message

Constant array problem
PostPosted: Mon Mar 06, 2006 2:02 pm     Reply with quote

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)

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Mon Mar 06, 2006 2:09 pm     Reply with quote

Colud you post the don't working code ?
_________________
Best Regards
Daniel H. Sagarra
La Plata (Argentina)
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Mar 06, 2006 2:33 pm     Reply with quote

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:

Quote:
#device *=16

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.


Quote:
#fuses H4,PROTECT

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

View user's profile Send private message

PostPosted: Tue Mar 07, 2006 4:33 am     Reply with quote

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







PostPosted: Tue Mar 07, 2006 5:05 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Mar 07, 2006 5:40 am     Reply with quote

Quote:
Add ERRORS anyway


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

View user's profile Send private message

PostPosted: Tue Mar 07, 2006 12:32 pm     Reply with quote

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:
Code:
ad = 0x55;


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







PostPosted: Tue Mar 07, 2006 4:05 pm     Reply with quote

bilko wrote:
Quote:
Add ERRORS anyway


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

View user's profile Send private message

PostPosted: Wed Mar 08, 2006 9:54 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Mar 08, 2006 1:04 pm     Reply with quote

What is your compiler version ?
Ttelmah
Guest







PostPosted: Thu Mar 09, 2006 3:23 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Mar 09, 2006 4:12 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Mar 09, 2006 1:13 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Mar 22, 2006 11:17 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Mar 22, 2006 12:54 pm     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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