PDA

View Full Version : Pic12f683 Cmcon0 = 7



penelopepug
- 11th July 2007, 16:52
Hi! I just purchased some PIC12F683s and am having some problems. The simple program I wrote takes a 0 to 5V analog voltage from a 5k potentiometer and this adjusts HPWM. I have 0.1uF caps in place from VDD to VSS and another on the pot's wiper. At the moment, the HPWM drives an LED. Ultimately it will feed a mosfet that will control a small toy motor.

Compiler - PisBasic Pro 2.47
Using MicroCode Studio
Pic - PIC12F683

I get a syntax error on the line "CMCON0 = 7" which disables the comparators. Yes, I tried "0" and "O" and just "CMCON". As well, I am getting irratic behavoir from the HPWM where as I adjust the pot, the duty cycle jumps around irraticaly. I used an oscilloscope to verify the behavior.

Any advice would be appreicated. The program is below;

INTCON = %10001000 ‘internal oscillator
OSCCON = %01110000 ‘ 8mHz
CMCON0 = 7 'Comparators off
GPIO = %00000000 'outputs low
TRISIO = %00010000 'GP3 as input
ANSEL = %00111000 'AN3 analog

'Define ADCIN parameters
Define ADC_BITS 10 ' Set number of bits in result
Define ADC_CLOCK 3 ' Set clock source (3=rc)
Define ADC_SAMPLEUS 50 ' Set sampling time in uS
Define CCP1_REG GPIO 'PWM Output on gpio
Define CCP1_BIT 2 'Bit 2

‘ Variables
Posit var Word
Speed var byte
Pause 100

Scan:
ADCIN 3, Posit ' Read channel AN3 to Posit
Speed = Posit/4
HPWM 1,Speed,1000
Pause 10
Goto Scan
End

sayzer
- 11th July 2007, 17:45
...and another on the pot's wiper.

Remove the cap.


...I get a syntax error on the line "CMCON0 = 7" which disables the comparators. Yes, I tried "0" and "O" and just "CMCON".
Select the correct PIC model from the drop down menu in MicroCode Studio.


...
INTCON = %10001000 'internal oscillator
OSCCON = %01110000 '8mHz


Add, DEFINE OSC 8.


...
Define CCP1_REG GPIO 'PWM Output on gpio
Define CCP1_BIT 2 'Bit 2


Not sure why you used these?

Archangel
- 11th July 2007, 18:40
Hi! I just purchased some PIC12F683s and am having some problems. The simple program I wrote takes a 0 to 5V analog voltage from a 5k potentiometer and this adjusts HPWM. I have 0.1uF caps in place from VDD to VSS and another on the pot's wiper. At the moment, the HPWM drives an LED. Ultimately it will feed a mosfet that will control a small toy motor.

Compiler - PisBasic Pro 2.47
Using MicroCode Studio
Pic - PIC12F683

I get a syntax error on the line "CMCON0 = 7" which disables the comparators. Yes, I tried "0" and "O" and just "CMCON". As well, I am getting irratic behavoir from the HPWM where as I adjust the pot, the duty cycle jumps around irraticaly. I used an oscilloscope to verify the behavior.

Any advice would be appreicated. The program is below;

INTCON = %10001000 ‘internal oscillator
OSCCON = %01110000 ‘ 8mHz
CMCON0 = 7 'Comparators off
GPIO = %00000000 'outputs low
TRISIO = %00010000 'GP3 as input
ANSEL = %00111000 'AN3 analog

'Define ADCIN parameters
Define ADC_BITS 10 ' Set number of bits in result
Define ADC_CLOCK 3 ' Set clock source (3=rc)
Define ADC_SAMPLEUS 50 ' Set sampling time in uS
Define CCP1_REG GPIO 'PWM Output on gpio
Define CCP1_BIT 2 'Bit 2

‘ Variables
Posit var Word
Speed var byte
Pause 100

Scan:
ADCIN 3, Posit ' Read channel AN3 to Posit
Speed = Posit/4
HPWM 1,Speed,1000
Pause 10
Goto Scan
End
Hello,
Without checking to see if this code works, and without reading for understanding, I did compile as presented below and it compiles. I found 3 things which prevented it from compiling. You used ` instead of ' on some of your comments and you defined
Define CCP1_REG GPIO 'PWM Output on gpio
Define CCP1_BIT 2 'Bit 2
which are already defined in the 12f683.bas file. I just commented them out.
HTH
JS
Oh, BTW, a scratchy pot can do wild things when used here too, and Sayzer will never steer you wrong.


INTCON = %10001000 'internal oscillator
OSCCON = %01110000 ' 8mHz
CMCON0 = 7 'Comparators off
GPIO = %00000000 'outputs low
TRISIO = %00010000 'GP3 as input
ANSEL = %00111000 'AN3 analog

'Define ADCIN parameters
Define ADC_BITS 10 ' Set number of bits in result
Define ADC_CLOCK 3 ' Set clock source (3=rc)
Define ADC_SAMPLEUS 50 ' Set sampling time in uS
'Define CCP1_REG GPIO 'PWM Output on gpio
'Define CCP1_BIT 2 'Bit 2

' Variables
Posit var Word
Speed var byte
Pause 100

Scan:
ADCIN 3, Posit ' Read channel AN3 to Posit
Speed = Posit/4
HPWM 1,Speed,1000
Pause 10
Goto Scan
End

penelopepug
- 11th July 2007, 21:24
Thanks for looking at this for me. I should have realized that the "bas" file sets up the HWPM for me. However I am not sure this is the source of the problem. I did look at the output of the pot and it is perfectly clean with and without the capacitor. It seems to be related to the anolog sampling or calculation (I think). As for the compiling issue, I did select the correct PIC but no matter what I do the CMCON0 shows up as a syntax error for me. I ended up commenting it out and moving the analog over to a differing port so as to not have to worry about the error.

skimask
- 11th July 2007, 22:08
However I am not sure this is the source of the problem. I did look at the output of the pot and it is perfectly clean with and without the capacitor. It seems to be related to the anolog sampling or calculation (I think).

The problem probably stems from the fact that you are most likely updating the duty cycle in the middle of performing a cycle. The datasheets talk about that sort of thing. What happens if you just run the program in a loop that doesn't change the duty cycle?
As far as the A/D output, are you sure the A/D output (the number returned by the ADCIN command) is smooth in the first place? Maybe a 10ms pause isn't enough (not likely), maybe too much. Add in a bit of code to average out the duty cycle itself, software averaging of some sort, move the duty cycle around 'slower'...see what happens.

And as far as CMCON goes, just POKE the value into the appropriate register and see what happens.

penelopepug
- 11th July 2007, 22:52
Thanks skimask. You've given me some things to try. I'll post my findings assuming I resolve the problems. Thanks again.

sayzer
- 12th July 2007, 07:57
....You used ` instead of ' on some of your comments.

penelopepug,

May be you missed what Joe talks about.

Pay attention to these characters;
`
'


as you know, they are not the same characters and will give you syntax errors.

penelopepug
- 12th July 2007, 19:08
penelopepug,

May be you missed what Joe talks about.

Pay attention to these characters;
`
'


as you know, they are not the same characters and will give you syntax errors.

Hi Sayzer. I had retyped that line and copied and pasted it a few times thinking something hidden was the problem. However I'll take a close look at that, hopefully tonight. Thanks again.

StoneColdFuzzy
- 2nd June 2009, 21:47
Hello,
Edited.


INTCON = %10001000 'internal oscillator
OSCCON = %01110000 ' 8mHz
CMCON0 = 7 'Comparators off
GPIO = %00000000 'outputs low
TRISIO = %00010000 'GP4 as input
ANSEL = %00111000 'AN3 analog

'Define ADCIN parameters
Define ADC_BITS 10 ' Set number of bits in result
Define ADC_CLOCK 3 ' Set clock source (3=rc)
Define ADC_SAMPLEUS 50 ' Set sampling time in uS
'Define CCP1_REG GPIO 'PWM Output on gpio
'Define CCP1_BIT 2 'Bit 2

' Variables
Posit var Word
Speed var byte
Pause 100

Scan:
ADCIN 3, Posit ' Read channel AN3 to Posit
Speed = Posit/4
HPWM 1,Speed,1000
Pause 10
Goto Scan
End


OK, I'm still trying to understand this and use code, so I thought that I would revive this thread.

Above, the code has "ANSEL = %00111000 'AN3 analog" To me it looks like AN4 and 5 are also made analog. Is this needed? if it is not needed, I should be able to use:

ANSEL = %00001000 ' AN3 analog

~ Dave

Archangel
- 3rd June 2009, 02:46
OK, I'm still trying to understand this and use code, so I thought that I would revive this thread.

Above, the code has "ANSEL = %00111000 'AN3 analog" To me it looks like AN4 and 5 are also made analog. Is this needed? if it is not needed, I should be able to use:

ANSEL = %00001000 ' AN3 analog

~ DaveFor the 12F683 there is no AN4 and AN5, those bits control the data conversion clock. see the Data sheet page 33.

StoneColdFuzzy
- 3rd June 2009, 14:34
For the 12F683 there is no AN4 and AN5, those bits control the data conversion clock. see the Data sheet page 33.

OK, yes, I see that now. Are they to be set to 1 for this application? Where may I find more information in layman's terms to help me understand what that is?

~ Dave

astouffer
- 3rd June 2009, 15:53
This may help you a bit. I've been playing with the 12F683.


@ __CONFIG _INTOSCIO & _FCMEN_OFF & _IESO_OFF & _BOD_OFF & _BOD_OFF & _CP_OFF & _MCLRE_ON & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF

DEFINE OSC 8 ' Internal 8MHz
DEFINE ADC_BITS 8 ' 8-bit resolution
DEFINE ADC_CLOCK 2 ' Set clock source to Frc/32
DEFINE ADC_SAMPLEUS 50 ' Sample time in uS before A/D conversion is started

CMCON0 = 7 'Comparators off
ADCON0 = %00000001 'ADC enabled and right justified
ANSEL = %00001000 'GPIO.0 and GPIO.1 analog input
INTCON = 0 'INTERRUPTS off
OSCCON = %01110000 '8 Mhz
TRISIO = %111011 'GPIO2 output
GPIO = %00010000 ' All outputs = 0 on boot

StoneColdFuzzy
- 5th June 2009, 20:35
astouffer, thank you.

What's wrong when I can compile multiplication but not division? I get this error "macro div?ctb not found in macro file."

This compiles OK:

width = 510 * mon

This will not compile:

width = 510 / mon

~ Dave

StoneColdFuzzy
- 10th June 2009, 14:35
I've been playing with this code to change HPWM depending on a monitored voltage. The original code at the top of this thread works, but it's erratic.

I've changed things around a bit to fit my needs and it runs a little bit better, but it's still erratic, probably due to refreshing the duty cycle all of the time. I'm looking for suggestions to make this run a little more smooth. Any suggestions?

~ Dave


Mon var Word
Width var byte
Pause 100

Main:
ADCIN 3, mon ' Read channel AN3 to Mon
width = mon*1
if width <= 2 then OneP
if width > 2 then twoP

OneP:
hpwm 1,255,2000
pause 1000
goto main

TwoP:
hpwm 1,32,2000
pause 1000
goto main

end

StoneColdFuzzy
- 11th June 2009, 13:41
I've been playing with this code to change HPWM depending on a monitored voltage. The original code at the top of this thread works, but it's erratic.

I've changed things around a bit to fit my needs and it runs a little bit better, but it's still erratic, probably due to refreshing the duty cycle all of the time. I'm looking for suggestions to make this run a little more smooth. Any suggestions?

~ Dave


Mon var Word
Width var byte
Pause 100

Main:
ADCIN 3, mon ' Read channel AN3 to Mon
width = mon*1
if width <= 2 then OneP
if width > 2 then twoP

OneP:
hpwm 1,255,2000
pause 1000
goto main

TwoP:
hpwm 1,32,2000
pause 1000
goto main

end

Anyone?

~ Dave

Melanie
- 11th June 2009, 17:22
Dave - What is your definition of 'erratic'?

width = mon*1

Oh... Can you tell me what is the point of the *1 part of this line?

Basically your program states that if mon is >2 then your HPWM will be at around 12.5% otherwise it will be solid ON. There's not much else that happens... or at least it would do if you remembered a GOTO MAIN after the last IF statement!!! Because as it is, your code is slamming straight into the OneP section.

You could rewrite your code as...



Main:
ADCIN 3, mon ' Read channel AN3 to Mon
width = mon
if width > 2 then
hpwm 1,32,2000
else
hpwm 1,255,2000
endif
pause 1000
goto main


I'm also assuming you've set TRISIO and such properly.

StoneColdFuzzy
- 11th June 2009, 19:31
Dave - What is your definition of 'erratic'?

width = mon*1

Oh... Can you tell me what is the point of the *1 part of this line?

Basically your program states that if mon is >2 then your HPWM will be at around 12.5% otherwise it will be solid ON. There's not much else that happens... or at least it would do if you remembered a GOTO MAIN after the last IF statement!!! Because as it is, your code is slamming straight into the OneP section.

You could rewrite your code as...



Main:
ADCIN 3, mon ' Read channel AN3 to Mon
width = mon
if width > 2 then
hpwm 1,32,2000
else
hpwm 1,255,2000
endif
pause 1000
goto main


I'm also assuming you've set TRISIO and such properly.

Melanie,

Thank you for replying.

Initially, I couldn't get the code to compile without width=mon*1. I've sice removed the *1 and it compiles OK now. No idea why.

Erratic = while it's executing hpwm 1,255,2000 when "width is less than 2" with either version of code, it cycles randomly back and forth to 1,32,2000. While "width is greater than 2" the output is stable.

I'm going to try a while wend in there.

~ Dave

Here's what I'm using since your reply:


INTCON = %10001000 'internal oscillator
OSCCON = %01110000 ' 8mHz
CMCON0 = 7 'Comparators off
GPIO = %00000000 'outputs low
TRISIO = %00010000 'GP4 as input
ANSEL = %00111000 'AN3 analog

'Define ADCIN parameters
Define ADC_BITS 10 ' Set number of bits in result
Define ADC_CLOCK 3 ' Set clock source (3=rc)
Define ADC_SAMPLEUS 50 ' Set sampling time in uS

' Variables
Mon var Word
Width var byte
Pause 100

Main:
ADCIN 3, mon ' Read channel AN3 to Mon
width = mon
if width > 2 then
hpwm 1,32,2000
else
hpwm 1,255,2000
endif
pause 1000
goto main
end

Melanie
- 11th June 2009, 20:09
OK, the penny's dropped...

mon = 16 bits, whilst width = 8 bits... you can't put a quart into a pint pot...

try...

width = mon/4

In case you're wondering why /4 instead of /8... that's because your ADC reading is 10 bits. So why not read 8-bit ADC to start with?

StoneColdFuzzy
- 11th June 2009, 21:02
OK, the penny's dropped...

mon = 16 bits, whilst width = 8 bits... you can't put a quart into a pint pot...

try...

width = mon/4

In case you're wondering why /4 instead of /8... that's because your ADC reading is 10 bits. So why not read 8-bit ADC to start with?

Because I'm such a noob that I have no idea how to do that. Now I'm really confused.

So with this change, when the IC reads less than 2 volts on "mon" it should execute hpwm 1,255,2000; more than 2 volts and it should execute 1,32,2000?

~ Dave

Melanie
- 11th June 2009, 23:15
Looks like we have a lot to learn here...

No, it WON'T be two volts....

The ADC returns a number between zero and 1023 (because you are in 10-bit mode), where zero equals 0v on the ADC, and 1023 equals full-scale 5v on the ADC. Each click on the ADC scale represents 1/1023 ie a FRACTIONAL part of 5v.

So if 5v = 1023, then 2v will be two fifths of 1023 (namely 409).

So, if you want the trip point to be 2v and with a 10-bit ADC, your code should be...



Main:
ADCIN 3, mon ' Read channel AN3 to Mon
if mon > 409 then
hpwm 1,32,2000
else
hpwm 1,255,2000
endif
pause 1000
goto main

StoneColdFuzzy
- 12th June 2009, 14:26
Looks like we have a lot to learn here...

No, it WON'T be two volts....

The ADC returns a number between zero and 1023 (because you are in 10-bit mode), where zero equals 0v on the ADC, and 1023 equals full-scale 5v on the ADC. Each click on the ADC scale represents 1/1023 ie a FRACTIONAL part of 5v.

So if 5v = 1023, then 2v will be two fifths of 1023 (namely 409).

So, if you want the trip point to be 2v and with a 10-bit ADC, your code should be...



Main:
ADCIN 3, mon ' Read channel AN3 to Mon
if mon > 409 then
hpwm 1,32,2000
else
hpwm 1,255,2000
endif
pause 1000
goto main


Wow, it's no wonder I was frustrated enough to chew the lips off of a carp!

OK, where is it that I look up the ins and outs of 8 bit, 10 bit and such? I'd love to find a PBP book for Dummies or something like it.

Thanks again Melanie!

~ Dave

StoneColdFuzzy
- 12th June 2009, 14:38
OK, the penny's dropped...

mon = 16 bits, whilst width = 8 bits... you can't put a quart into a pint pot...

try...

width = mon/4

In case you're wondering why /4 instead of /8... that's because your ADC reading is 10 bits. So why not read 8-bit ADC to start with?

So, if I would have used Define ADC_BITS 8, I would have been OK?

~ Dave

Melanie
- 12th June 2009, 15:07
Well, in that case with 8 bit ADC, variable mon should be a BYTE rather than a WORD.

Your ADC range for 0-5v is an ADC reading of 0-255 where 255=5v.

So 2 volts will be 2/5ths of 255 namely 102...

So the IF statement then becomes IF mon > 102 THEN...

The decision to use 8-bit or 10-bit ADC is simply a matter of precision, and you chose whether you need steps of 1/255 or 1/1024 for the ADC span that you are using.

StoneColdFuzzy
- 12th June 2009, 16:45
Melanie,

1/255 is fine.

Where can I go to learn the basics of using AD conversions? It's obvious that I have no clue.

Thanks again for the help.

~ Dave

Melanie
- 12th June 2009, 17:51
Posts #20 and #23 of this thread... and you're almost there... it's real simple... add to that the ADCIN section of your PBP Manual and the ADC Section of your chosen PICs Datasheet.

Lesson 1.

Get a PIC with ADC Input capability and enough pins to drive an LCD Display. Hook it up so you can send messages to your LCD. Put a POT (10K or 5K) across your 5v supply with the wiper to the PIC ADC pin. Write a small program to display what the ADC value is when reading 8-bit. Wind the POT up and down a few times to see digits change...

Lesson 2.

Repeat above with 10-bit ADC input.

You're an expert!

StoneColdFuzzy
- 12th June 2009, 18:23
Melanie,

OK, I contacted my supplier rep and he's sampling me some LCD screens and driver ICs. He gasped and said "Wow, you're finally going digital!"

I also went a step further and ordered the book, Programming PIC Microcontrollers with PICBASIC. Something that I should have done a long time ago.

Thanks again!

~ Dave