Can you elaborate on the following statement?
Do you want a frequency of 325-Hz or do you want a variable frequency?... output a square wave at 325hz with a duty cycle and frequency that can be defined in the program ...
Happy Holidays. Mike
Can you elaborate on the following statement?
Do you want a frequency of 325-Hz or do you want a variable frequency?... output a square wave at 325hz with a duty cycle and frequency that can be defined in the program ...
Happy Holidays. Mike
I want a frequency of 325Hz but if possible be able to change the frequency by adjusting a value in the code and reprogramming the PIC. It will only output one frequency at a time. If the frequency wishes to be changed then it must be done so by changing the 325Hz value in the code to a desired value - lets say 350Hz - and then reprogramming the PIC.
Thanks for all the help you guys.
RFEFX: I will take a look at what Reynolds Electronics has to offer - thanks
Hello,
Have a look at the HPWM command in the manual. It does what RFEFX suggested, without having to setup the CCP1 registers. The minimum frequency for HPWM, depends on your mcu clock.
Something like this should work, Regards
Duty var Byte
Freq var Byte
Freq = 325
Duty = 127 '50%
Main:
HPWM 1, Duty, Freq 'Output 325hz, 50% duty on pin 5 pic12f683
If X happens then Duty = 0 'Pwm off - pin5 low
If y happens then Duty = 127' Pwm on 50% duty
If Z happens then Duty = 255, Pwm off - pin 5 high
goto Main
Reynolds Electronics was nice in breaking it down but it won't give me a low enough frequency with the lowest value being 3.9kHz with a 4MHz clock - I need at least 325Hz. I don't really want to change the clock frequency since it affects the speed of my main program. I have posted my code below. It turns an LED on for 1 second and then off for one second while continually sending 3.9kH to a pin. Everyone helps is very much appreciated.
'device PIC12F683
DEFINE LOADER_USED 1'Setup for boot-loader programming
OSCCON = %01100101 ' 01100101 - 4MHZ system clock
TRISIO.2 = 0 ' GPIO.2 (GPIO.2 = Output)
PR2 = 254 '(Max Value = 255 Set PWM Period for approximately 3.9KHz
CCPR1L = 127 ' Set PWM Duty-Cycle to 50%
CCP1CON = %00001100 ' Select PWM Mode
T2CON = %00000100 ' Timer2 = ON + 1:1 prescale
TRISIO.1 = 0
LED_HIGH VAR BYTE
LED_LOW VAR BYTE
BEGIN:
FOR LED_HIGH = 0 TO 10 'Turn ON LED for 1 Second
HIGH GPIO.5
PAUSE 100
NEXT
for LED_LOW = 0 to 10 'Turn OFF LED for 1 Second
LOW GPIO.5
PAUSE 100
Next
GOTO BEGIN
Madbass1,
Try this I modified your code.
DEFINE OSC 4
TRISIO =%000000 'All outputs
ANSEL = 0 'ALL I/O digital
CMCON0 = 7 'comparator off
OSCCON =$60 'set internal osc to 4mhz
LED_HIGH VAR BYTE
LED_LOW VAR BYTE
BEGIN:
HPWM 1, 127, 325 'GPIO.2 output 325hz
FOR LED_HIGH = 0 TO 10 'Turn ON LED for 1 Second
HIGH GPIO.5
PAUSE 100
NEXT
for LED_LOW = 0 to 10 'Turn OFF LED for 1 Second
LOW GPIO.5
PAUSE 100
Next
GOTO BEGIN
Last edited by mark_s; - 15th December 2010 at 19:41.
I think I'm just going to settle with changing my OSC value. I managed to complete the code and generate my 350Hz and being able to turn it on and off. Thanks for everyones help. My code is listed below:
'device PIC12F683
OSCCON = %00100101 '250kHZ system clock
CCP1CON = %00001100 'Select PWM Mode
T2CON = %00000100 'Timer2 = ON + 1:1 prescale
PR2 = 177 'Max Value = 255 Set PWM Period for 350Hz
CCPR1L = 150 'Set PWM Duty-Cycle to 85% (177*0.85 = 150)
TRISIO.2 = 0 'GPIO.2 (GPIO.2 = Output)
TRISIO.1 = 0
PIN_VOLTAGE VAR BYTE
INPUT GPIO.1 'Button input
OUTPUT GPIO.4 'Red LED
OUTPUT GPIO.5 'Green LED
BEGIN:
ADCIN 1, PIN_VOLTAGE 'ADCIN - Button Voltage Level
IF PIN_VOLTAGE >= 163 THEN 'Voltage greater then 3.2V
GOTO TURN_OFF_PULSE
ENDIF
IF PIN_VOLTAGE <= 160 THEN 'Voltage less then 3.2V
GOTO TURN_ON_PULSE
ENDIF
TURN_ON_PULSE:
TRISIO.2 = 0 'Turn ouput pulse on - make timer an output
low GPIO.4 'Turn Red LED off
HIGH GPIO.5 'Turn Green LED on
PAUSE 32 'Wait 0.5sec
LOW GPIO.5 'Turn Green LED off
PAUSE 32 'Wait 0.5sec
GOTO BEGIN
TURN_OFF_PULSE:
TRISIO.2 = 1 'Turn output pulse off - make timer an input
HIGH GPIO.4 'Turn on Red LED
goto begin
END
Here are a few ways to do this without using a slower osc.
For a PIC12F1822 using a compare interrupt.
And one for the 12F683 using Timer2/PR2 match interrupt;Code:@ __config _CONFIG1, _FOSC_INTOSC & _MCLRE_OFF & _CLKOUTEN_OFF @ __config _CONFIG2, _PLLEN_OFF & _LVP_OFF DEFINE INTHAND HzOut LED VAR PORTA.0 TRISA = 0 ANSELA = 0 ' All digital CCP1CON = %00001011 ' Compare mode with auto reset of Timer1 CCPR1H = $06 ' Load for match every 1,538uS CCPR1L = $02 ' 1,538uS x 2 = 3.076mS. 1/3.076mS = ~325.09 Hz OSCCON = %01101000 ' 4MHz internal osc T1CON = %00000001 ' Enable Timer1, 1:1 rescale PIR1.2 = 0 ' Clear int flag before enabling interrupt PIE1 = %00000100 ' Enable CCP1 interrupt INTCON = %11000000 ' Global & peripheral ints enabled Main: TOGGLE LED ; Do whatever here. You have ~1,538 instruction PAUSE 1000 ; cycles before each interrupt GOTO Main ASM HzOut ; Eats-up 5 instruction cycles MOVLW B'00000100' ; Load WREG with %00000100 for XOR op below XORWF PORTA,F ; Toggle PORTA,2 on each 1/2 cycle BCF PIR1,CCP1IF ; Clear CCP1 interrupt flag RETFIE ; Go get some more ENDASM END
Interrupts are a LOT faster & easier with newer PIC types with auto context save/restore.Code:@ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _CP_OFF DEFINE INTHAND HzOut wsave VAR BYTE $70 SYSTEM ssave VAR BYTE BANK0 SYSTEM psave VAR BYTE BANK0 SYSTEM LED VAR GPIO.0 TRISIO = 0 ANSEL = 0 ' All digital CMCON0 = 7 OSCCON = %01100000 ' 4MHz internal osc T2CON = %00111100 ' Enable Timer2, 1:1 prescale / 1:8 postscale PIR1.1 = 0 ' Clear TMR2 int flag before enabling interrupt PIE1 = %00000010 ' Enable TMR2 interrupt INTCON = %11000000 ' Global & peripheral ints enabled PR2 = 191 Main: TOGGLE LED ; Do whatever here. PAUSE 1000 ; GOTO Main ASM HzOut movwf wsave ; Save W swapf STATUS,W ; Swap STATUS to W (swap avoids changing STATUS) clrf STATUS ; Clear STATUS movwf ssave ; Save swapped STATUS movf PCLATH,W ; Move PCLATH to W movwf psave ; Save PCLATH MOVLW B'00000100' ; Load WREG with %00000100 for XOR op below XORWF GPIO,F ; Toggle GPIO,2 on each 1/2 cycle BCF PIR1,TMR2IF ; Clear TMR2 interrupt flag movf psave,W ; Retrieve PCLATH value movwf PCLATH ; Restore it to PCLATH swapf ssave,W ; Retrieve the swapped STATUS value (swap to avoid changing STATUS) movwf STATUS ; Restore it to STATUS swapf wsave,F ; Swap the stored W value swapf wsave,W ; Restore it to W (swap to avoid changing STATUS) retfie ; Go get some more ENDASM END
Last edited by Bruce; - 16th December 2010 at 01:40.
Bruce,
In your code for the pic12f683, is there a way I could define a 85% duty cycle for the 325Hz signal?
Not without several modifications, but Darrel has a very handy routine at the link below you should find helpful - along with a brief explanation of how you could alter the above to work. http://www.pbpgroup.com/modules/wfse...hp?articleid=6
Bookmarks