PicBasic Pro program to demonstrate hardware PWM. Output is a 1KHz signal with duty cycle sweeping from 20% to 80% once per second. PWM output will be on the CCP1 pin. Register names are for the PIC16F87x devices.
' Name : HARDPWM.pbp ' Compiler : PICBASIC PRO Compiler 2.6 ' Assembler : PM or MPASM ' Target PIC : 12F, 16F, 18F ' Hardware : Non specific ' Oscillator : 4MHz internal or external ' Keywords : HARDWARE PWM ' Description : PICBASIC PRO program to demonstrate hardware PWM. ' Output is a 1Khz signal with duty cycle sweeping from 20% to 80% once per second. ' PWM output will be on the CCP1 pin. Register names are for the PIC16F87x devices. ' ' PR2 = Timer2 period register, controls PWM period. ' CCPR1L and CCP1CON<5:4>bits control the duty cycle, ' and should be treated as a 10-bit word. ' Fosc = Clock Frequency (4MHz) ' PS = Timer2 Prescale Value (T2CON<1:0>) ' Freq = PWM output frequency ' Duty% = Duty cycle (20% = 0.2) ' formulas: ' PR2=(Fosc/(4*PS*Freq))-1 ' CCPR1L:CCP1CON<5:4>=(PR2+1)*4*Duty% duty VAR WORD ' Duty cycle value (CCPR1L:CCP1CON<5:4>) TRISC.2 = 0 ' Set PORTC.2 (CCP1) to output CCP1CON = %00001100 ' Set CCP1 to PWM T2CON = %00000101 ' Turn on Timer2, Prescale=4 ' Use formula to determine PR2 value for a 1KHz signal, ' 4MHz clock, and prescale=4. (4E6/(4*4*1E3))-1=249 PR2 = 249 ' Set PR2 to get 1KHz out ' Use formula to determine CCPR1L:CCP1CON<5:4> value for ' ends of range 20% to 80%. (249+1)*4*0.2=200 (20% value) ' (249+1)*4*0.8=800 (80% value) duty = 200 ' Set duty cycle to 20% mainloop: CCP1CON.4 = duty.0 ' Store duty to registers as CCP1CON.5 = duty.1 ' a 10-bit word CCPR1L = DUTY >> 2 duty = duty + 10 ' Increase duty cycle ' Since the total sweep of duty is 600 (800-200) and ' we are adding 10 for each loop, that results in 60 ' steps min to max. 1 second divided by 60 = 16.67mS Pause 17 ' Pause 1/60 of second IF (duty < 800) Then mainloop ' Do it again unless 80% duty cycle duty = 200 ' Reset to 20% duty cycle GoTo mainloop ' Do it forever End