Pin connections PIC 16F628.

Controlling PIC Pulse Width Modulation with a Serial ADC

by Lewis Loflin


YouTube video: Calculating Pulse-Width Modulation with a PIC

In Interface Example PIC16F628 Reading TLC548 Serial ADC we read the 8-bit value from a TLC548 serial ADC and wrote that value to 8 LEDs on PORTB. Here we will use those values to control the duty cycle on the pulse-width-modulation module on RB3.

Here we will look at the PWM control on the PIC16F683. For how to calculate frequency and duty cycle for PIC PWM see Pulse-Width Modulation and the PIC Micro-controller

The PWM output is pin 9 which is PORTB RB3 must be programmed as an OUTPUT. In fact changing the bit value in TRISB bit 3 to an input (HIGH) will turn off the PWM output - this can be done by the program itself after setup.

The complete program is at TLC548_PWM.asm. The following code snippets are from that.

PWM Period = [(PR2) + 1] * 4 * TOSC * 
(TMR2 Prescale Value)

PWM duty cycle = (DCxB9:DCxB0 bits value) * Tosc * 
(TMR2 prescale value)

Tosc = 16 mHz
PR2 = 255 ; Freq. ~1000Hz & PWM period .001 Sec.
PWM output PORTB, 3 

First I'm using a clock frequency of 16 mHz. PR2 is a register located at 92H in bank 1. I'm using a TMR2 prescale of 16. This is a 10-bit PWM values with the two lowest bits set to 0s. So only the upper 8-bits are used due to the TLC548 being a 8-bit device.

 From setup: 
 	banksel PIE1 
 	; jump to BANK1    
	clrf	PIE1 
	; part of TMR2 setup
	movlw	d'255' 
	; frequency = 1000 Hz
	movwf	PR2
	banksel T2CON 
	; back to BANK0 
 	movlw	b'00000111'
	movwf	T2CON 
	; turn on TMR2 prescale 16
	movlw	d'0' 
	; duty cycle = 0%
	movwf	CCPR1L
	movlw	b'00001100'
	; PWM B0 and B1 LOW Bits 5,6
	movwf	CCP1CON 	
	; turn on PWM 

Above is the partial setup code for using the PWM module. See pages 66-67 in the spec sheet.

	call delay_100ms
	call get_adc 
	; value returned in val
	movfw val
	movwf CCPR1L 
	; output pwm duty cycle RB3
goto main

Above is the main loop that delays 100 mSec, reads the ADC value, writes the values to CCPR1L register in BANK0.

See How I got into Electronics