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

Zany 16F88 problem.
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
theMagni



Joined: 21 May 2004
Posts: 48
Location: Victoria, BC

View user's profile Send private message Visit poster's website

Hardware Specs:
PostPosted: Mon Feb 14, 2005 5:31 pm     Reply with quote

The PIC is powered by a 3.6V lithium cell. It reads 3.53V.

REED is connected to a normally open reed switch. The pullup on the reed switch is 470k Ohm.

AD_IN is the input for the A/D converter. It's connected to COMP_IN and the common line has a 1M Ohm pullup. (There's a very special reason that they are connected in this way.) Draw a lower-case h, put AD_IN on one of the feet, COMP_IN on the other foot, and a 1M on the top of the h, and you'll have a good idea of what I mean.

The pullup resistors and the reed switch are the only things connected to thses pins right now.

AD_IN and COMP_IN are at 3.3 V and will not change; there is nothing on these pins expect the pullup resistors.

REED is at 3.46 when open and 0 V when closed.

Note that I have NOT set CS_GPS to go low during the interrupt. The commented-out line shows that is what I intend later, but I haven't put that part in yet.

Thanks for your help.
_________________
In the 90's, I promised myself I'd never use a so-called "smiley icon". I hate what I've become. ;)
theMagni



Joined: 21 May 2004
Posts: 48
Location: Victoria, BC

View user's profile Send private message Visit poster's website

It gets better...
PostPosted: Mon Feb 14, 2005 6:14 pm     Reply with quote

PCM et al:

Here's something even better:

The bug does not repeat NOT happen in compiler version 3.178. It does happen in version 3.218, and it DOES happen in version 3.191. I don't have any other versions available.

I guess when they were "adding support for the newest devices" they took out the part where they support the 16F88. Confused It looks like a bug in the compiler. Is there somewhere where I should send this to?
_________________
In the 90's, I promised myself I'd never use a so-called "smiley icon". I hate what I've become. ;)
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Feb 14, 2005 6:32 pm     Reply with quote

That's a big help. I'll install vs. 3.178 and compare the listings
for the program you posted.
Humberto



Joined: 08 Sep 2003
Posts: 1215
Location: Buenos Aires, La Reina del Plata

View user's profile Send private message

PostPosted: Mon Feb 14, 2005 9:15 pm     Reply with quote

V3.178 listing
Quote:

.................... SETUP_ADC_PORTS( NO_ANALOGS );
0075: BSF 03.5
0076: CLRF 1F // ADCON0
0077: CLRF 1B // CCPR2L
....................


V3.190 listing
Quote:

.................... SETUP_ADC_PORTS( NO_ANALOGS );
007A: BSF 03.5
007B: MOVF 1F,W
007C: ANDLW C0
007D: MOVWF 1F // ADCON0
007E: CLRF 1B // CCPR2L

....................


V3.178 listing
Quote:
.................... MAGNET_ON = C1OUT;
003A: BCF 03.5
003B: BCF 29.0
003C: BTFSC 1F.6
003D: BSF 29.0
.................... //CS_GPS = FALSE;
.................... }
003E: BCF 0D.6
003F: BCF 0A.3
0040: GOTO 022

Configuration Fuses:
Word 1: 3934 WDT PUT MCLR NOBROWNOUT NOLVP NOCPD WRT NODEBUG CCPB0 NOPROTECT INTRC_IO


V3.190 listing
Quote:
.................... MAGNET_ON = C1OUT;
003A: BCF 03.5
003B: BCF 29.0
003C: BSF 03.5
003D: BTFSS 1C.6
003E: GOTO 042
003F: BCF 03.5
0040: BSF 29.0
0041: BSF 03.5
.................... //CS_GPS = FALSE;
.................... }
0042: BCF 03.5
0043: BCF 0D.6
0044: BCF 0A.3
0045: GOTO 022

Configuration Fuses:
Word 1: 3934 WDT PUT MCLR NOBROWNOUT NOLVP NOCPD WRT NODEBUG CCPB0 NOPROTECT INTRC_IO
Word 2: 3FFF FCMEN IESO
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Feb 14, 2005 9:27 pm     Reply with quote

I looked at the listing for vs. 3.178 and it's got serious problems.
The register address for CMCON is wrong. It's supposed to be 0x9C
for the 16F88, but 3.178 is using 0x1F. That's the CMCON address for
a 16F628.

Also the address of the C1OUT bit is incorrect in vs. 3.178.
This bit is defined in 16F88.H as 0x1F.6, and it should be 0x9C.6.

What's happening with 3.178 is that the power-up state of the
comparators is "off", and because of the incorrect register
addresses, it's left in that condition. You reported earlier that
if the comparators are not setup, then your code works.
So that's why 3.178 appears to work.

I'll continue to look at the problem. I will get a 16F88 in on Wednesday,
so you might not get an answer until later in the week. Of course,
anyone else who wants to help can do so.
theMagni



Joined: 21 May 2004
Posts: 48
Location: Victoria, BC

View user's profile Send private message Visit poster's website

PostPosted: Tue Feb 15, 2005 5:42 pm     Reply with quote

Thanks, PCM.

The GPS engine is not capable of turning that line low. It's really the enable pin on a very precise voltage regulator which in turn powers the GPS engine. The voltage regulator will only shut off if the voltage frops below 2.2V, and that's not what the scope is showing. Based on the differing behaviour with different software versions and comparator configureations, I'm really leaning towards a problem internal to the PIC.

Yes, looking at the schematic, I've got a ferrite bead and the enable pin on a tristate buffer leading from the CS_GPS pin. Unless the ferrite bead is somehow haunted, the CS_GPS turnoff isn't coming from there. Wink

Grr. If only the ICE plugin for the 16F88 wasn't so bloody expensive. I guess it makes more financial sense for me to waste thousands of dollars in labour than it does to buy the $1000 emulator. </irony>
_________________
In the 90's, I promised myself I'd never use a so-called "smiley icon". I hate what I've become. ;)
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Feb 18, 2005 12:48 am     Reply with quote

I received my 16F88 and I was able to duplicate the problem.

It's a RMW problem. When the comparators are configured
in Mode 2, all the input pins (RA0-RA3) are set as analog inputs.
It doesn't matter what state the CIS bit is in, they are still configured
as analog inputs. You can override part of this by setting pin A3
as a digital pin with the ANSEL register. But the input latch for
pin A3 has a logic '0' on it, due to the analog-input configuration
and you can't change it. Because of this, if you read pin A3 you
will always read a logic '0'.

This causes a problem because when you write code like this,
Code:
VHF_MOD = HIGH;

you are doing a RMW on all pins of Port A. The PIC reads all
Port A pins into a temporary register. Then it modifies the
VHF_MOD bit (it sets bit 4 = logic high) in that register. Finally,
it writes the entire register to the Port A output latches.
But because it read a 0 on pin A3, it writes a 0 back to it.
That's why calling the vhf_chirp() function causes CS_GPS to go low.
Both of the lines of code, VHF_MOD = HIGH or VHF_MOD = LOW
do the RMW and will cause CS_GPS to go low.

The solution is to use a shadow register to hold the Port A bit values.
You update the shadow register and then write its contents to Port A.

I stripped your program down to the minimum necessary to show the
problem. In the code below, I have redefined the #bit variables, so
they are in a shadow register, instead of being directly on Port A.
I also declare a shadow register and initialize it to 0. There is also
a macro which I defined, in order to make it easier to update the code.

Every place in your code where you access a bit on Port A, must be
changed to use the new "update_Port_A()" function (macro).

For example, if you have
Code:
VHF_MOD = HIGH;

then you must change it to this:
Code:
update_Port_A(VHF_MOD, HIGH);


You have to do this everywhere you access a Port A pin.
If you miss even one place, it'll do the RMW and set CS_GPS low.

Code:
#include <16F88.H>   
#fuses INTRC_IO,NOWDT,PUT,NOPROTECT,NOBROWNOUT,MCLR,NOLVP,WRT
#use delay( clock=4000000 )
#ignore_warnings 203

#byte PORT_A        = 0x05

int8 Shadow_Port_A = 0;

#bit  REED          = Shadow_Port_A.0 // 470K pullup.
#bit  AD_IN         = Shadow_Port_A.1 // Wired to COMP_IN
#bit  COMP_IN       = Shadow_Port_A.2 //  and has a 1Meg pullup.
#bit  CS_GPS        = Shadow_Port_A.3
#bit  VHF_MOD       = Shadow_Port_A.4
#bit  MCLR          = Shadow_Port_A.5
#bit  MORT          = Shadow_Port_A.6 // pullup
#bit  CS_RTC_READ   = Shadow_Port_A.7

// This macro updates Port A bits via a shadow register.
#define update_Port_A(bit ,value)  bit = value; PORT_A = Shadow_Port_A

#byte OSC_CON     = 0x8F
#byte TRIS_A      = 0x85
#byte COMREF      = 0x9D
#byte ANSEL       = 0x9B

#byte CMCON = 0x9C

//=========================================
void main()
{
  OSC_CON = 0x62;

  setup_comparator( A0_VR_A1_VR );

  //set the voltage reference for about 1/2 way.
  COMREF = 0b10000111;

  TRIS_A = 0b01100111;

  setup_adc_ports(sAN0 | sAN1 | sAN2);
 
  update_Port_A(CS_GPS, 1);
  //CS_GPS = 1;
 
  delay_ms(3000);

 update_Port_A(VHF_MOD, 1);
   //VHF_MOD = 1;      // This line makes CS_GPS go low

  delay_ms(5000);

 update_Port_A(CS_GPS, 1);
 //  CS_GPS = 1;
 
  while(1);
 
}


-----------------------------
I found a few other things in your code:

1. You have several places where you're doing this
Code:
PORT_A = PORT_A;
PORT_B = PORT_B;

I'm not sure what your intention is, but the compiler optimizes that
code away. No assembly language instructions are generated.
You can see this in the .LST file.

2. According to the 16F88 data sheet, in the comparator ISR
you need to read the CMCON register and clear the CMIF bit
before you exit the ISR. The compiler inserts code to clear
the CMIF bit, but it doesn't take care of reading CMCON, so
you need to do that. The isr should be modified as shown
in bold below.

#byte CMCON = 0x9C // Put this above main()

#int_comp
void magnetic_interference()
{
char c;
OSC_CON = 0b01100010;
//The comparator has just been triggered. Set the MAGNET_ON
//to sync with the comparator. The reed switch is on A0, and that
//is comparator one. The pin will go low when the reed switch is
//activated, so the negative rail of the comparator will go below
//the positive rail, making C1 out low.
MAGNET_ON = C1OUT;
//CS_GPS = FALSE; (this was commented out by you)
c = CMCON; // Read the CMCON register before exiting
}

3. In your initialize() function, you have one line like this:
Code:
TRIS_A = 0b00100101;

That's setting pin A1 to an output. But pin A1 is the Vin- pin
for Comparator #1. So I think it should be:
Code:
TRIS_A = 0b00100111;


I did note that CCS is still using the obsolete TRIS instruction in
their built-in function, set_tris_a(), so I think it's a good idea to
set it manually as you're doing. I mean, TRIS may work, but
it's not in the published instruction set in the data sheet, so why
take the chance ? I've told them about this, but they don't
seem to want to change it.
theMagni



Joined: 21 May 2004
Posts: 48
Location: Victoria, BC

View user's profile Send private message Visit poster's website

PostPosted: Fri Feb 18, 2005 11:48 am     Reply with quote

Well, wow.

Where did you learn that? That's certainly a solution I couldn't have come up with. That's just... fantastic. Thank you very much. Can I send you some beer or something?

As for the PORTA = PORTA thing, the intent was to let the external wiring set the logic levels on the pins after I write a value to them. In the interrupts, the intent is to clear the interrupt flag. The manual told me that any write or read of the port clears the flag. Those lines were in the old code that I inherited, and I assumed that that was why they were there. I graduated in June and was hired to sort out and organize all the code here. My assembly is really, really, really poor, so I don't check the LST files. If it doesn't generate code then I'll take the lines out.

The reason I set the A1 pin to an output was because I made a mistake. Thanks for catching that.

All this time I thought you worked for CCS. Huh.
_________________
In the 90's, I promised myself I'd never use a so-called "smiley icon". I hate what I've become. ;)
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 Previous  1, 2
Page 2 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