0% found this document useful (0 votes)
25 views16 pages

Experiment No 4

The document outlines the design and implementation of a sine PWM half-bridge inverter using the PIC16F877A microcontroller, targeting a 50Hz output frequency and a 20kHz switching frequency. It details the configuration of various registers, PWM operation, and the generation of a duty cycle matrix for PWM output. Additionally, it includes a C program for generating the PWM duty ratios and the main program for controlling the inverter operation.

Uploaded by

amala081998
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
25 views16 pages

Experiment No 4

The document outlines the design and implementation of a sine PWM half-bridge inverter using the PIC16F877A microcontroller, targeting a 50Hz output frequency and a 20kHz switching frequency. It details the configuration of various registers, PWM operation, and the generation of a duty cycle matrix for PWM output. Additionally, it includes a C program for generating the PWM duty ratios and the main program for controlling the inverter operation.

Uploaded by

amala081998
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 16

Experiment No : 4

SINE PWM GENERATION USING PIC16F877A


MICROCONTROLLER AND SIMULATION OF
HALF BRIDGE INVERTER

AIM
Design and set up a microcontroller based 50Hz sine PWM half-bridge inverter to power a resistive load of
33 ohm. The switching frequency is to be 20kHz. The DC supply voltage is 200V. Also design a low pass
LC filter with a corner frequency of 1kHz to filter the harmonics, ensuring that the voltage drop across the
inductor does not exceed 10% of the inverter output voltage. Plot relevant waveforms.

SOFTWARE USED

Proteus 8 , MPLAB XC8 Compile

DESIGN

Crystal Frequency = 16MHz

PWM Frequency = 20kHz

PWM Period = (PR2 + 1)×4×Tosc×TMR2 prescale value

where; TMR2 prescale value= 1, 4, 16

Let’s take TMR2 prescale value= 1


1
1 = (PR2 +1) 4× 6 ×1
20×1000 16×10

By solving PR2= 199

Hence take TMR2 prescale value=1

Bit2 is set to be 1 to turn on the TIMER2 and bit 1-0 will determine the prescale value.
We need a prescale value as 1. Hence bit1-0 =00
T2CONbits. TMR2ON=1;

T2CONbits. T2CKPSX=00;

We don’t need capture and compare module. We need the PWM module only.

Hence bit3-0 of the CCP1CON will be11xx.

CCPxX, CCPxY are bits used to get 10 bit resolution. But here we use only 8 bit resolution. Hence these
2 bits (bit5-4) will be 0.
CCP1CONbits. CCP1X=0;

CCP1CONbits. CCP1Y=0;

CCP1CONbits. CCP1M=0b1111;

1.T2CON: TIMER 2 CONTROL REGISTER

ADDRESS 12h

bit 7- Unimplemented: Read as ‘0’

bit 6-3 TOUTPS3:TOUTPS0: Timer2 Output Postscale Select bits 0000 = 1:1 postscale
0001 = 1:2 postscale
0010 = 1:3 postscale


1111 = 1:16 postscale

bit 2 TMR2ON: Timer2 On bit

1 = Timer2 is on

0 = Timer2 is off

bit 1-0 T2CKPS1:T2CKPS0: Timer2 Clock Prescale Select bits 00 =

Prescaler is 1

01 = Prescaler is 4

1x = Prescaler is 16

2. CCP1CON REGISTER/CCP2CON REGISTER

ADDRESS 17h/1Dh

bit 7-6 Unimplemented: Read as ‘0’

bit 5-4 CCPxX:CCPxY: PWM Least Significant bits

Capture mode: Unused.

Compare mode: Unused.

PWM mode: These bits are the two LSbs of the PWM duty cycle. The eight MSbs are found in CCPRxL.
bit 3-0 CCPxM3:CCPxM0: CCPx Mode Select bits
▪ 0000 = Capture/Compare/PWM disabled (resets CCPx module) ▪ 0100 =
Capture mode, every falling edge
▪ 0101 = Capture mode, every rising edge
▪ 0110 = Capture mode, every 4th rising edge
▪ 0111 = Capture mode, every 16th rising edge
▪ 1000 = Compare mode, set output on match (CCPxIF bit is set) ▪ 1001 = Compare
mode, clear output on match (CCPxIF bit is set) ▪ 1010 = Compare mode, generate
software interrupt on match (CCPxIF bit is set, CCPx pin is unaffected)
▪ 1011 = Compare mode, trigger special event (CCPxIF bit is set, CCPx pin is
unaffected); CCP1 resets TMR1; CCP2 resets TMR1 and starts an A/D conversion
(if A/D module is enabled)
▪ 11xx = PWM mode

CAPTURE/COMPARE/PWM MODULES

Each Capture/Compare/PWM (CCP) module contains a 16-bit register which can operate as
a:

• 16-bit Capture register

• 16-bit Compare register

• PWM Master/Slave Duty Cycle register

Both the CCP1 and CCP2 modules are identical in operation, with the exception being the
operation of the special event trigger. Table 8-1 and Table 8-2 show the resources and
interactions of the CCP module(s). In the following sections, the operation of a CCP module is
described with respect to CCP1. CCP2 operates the same as CCP1 except where noted.
CCP1 Module: Capture/Compare/PWM Register 1 (CCPR1) is comprised of two 8-bit
registers: CCPR1L (low byte) and CCPR1H (high byte). The CCP1CON register controls the
operation of CCP1. The special event trigger is generated by a compare match and will reset
Timer1.

PWM OPERATION

▪ In Pulse Width Modulation mode, the CCPx pin produces up to a 10-bit resolution
PWM output. Since the CCP1 pin is multiplexed with the PORTC data latch, the
TRISC bit must be cleared to make the CCP1 pin an output.
▪ Clearing the CCP1CON register will force the CCP1 PWM output latch to the default
low level. This is not the PORTC I/O data latch.

SIMPLIFIED PWM BLOCK DIAGRAM

Steps for configuring the CCP module for PWM operation:

▪ Set the PWM period by writing to the PR2 register.


▪ Set the PWM duty cycle by writing to the CCPR1L register and CCP1CON bits.
▪ Make the CCP1 pin an output by clearing the TRISC bit.
▪ Set the TMR2 prescale value and enable Timer2 by writing to T2CON. ▪ Configure
the CCP1 module for PWM operation

PWM OUTPUT
A PWM output has a time base (period) and a time that the output stays high (duty cycle).
The frequency of the PWM is the inverse of the period (1/period).

▪ The PWM period is specified by writing to the PR2 register. ▪ The PWM period can be
calculated using the following formula: PWM Period = [(PR2) + 1] • 4 • TOSC •
(TMR2 Prescale Value) ▪ PWM frequency is defined as 1/[PWM period].
▪ When TMR2 is equal to PR2, the following three events occur on the next increment
cycle:
• TMR2 is cleared
• The CCP1 pin is set (exception: if PWM duty cycle = 0%, the CCP1 pin will not be
set)
• The PWM duty cycle is latched from CCPR1L into

INTERRUPT REGISTERS

• To enable interrupt PIE1 (Peripheral Interrupt enable) register is used. TMR2IE bit of PIE1 register
will be 1 to enable interrupt.

• PIR1 is the peripheral interrupt flag register. When TMR2 overflows TMR2IF bit of PIR1 become 1
• General interrupt and peripheral interrupt enable is done by making PEIE=1 & GIE=1 • PEIE, GIE
are the bits of interrupt control register INTCON
MATRIX GENERATION

Modulating frequency = 50Hz

Carrier frequency = 20 kHz

20000
Total no. of pulses per cycle of sine wave = = 400 50
Following C program is used to generate the duty ratio of these 400 pulses.

#include <stdio.h>

#include <math.h>

#include <conio.h>

#define PI 3.141592653589793

int main()

int period=1000;

int OnTimer=500;

int Nsamples=100;

int n=1;

float carrierFreq = 5000;

float modFreq = 50;

float modIndex = 0.96;

double duty=0.5;

printf("####################################################
########\n");
printf("## ##\n");

printf("## SINE-PWM Matrix Generator ##\n");

printf("## ##\n");

printf("####################################################
########\n\n");
printf("Enter the modulation frequency : ");

scanf("%f",&modFreq);
printf("Enter the carrier frequency : ");

scanf("%f",&carrierFreq);

printf("Enter the value of Time Period Register : ");


scanf("%d",&period);
Nsamples = carrierFreq/modFreq;

printf("Enter the modulation Index : ");

scanf("%f",&modIndex);

printf("\n################# FILE SAVED AS matrix.c


#################\n\n");

FILE* file;

file = fopen("matrix.c","w");

printf("#define LKUP_SIZE %d\n\n",Nsamples);


fprintf(file,"#define LKUP_SIZE %d\n\n",Nsamples);
printf("const unsigned char lookup[LKUP_SIZE] = {\n\t");
fprintf(file,"const unsigned char lookup[LKUP_SIZE] = {\n\t");
for (n=1;n<=Nsamples;n++)
{

duty = 0.5 * ( 1 + modIndex * sin( (PI*((2*n)-1)) / Nsamples


)); OnTimer = round(period * duty);
if(n==Nsamples)

printf("%d };",OnTimer);

fprintf(file,"%d };",OnTimer);
}

else

printf("%d ,",OnTimer);

fprintf(file,"%d ,",OnTimer);
}

if(n%10 == 0)

printf("\n\t");

fprintf(file,"\n\t");

printf("\n################# FILE SAVED AS matrix.c


#################\n\n");
printf("Press any key to exit...");

getch();

fclose(file);

return 0;

Generated matrix value

#define LKUP_SIZE 400

const unsigned char lookup[LKUP_SIZE] = { 101


,102 ,104 ,105 ,107 ,108 ,110 ,111 ,113 ,114 , 115
,117 ,118 ,120 ,121 ,123 ,124 ,126 ,127 ,128 ,
130 ,131 ,133 ,134 ,135 ,137 ,138 ,139 ,141 ,142
, 143 ,145 ,146 ,147 ,148 ,150 ,151 ,152 ,153
,155 , 156 ,157 ,158 ,159 ,160 ,162 ,163 ,164
,165 ,166 , 167 ,168 ,169 ,170 ,171 ,172 ,173
,174 ,175 ,176 , 176 ,177 ,178 ,179 ,180 ,181
,181 ,182 ,183 ,183 , 184 ,185 ,185 ,186 ,187
,187 ,188 ,188 ,189 ,189 , 190 ,190 ,190 ,191
,191 ,192 ,192 ,192 ,192 ,193 , 193 ,193 ,193
,194 ,194 ,194 ,194 ,194 ,194 ,194 , 194 ,194
,194 ,194 ,194 ,194 ,194 ,193 ,193 ,193 , 193
,192 ,192 ,192 ,192 ,191 ,191 ,190 ,190 ,190 ,
189 ,189 ,188 ,188 ,187 ,187 ,186 ,185 ,185 ,184
, 183 ,183 ,182 ,181 ,181 ,180 ,179 ,178 ,177
,176 , 176 ,175 ,174 ,173 ,172 ,171 ,170 ,169
,168 ,167 , 166 ,165 ,164 ,163 ,162 ,160 ,159
,158 ,157 ,156 , 155 ,153 ,152 ,151 ,150 ,148
,147 ,146 ,145 ,143 , 142 ,141 ,139 ,138 ,137
,135 ,134 ,133 ,131 ,130 , 128 ,127 ,126 ,124
,123 ,121 ,120 ,118 ,117 ,115 , 114 ,113 ,111 ,110
,108 ,107 ,105 ,104 ,102 ,101 , 99 ,98 ,96 ,95 ,93
,92 ,90 ,89 ,87 ,86 ,
85 ,83 ,82 ,80 ,79 ,77 ,76 ,74 ,73 ,72 ,

70 ,69 ,67 ,66 ,65 ,63 ,62 ,61 ,59 ,58 ,

57 ,55 ,54 ,53 ,52 ,50 ,49 ,48 ,47 ,45 ,

44 ,43 ,42 ,41 ,40 ,38 ,37 ,36 ,35 ,34 ,


33 ,32 ,31 ,30 ,29 ,28 ,27 ,26 ,25 ,24
,
24 ,23 ,22 ,21 ,20 ,19 ,19 ,18 ,17 ,17
, 16 ,15 ,15 ,14 ,13 ,13 ,12 ,12 ,11 ,11
,
10 ,10 ,10 ,9 ,9 ,8 ,8 ,8 ,8 ,7 ,

7 ,7 ,7 ,6 ,6 ,6 ,6 ,6 ,6 ,6 ,

6 ,6 ,6 ,6 ,6 ,6 ,6 ,7 ,7 ,7 ,

7 ,8 ,8 ,8 ,8 ,9 ,9 ,10 ,10 ,10 ,

11 ,11 ,12 ,12 ,13 ,13 ,14 ,15 ,15 ,16 ,

17 ,17 ,18 ,19 ,19 ,20 ,21 ,22 ,23 ,24 ,

24 ,25 ,26 ,27 ,28 ,29 ,30 ,31 ,32 ,33


, 34 ,35 ,36 ,37 ,38 ,40 ,41 ,42,43,44,
45 ,47 ,48 ,49 ,50 ,52 ,53 ,54 ,55 ,57 ,
58 ,59 ,61 ,62 ,63 ,65 ,66 ,67 ,69 ,70,
72 ,73 ,74 ,76 ,77 ,79 ,80 ,82 ,83 ,85 ,

86 ,87 ,89 ,90 ,92 ,93 ,95 ,96 ,98 ,99 };

PROGRAM

Main File :

#define _XTAL_FREQ 16000000

#include "configuration.h"

#include <xc.h>

#include "matrix.c"

extern const unsigned char


lookup[LKUP_SIZE]; unsigned char buffer=0;
int n=0;
void __interrupt() myISR()

if(PIR1bits.TMR2IF &&
PIE1bits.TMR2IE) {
PIR1bits.TMR2IF = 0; //timer 2 interrupt cleared
buffer = lookup[n++];
if(n>=LKUP_SIZE) n=0;

return;

void main()

TRISC = 0; //configure port C as output

//CCP pin RC2/CCP1 is on port C


PR2 = 199; // PWM frequency = Fosc/(4*(PR2+1)) = 20kHz
// PWM frequency = 16MHz/(4*200) = 20kHz
// PWM time period = 50uS

CCPR1L = 0;

T2CONbits.T2CKPS = 0b00; // prescaler is 1 //00-1


//01-4
//1x-16
T2CONbits.TOUTPS = 0x0; //postscaler is 1

TMR2 = 0; // clear timer before turning on

PIE1bits.TMR2IE = 1; //timer 2 interrupt enable


PIR1bits.TMR2IF = 0; //timer 2 interrupt cleared
INTCONbits.PEIE = 1; //peripheral interrupt enable
INTCONbits.GIE = 1; //general interrupt enable

T2CONbits.TMR2ON = 1; // timer 2 turned on

CCP1CONbits.CCP1X = 0; // LSB = 0

CCP1CONbits.CCP1Y = 0; // LSB = 0

CCP1CONbits.CCP1M = 0b1100; //15- PWM turned on

while(1)

CCPR1L = buffer;

}
Header File:

// PIC16F877A Configuration Bit Settings

// 'C' source line config statements


// CONFIG

#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)

#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit
(RB3 is digital I/O, HV on MCLR must be used for programming)

#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code
protection off)

#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all
program memory may be written to by EECON control)

#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)

// #pragma config statements should precede project file includes.

// Use project enums instead of #define for ON and OFF.

#include <xc.h>

Configuration bit = 3F3A


SIMULATION MODEL
SIMULATION RESULTS

OUTPUT
RESULT

A microcontroller based 50Hz sine PWM half bridge inverter is designed and simulated using Proteus.
Relevant waveforms are plotted.

Submitted by:

Amala M

S2 M.Tech

Roll No:01

You might also like