' PicBasic Pro Program to demonstrate hardware PWM. ' Output is a 1Khz signal with duty cycle sweeping ' from 20% to 80% once per second ' Note: 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=16. (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% loop: 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 loop ' Do it again unless 80% duty cycle duty = 200 ' Reset to 20% duty cycle GoTo loop ' Do it forever