Author Topic: Wanted to generate PWM pulses using IC16F87XA  (Read 1314 times)

0 Members and 1 Guest are viewing this topic.

Offline khatusTopic starter

  • Regular Contributor
  • *
  • Posts: 146
  • Country: gl
Wanted to generate PWM pulses using IC16F87XA
« on: April 07, 2020, 06:24:37 pm »
Hello guys I wanted to generate 4.9kHZ Pwm using Pic micro controller  with out using in build functions.I am using PIC16F87XA mcu this time .
Here is my code
Code: [Select]
void main()
{
    PR2=0x65; // Frequency: 4.90 kHz
    CCP1CON=0b00001100;   //Configure the CCP1 module
    T2CON.T2CKPS0 = 1;
    T2CON.T2CKPS1 = 0;
    TRISC.B2 = 0; // make port pin on C as output
    while(T2CON.TMR2ON = 1) //Infinite Loop
{
}
}
Here is the steps that i have followed




BUT while simulating it in proteus i did not get any result from RC2 PIN(CCP1 pin of PC microcontroller) i did not get any pulse from the pin.
What is the problem??
 

Offline MarkF

  • Super Contributor
  • ***
  • Posts: 2555
  • Country: us
Re: Wanted to generate PWM pulses using IC16F87XA
« Reply #1 on: April 07, 2020, 07:26:24 pm »
I have setup PWM on a pic18F2550 and here is some code for a pic16F877A (I don't remember if I tested the PIC16 code):

Code: [Select]
            // PWM token...
            //    buffer[2] == Prescalar (0 = Turn Off PWM Mode)
            //    buffer[3] == PR2
            //    buffer[4] == CCPR1L (Duty Cycle)

            case FT_PWM:
               T2CON=buffer[2];        // Timer2 Control Reg
               if (buffer[2]==0) {
                  CCP1CON=0;           // PWM Off
                  TRISCbits.TRISC2=1;  // Pin as Input
               } else {
                  PR2=buffer[3];       // PWM Period
                  CCPR1L=buffer[4];    // Duty Cycle MSBs
                  CCP1CON=0x0c;        // PWM On & Duty Cycle LSBs
                  TRISCbits.TRISC2=0;  // Pin as Output
               }
               break;


I noticed in your code your TRIS direction code is wrong.
You are mixing PortB and PortC.
Code: [Select]
TRISC.B2 = 0; // make port pin on C as outputShould be:
Code: [Select]
TRISCbits.TRISC2=0;  // Pin as Output
« Last Edit: April 07, 2020, 07:29:49 pm by MarkF »
 

Offline khatusTopic starter

  • Regular Contributor
  • *
  • Posts: 146
  • Country: gl
Re: Wanted to generate PWM pulses using PIC16F87XA
« Reply #2 on: April 07, 2020, 07:54:27 pm »
Can you show something simpler .I am newbie.
 

Offline chayanforyou

  • Newbie
  • Posts: 2
  • Country: bd
Re: Wanted to generate PWM pulses using IC16F87XA
« Reply #3 on: April 08, 2020, 02:17:21 am »
Here You Go.

Code: [Select]
/*

  PWM Generation 4.88KHz

  ********************************

  Compiler: mikroC Pro for PIC

  For
   PIC 16F877A @ 20MHz

  CONFIG:
   $2007 : 0x2F42

   Copyright (c) 2020
   Chayan Mistry

*/


// --- Function for Setting PWM Duty Cycle ---
void SetPWMDutyCycle(unsigned int DutyCycle) // Give a value in between 0 and 1024 for DutyCycle
{
  CCPR1L   = DutyCycle>>2;                // Put MSB 8 bits in CCPR1L
  CCP1CON &= 0xCF;                        // Make bit4 and 5 zero
  CCP1CON |= (0x30&(DutyCycle<<4));       // Assign Last 2 LSBs to CCP1CON
}

// --- Main Function ---
void main()
{
  TRISC.B2  = 0;          // Make CCP1 pin as output
  CCP1CON = 0x0C;         // Configure CCP1 module in PWM mode

  PR2   = 0xFF;           // Configure the Timer2 period
  T2CON = 0x01;           // Set Prescaler to be 4, hence PWM frequency is set to 4.88KHz.

  SetPWMDutyCycle(512);   // Intialize the PWM to 50% duty cycle

  T2CON |= 0x04;          // Enable the Timer2, hence enable the PWM.
 
  while (1)               //Infinite loop
  {

  } //end while

} //end main

« Last Edit: April 08, 2020, 02:53:17 am by chayanforyou »
 
The following users thanked this post: khatus

Offline khatusTopic starter

  • Regular Contributor
  • *
  • Posts: 146
  • Country: gl
Re: Wanted to generate PWM pulses using IC16F87XA
« Reply #4 on: April 08, 2020, 05:08:06 am »
Thanks :)
 

Offline khatusTopic starter

  • Regular Contributor
  • *
  • Posts: 146
  • Country: gl
Re: Wanted to generate PWM pulses using IC16F87XA
« Reply #5 on: April 08, 2020, 07:47:29 am »
Here is my code This time i wanted to vary pwm signal according to a potentiometer connected at pin A1.Here is my code for mikroc.But THe pwm signal did not vary according to the adc value.
Code: [Select]
void PWM_Init(unsigned char period)
{
  TRISC &=0xFD;  //  Set RC2 as output

  /* CCP PWM mode */
  CCP1CON &= 0xCF;  //  5,4 bits zeroed (DC1B1:DC1B0 = 00)
  CCP1CON |= 0x0C;  //  PWM mode ( CCP1M3:CCP1M0 = 1100)

  /* Timer2 configuration */
  PR2 = period;  //  configure timer2 period
  T2CON = 0x02;  //  Set prescalar 16
  TMR2ON_bit = 1;  //  timer2 on

}
void PWM_setDC(unsigned int dutycycle)
{

  CCPR1L = dutycycle>>2;  //  PWM duty cycle - first 8-bits (MSb)
  CCP1CON &= 0xCF;  //  5,4 bits zeroed (DC1B1:DC1B0 = 00)
  CCP1CON |= ((dutycycle<<4)&0x30);  //  PWM duty cycle - last 2-bits (LSb) in CCP1CON 5,4 bits
}
void main()
{
  int adc_value;
  TRISC = 0x00; //PORTC as output
  TRISA = 0xFF; //PORTA as input
  PWM_Init(0xFF);
  //This sets the PWM frequency of PWM1

 while(1); //Infinite Loop
   {

   adc_value = ADC_Read(1); //Reading Analog Channel 0
   PWM_setDC(adc_value);
   delay_ms(50);
   }
}


https://openlabpro.com/guide/pulse-width-modulation-using-pic18f4550/?fbclid=IwAR2a1g4x03pfe-nlGO5xAImaFrZUSOzNqZa5DS4t4Hts6kWZaBuF_nyQBIg
I used the following link code for my code.
 

Offline MarkF

  • Super Contributor
  • ***
  • Posts: 2555
  • Country: us
Re: Wanted to generate PWM pulses using IC16F87XA
« Reply #6 on: April 09, 2020, 03:38:56 pm »
You need to use AN0 (not AN1 as shown in your circuit).
Refer to register ADCON1 for analog channel selections.



Code: [Select]
/*
 * File:      main.c
 * Author:    Mark
 * Compiler:  Microchip XC8
 */

// CONFIGURATION BITS

#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
#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)

#define _XTAL_FREQ 20000000L

#include <xc.h>
#include <stdio.h>
#include <stdlib.h>

//======================================================================
void main(void)
{
   // SETUP PWM
   TRISCbits.TRISC2=0;     // Pin as Output
   PR2=0xff;               // PWM Period (4.88 KHz)
   CCPR1L=0;               // Duty Cycle MSBs
   CCP1CON=0x0c;           // PWM On
   T2CON=0x05;             // Timer2 Ctrl Reg (Timer2=On, Prescale=4)

   // SETUP A/D CONVERSION
   TRISAbits.TRISA0=1;     // Pin as Input
   ADCON0bits.CHS=0;       // Channel=AN0
   ADCON1=0x0e;            // FSOC/32 and Left Justified Result
   ADCON0=0x81;            // FSOC/32 and A/D On

   while (1)
   {
      // Get AN0 and Update PWM
      ADCON0bits.GO=1;                       // Start A/D conversion
      while (ADCON0bits.nDONE);              // Wait for Done
      CCP1CON=((ADRESL>>2) & 0x30) | 0x0c;   // PWM Duty Cycle lower bits + PWM On
      CCPR1L=ADRESH;                         // PWM Duty Cycle upper bits
     
      __delay_ms(100);     // Delay 100ms (i.e. 10Hz update rate)
   }
}

 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf