PDA

View Full Version : 16f677a to 12f683



ChrisHelvey
- 23rd July 2007, 18:51
Hello all. I'm a newbie and I wrote a small program with PicBasic Pro to test on my MikroElektronica development board (very nice.) It is a simple pulse width/frequency controller running on a 16f877A.
I would like it to run on a 12f683 for a different application (actually all I need is the Pulse width part - the frequency will be set,) but reading over the data sheet for the 12f683 makes me feel like I've been drugged with some kind of horse barbiturate.

I don't get how to set the register properly for this function or to select input pins. Would some nice person out there who knows a bit about the 12f683 take a peek (pun intended) at this and tell me what I need to change to make it function? (It works great on the 16f877A)

Oh yeah, one more thing. I have the ADC set to use the internal clock (because it's the only way I could get it to work,) but am actually using a 20Mhz crystal. Is this OK or should I set the ADC_Clock number to something else? This I also could not decipher from the data sheet. That number seems to change from PIC model to model. How the heck does one figure out what number to use?

Thanks in advance.

Here is the program:

DEFINE ADC_BITS 8
DEFINE ADC_CLOCK 3 'Uses internal RC clock
DEFINE ADC_SAMPLEUS 50 'Microsecond sample time

'Variables
PulseWidth VAR BYTE
Freqtmp VAR BYTE
Frequency VAR Word
TRISA = 255 ' Set PORTA to all input
ADCON1 = 2 ' PORTA is analog

Loop:
'Read Input Variables
ADCIN 2, PulseWidth 'Read channel 2 to variable "PulseWidth" PinA.2
ADCIN 3, Freqtmp 'Read channel 3 to variable "Freqtmp" PinA.3
Frequency = Freqtmp * 100 'Make Freq = 0-25,500hz in 100hz intervals


'Send Pulse
HPWM 1, PulseWidth, Frequency 'Send PWM with variable Duty and Frequency PinC.2 on 16f677A

Pause 500
goto Loop 'Do it forever


Regards,
Chris Helvey
Being a beginner can be so frustrating....

peterdeco1
- 23rd July 2007, 19:23
Hi Chris. I use the PWM on a 12F683. Here is my code. Modify the ports for your code. Output PWM is attached to a FET on gpio.2.

CMCON0 = 7 'comparators off
ANSEL = 0 'all inputs digital
DEFINE OSCCON_1K 1 ' Set OSCCAL for 1K device
@ DEVICE MCLR_ON, INTRC_OSC, WDT_ON, BOD_OFF, PWRT_ON, PROTECT_ON
TRISIO = %00000000 'ALL OUTPUTS
GPIO = %11111011 'ALL HIGH EXCEPT FET ON GPIO.2
Input GPIO.0 'INPUT SWITCH

START:
CCP1CON = 0 'TURN OFF PWM
NAP 0
IF GPIO.0 = 1 Then PULSE
GoTo START

PULSE:
HPwm 1,127,3000
Pause 500
HPwm 1,127,2000
Pause 500

WAITFORRELEASE:
CCP1CON = 0 'TURN OFF PWM
IF GPIO.0 = 1 Then WAITFORRELEASE
GoTo START

ChrisHelvey
- 23rd July 2007, 22:50
Thanks, I see that you are sensing an input (I assume anything around 5V is considered high,) and actually that bit of code may REALLY help me in other parts of my circuit. I see now how sensing a digital input is done. (IF GPIO.0 = 1 Then ...)

However, my current issue is trying to tell the 12f683 that I want to listen to an analog input on two of the pins (duty cycle and frequency) and convert them to a digital number like I did on the previous chip.
I'm just tripped up on how to set this particular register so I can use the pins as I need them:
Pin 1 is VDD
Pins 2 and 3 are for the clock crystal.
Pin 4 is MCLR
Pin 5 is PWM out (according to the datasheet it is default ccp1...I think.)
Pin 6 would be an Analog input for AD conversion for duty cycle
Pin 7 would be an Analog input for AD conversion for frequency
Pin 8 is VSS

I know what I need to do, I just don't understand how to tell it to do it.
Assuming I am reading the datasheet correctly, since the PWM is multiplexed to the outputs, then simply setting one of the ports to an output would give me the desired result. And you have now shown me an example of how to do that - cool (GPIO = %11111011 'ALL HIGH EXCEPT FET ON GPIO.2.)
Now I just need to tell it to listen to GP0 and GP1 (pins 7 and 6) and convert them to digital and I'll be golden.
Is this an ADCON statement?

peterdeco1
- 24th July 2007, 09:28
Hi Chris. I don't think you need to use an ADC input for duty cycle. In MEASUREFREQ below, I used the chip to detect a 3KHZ tone. In the WAITHERE and MEASUREDUTY routine, I used "pause 1" to measure a pulse width up to 255 ms. I don't know what frequencies you're working with but, unless they are really high, you may be able to use something like this.

FREQ VAR BYTE
DUTYCYCLETIMER VAR BYTE
CLEAR 'CLEAR ALL VARIABLES

MEASUREFREQ:
Count GPIO.0, 10, FREQ
IF FREQ > 25 AND FREQ < 35 Then DOSOMETHING 'LOOKING FOR 30 = 3KHZ
GoTo MEASUREFREQ

WAITHERE:
IF GPIO.1 = 0 THEN WAITHERE 'WAIT FOR + PULSE TO MEASURE

MEASUREDUTY:
LET DUTYCYCLETIMER = (DUTYCYCLETIMER + 1)
PAUSE 1
IF GPIO.1 = 0 THEN FINISHED
GOTO MEASUREDUTY

Bruce
- 24th July 2007, 17:34
ANSEL configures A/D pins as digital or analog. CMCON0=7 disables analog
comparators, and TRISIO is the TRIS reg on this one, so,


@ device pic12F683, hs_osc, wdt_off, mclr_off, protect_off

DEFINE OSC 20
DEFINE ADC_BITS 8
DEFINE ADC_CLOCK 3 ' Frc clock
DEFINE ADC_SAMPLEUS 20 ' sample time in uS

'Variables
PulseWidth VAR BYTE
Freqtmp VAR BYTE
Frequency VAR Word
TRISIO = %00111011 ' all inputs except GPIO.2
ANSEL = %00000011 ' GPIO.0, GPIO.1 = analog, rest digital
CMCON0 = 7 ' comparator module disabled

Loop:
'Read Input Variables
ADCIN 0, PulseWidth 'Read analog in on GPIO.0
ADCIN 1, Freqtmp 'Read analog in on GPIO.1
Frequency = Freqtmp * 100 'Make Freq = 0-25,500hz in 100hz intervals

'Send Pulse
HPWM 1, PulseWidth, Frequency 'Send PWM with variable Duty and Frequency PinC.2 on 16f677A

Pause 500
goto Loop 'Do it forever

Note: The minimum frequency with HPWM running at 20MHz is ~1,221hz, so
you might get odd action on CCP1 once the A/D input falls below ~255mV.

ChrisHelvey
- 24th July 2007, 23:15
Thank you, thank you.
This is definitely what I was missing:
TRISIO = %00111011 ' all inputs except GPIO.2
ANSEL = %00000011 ' GPIO.0, GPIO.1 = analog, rest digital
CMCON0 = 7 ' comparator module disabled

So, the % thing simply sets each IO pin on or off explicitly? As in the the eighth position stands for IO0, the seventh for IO1, the sixth for IO2 etc? And since this PIC only has 6 useable IO pins, we only set the last six bits?
Same for ANSEL?

Holy Cow, I think I'm having an Ah Ha moment! And the decimal equivalent is
1 + 2 + 8 + 16 + 32 = 59 ....??? So would it work if the setting was TRISIO = 59 ?

Is it really that simple?

ChrisHelvey
- 24th July 2007, 23:29
How does one come to the conclusion that CMCON = 7?
Am I correct in saying that the reason it is seven is because there are only the last three bits in the CMCON register that sets this? Looking at the data sheet I see:
7 6 5 4 3 2 1 0
19h CMCON0 — COUT — CINV CIS CM2 CM1 CM0

Actually, a better question for me is:
is CMCON a common "register" in all the PICs that have comparators?

Thanks for your time.

Archangel
- 25th July 2007, 06:16
How does one come to the conclusion that CMCON = 7?
Am I correct in saying that the reason it is seven is because there are only the last three bits in the CMCON register that sets this? Looking at the data sheet I see:
7 6 5 4 3 2 1 0
19h CMCON0 — COUT — CINV CIS CM2 CM1 CM0



YEP,
%00000111 = 7 or I believe $07, I'm not real good with hex.


Actually, a better question for me is:
is CMCON a common "register" in all the PICs that have comparators?

Very likely, but I would never accuse all PICs of being the same about anything. The data sheet is your friend :)
JS