PDA

View Full Version : 18F2620 Comparator Problems



Joe Rocci
- 2nd August 2008, 13:54
I'm trying to set up comparator interrupts on an 18f2620, but I can't even get it to work without interrupts. As soon as the comparator is enabled via the CMCON register, the program seems to off into la-la land. Here is a streamlined code snippet that illustrates the setup:

************************************************** *****************
define LOADER_USED 1
define OSC 8
disable
on interrupt goto Process_Interrupts

'Configure the LCD display
output PORTB
'Set LCD Data Port
Define LCD_DREG PORTB
'Set starting data bit (0 or 4) if 4-bit bus
Define LCD_DBIT 1
'Set LCD register select port
define LCD_RSREG PORTA
'Set LCD register select bit
define LCD_RSBIT 0
'Set LCD enable port
define LCD_EREG PORTA
'Set LCD enable bit
define LCD_EBIT 1
'Set LCD bus size (4 or 8 bits)
define LCD_BITS 4
'Set LCD number of lines
define LCD_Lines 2
'Set LCD command delay time (us)
define LCD_COMMANDUS 2000
'Set LCD data delay time (us)
define LCD_DATUS 50

output porta.4
output portb.5
temp var word
adcon1 = 0

ADCON1 = $FF 'No A/D converter
'Configure the comparators
CMCON.0 = 0
CMCON.1 = 0 '4 inputs, mux'd to 2 comparators
CMCON.2 = 0

lcdout $FE,$1,$2
Pause 500

LCDOUT $FE,$80, "Inited"
LCDOUT
pause 1000

pie1 = 0
pir1=0
enable
'************************************************* *****************************
MainLoop:
lcdout $FE,$80, "Main Loop"
Pause 1000
goto MainLoop
'************************************************* *****************************
Process_Interrupts:
Disable
LCDOUT $FE,$C0,"Interrupt"
Pause 1000
Resume
Enable


end
************************************************** *****************

LCD output is produced at 3 critical points to trace where the program has gotten to:
1) Completion of comparator initialization
2) Main Loop
3) Any interrupt

So long as the CMCON register is in the default state, the program gets past initialization and into the main loop, with no evidence of any interrupts. However if CMCON is set to any operational mode, the program never even makes it to the initialization printout. Again, no interrupt message, just a blank display.

It appears that, when CMCON is configured, the program either crashes or is off doing something that I can't fathom. I bent out all the PIC pins related to the comparator, so I don't think it's a surrounding circuit issue.

Ideas?

Joe

Darrel Taylor
- 2nd August 2008, 16:25
Hi Joe,

You got a few sticky wickets going on here.

'Set starting data bit (0 or 4) if 4-bit bus
Define LCD_DBIT 1
Like the comment says, it has to be either 0 or 4. 1 will not work.
--
'Set LCD register select port
define LCD_RSREG PORTA
'Set LCD register select bit
define LCD_RSBIT 0

RA0 is a comparator input, you can't also use it for the LCD.
--
'Set LCD enable port
define LCD_EREG PORTA
'Set LCD enable bit
define LCD_EBIT 1

Same here, RA1 is a comparator input.
--
output porta.4
output portb.5
temp var word
adcon1 = 0

ADCON1 = $FF 'No A/D converter
'Configure the comparators
CMCON.0 = 0
CMCON.1 = 0 '4 inputs, mux'd to 2 comparators
CMCON.2 = 0

You've set the Comparator output pins to OUTPUT. But then select a comparator mode that doesn't use outputs.
--
lcdout $FE,$1,$2
This clears the LCD then prints Custom Character 2, which hasn't been defined.
--
Process_Interrupts:
Disable
LCDOUT $FE,$C0,"Interrupt"
Pause 1000
Resume
Enable

The Disable should be before the Process_Interrupts label.
And, YOU MUST clear the comparator interrupt flag before resuming.

Joe Rocci
- 2nd August 2008, 19:31
Darrel,

Thanks for the reply.

After I spent the better part of a day trying to figure out what I was doing wrong in software, I finally realized just what you spotted about the LCD drive signals - double duh on my part! I was about to post that I found the problem, but you beat me to the punch.
In my production code however, I had the comparator mux set up so the offending LCD drive signal was deselected (or so I thought), so I'm a bit puzzled about why it affected the comparator. Anyway, moving E and RS to another port fixed it.

The code snippet that I posted was actually a piece of test code I wrote just for this post to illustrate that just turning on the comparator causes the problem. Obviously I rushed and didn't check some of the other things you spotted. In my actual production code, everything is as you suggest it should be, except the LCD "Dbit" specifier. It actually works with a "1" instead of a "4", so I suspect that anything other that a "0" will work similarly - I'll check.

Thanks for being so thorough. Sometimes another set of eyeballs locks right in on a problem that might have eluded one for hours.

Joe

Darrel Taylor
- 4th August 2008, 20:18
In my actual production code, everything is as you suggest it should be, except the LCD "Dbit" specifier. It actually works with a "1" instead of a "4", so I suspect that anything other that a "0" will work similarly - I'll check.

I looked thru the PBP library files, and you're correct.

The way it uses LCD_DBIT is always the same ...
  if ((LCD_DBIT) == 0)

So anything other than 0 will be treated like a 4.

I had thought you were starting the Data bus on PORTB.1, which wouldn't have worked.
My mistake.
<br>

Bruce
- 4th August 2008, 22:53
It may work with 1, and automatically default to bit 4, but I wouldn't rely on this for anything down the road. The correct arguments are 0 or 4. If they make some change to a library file down the road, and you have 1 VS 4, this may screw-the-pooch after an update.

I would opt for the correct arguments as shown in the manual just to be safe. I have seen stuff like this change with compiler updates, and it can end up being a real headache to debug.