• AVR Freaks

Hot!How to change PWM using ADC

Author
parkcoding
New Member
  • Total Posts : 20
  • Reward points : 0
  • Joined: 2019/03/13 16:17:10
  • Location: 0
  • Status: offline
2019/04/22 23:17:09 (permalink)
0

How to change PWM using ADC

Hi~
 
I want to change brightness of LED using ADC and PWM in PIC18F87J60.
 
But I don't know what's the problem in my codes.
 
Please help me~
 
 
#include <xc.h> 
#include <pic18f87j60.h> 
#include <stdbool.h> 
#include <stdint.h>
#include <stdio.h>

#pragma config WDT = OFF
#pragma config FOSC = HS 
#pragma config DEBUG = OFF
#pragma config XINST = OFF
#define _XTAL_FREQ 25000000 

unsigned char num = 0; 
unsigned int adc_buf1 = 0;
unsigned int adc_buf2 = 0;
unsigned int left_adc;
unsigned int right_adc;
 
void Initial_PORT(void) //Port Initialize Function
{
    TRISAbits.TRISA0 = 1;
    PORTAbits.RA0 = 1;
}
 
void Initial_Interrupts(void) //Interrupt Initialize Function
{
    RCONbits.IPEN = 1; //Interrupt Priority enable
    INTCONbits.GIE = 1; //Global Interrupt enable
    INTCONbits.PEIE = 1; //Peripheral Interrupt enable

    PIR1bits.ADIF = 0; //A/D unable
    PIE1bits.ADIE = 1; //A/D enable
}

void Initial_ADC() //A/D Initialize Function
{
/*ADCON2 = 0xFF*/
    ADCON2bits.ADFM = 1;
    ADCON2bits.ACQT2 = 1;
    ADCON2bits.ACQT1 = 1;
    ADCON2bits.ACQT0 = 1;
    ADCON2bits.ADCS2 = 1; 
    ADCON2bits.ADCS1 = 1;
    ADCON2bits.ADCS0 = 1;
/*ADCON1 = 0x0E*/
    ADCON1bits.VCFG1 = 0; //Voltage : AVss
    ADCON1bits.VCFG0 = 0; //Voltage : AVdd
    ADCON1bits.PCFG3 = 1; 
    ADCON1bits.PCFG2 = 1;
    ADCON1bits.PCFG1 = 1;
    ADCON1bits.PCFG0 = 0;

/*ADCON0 = 0x03*/
    ADCON0bits.ADCAL = 0; 
    ADCON0bits.CHS3 = 0; 
    ADCON0bits.CHS2 = 0;
    ADCON0bits.CHS1 = 0;
    ADCON0bits.CHS0 = 0;
    ADCON0bits.ADON = 1; 
    ADCON0bits.GODONE = 1;
}
 
void plus()
{
    if(CCPR4L < 255)
    CCPR4L = CCPR4L + 25;
}
 
void minors()
{
    if(CCPR4L > 29)
    CCPR4L = CCPR4L - 25;
}
 

int adc_right() //A/D read
{
    ADCON0bits.GO = 1; 
    while(ADCON0bits.GODONE); 
    adc_buf1 = (unsigned int)(ADRESH <<8) + ADRESL;
    return adc_buf1; 
}
 
int adc_left() //A/D read
{
    ADCON0bits.GO = 1; 
    while(ADCON0bits.GODONE); 
    adc_buf2 = (unsigned int)(ADRESL <<8) + ADRESH;
    return adc_buf2; 
}
 
void main(void)
{

    OSCCON = 0xF2; 
    Initial_PORT(); 
    Initial_Interrupts(); 
    Initial_ADC(); 


    INTCON = 0xD0;
    INTCON3 = 0x08;
    PIE1 = 0x02; 
    PIE3 = 0x02; 
    RCON = 0x80; 

    TRISG = 0xF7; 
    TRISB = 0xFF; 

    PR2 = 249; //PWM Period = [(PR2)+1] * 4 * Tosc * (TMR2 Prescale Value)

    TMR2 = 35535;

    T2CON = 0x06;

    CCPR4L = 5; 
    CCP4CON = 0x2C; 


    LATGbits.LATG3 = 1;

    right_adc = adc_right();
    left_adc = adc_left();

 while(1)
 {
    if (right_adc)
  {
    plus();
  }

 else if (left_adc)
  {
 minors();
  }
 }
return;
}
 
 
#1

8 Replies Related Threads

    pcbbc
    Super Member
    • Total Posts : 900
    • Reward points : 0
    • Joined: 2014/03/27 07:04:41
    • Location: 0
    • Status: online
    Re: How to change PWM using ADC 2019/04/22 23:58:15 (permalink)
    0
    Where is your ISR (Interrupt Serive Routine)?
    You have enabled interrupts, but do not seem to have one. Post all of your code.

    Put [CODE]code tags[/CODE] around your code before posting to format it correctly.
    Note: The words “CODE” should be in lowercase (“code”) to work correctly.
    #2
    qhb
    Superb Member
    • Total Posts : 9951
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: How to change PWM using ADC 2019/04/23 00:27:35 (permalink)
    0
    Change
    #include <xc.h> 
    #include <pic18f87j60.h>
    #include <stdbool.h>
    #include <stdint.h>
    #include <stdio.h>

    to just
    #include <xc.h>

    (xc.h already includes the device specific header. You are not using ANYTHING from the other headers.)
     
    Your Initial_PORT() function sets A0 to be an input, then tries to set the state of that port.
    "input" is the default state anyway, and you can't set the level of an input pin.
     
    As stated by others, do NOT enable interrupts if you don't have an interrupt service routine.
    Your code is polling the interrupt request flag, so you should NOT set the interrupt enable flag. That will cause this code to crash as soon as an interrupt occurs.
     
    #3
    parkcoding
    New Member
    • Total Posts : 20
    • Reward points : 0
    • Joined: 2019/03/13 16:17:10
    • Location: 0
    • Status: offline
    Re: How to change PWM using ADC 2019/04/23 00:36:28 (permalink)
    0
    okay, but it doesn't work.
     
    haha
     
    #include <xc.h>

    #pragma config DEBUG = OFF //Debug off
    #pragma config XINST = OFF //Extended Instruction off
    #pragma config WDT = OFF //Watchdog Timer off
    #pragma config FOSC = HS 
    #define _XTAL_FREQ 25000000 

    unsigned int adc_value = 0; //adc_value Initilaize
    float adc_volt = 0; //adc_volt Initilaize
    unsigned char num = 0; 

    void Initial_PORT(void) //Port Initialize Function
    {
        TRISAbits.TRISA0 = 1; 
        PORTAbits.RA0 = 1; 
    }

    void Initial_Interrupts(void) //Interrupt Initialize Function
    {
        RCONbits.IPEN = 1; //Interrupt Priority enable
        INTCONbits.GIE = 1; //Global Interrupt enable
        INTCONbits.PEIE = 1; //Peripheral Interrupt enable
        PIR1bits.ADIF = 0; //A/D unable
        PIE1bits.ADIE = 1; //A/D enable
    }

    void Initial_ADC() //A/D Initialize Function
    {
    /*ADCON2 = 0xFF*/
        ADCON2bits.ADFM = 1; 
        ADCON2bits.ACQT2 = 1; 
        ADCON2bits.ACQT1 = 1;
        ADCON2bits.ACQT0 = 1;
        ADCON2bits.ADCS2 = 1; 
        ADCON2bits.ADCS1 = 1;
        ADCON2bits.ADCS0 = 1;
    /*ADCON1 = 0x0E*/
        ADCON1bits.VCFG1 = 0; //Voltage : AVss
        ADCON1bits.VCFG0 = 0; //Voltage : AVdd
        ADCON1bits.PCFG3 = 1; 
        ADCON1bits.PCFG2 = 1;
        ADCON1bits.PCFG1 = 1;
        ADCON1bits.PCFG0 = 0;

    /*ADCON0 = 0x03*/
        ADCON0bits.ADCAL = 0; 
        ADCON0bits.CHS3 = 0; 
        ADCON0bits.CHS2 = 0;
        ADCON0bits.CHS1 = 0;
        ADCON0bits.CHS0 = 0;
        ADCON0bits.ADON = 1; 
        ADCON0bits.GODONE = 1; 

    }


    unsigned int adc_read(unsigned char) //A/D read
    {
        unsigned int adc_buf; 
        ADCON0bits.GO = 1; 
        while(ADCON0bits.GODONE);  
        adc_buf = (unsigned int)(ADRESH <<8) + ADRESL; 
        return adc_buf; 
    }
     
    void main(void) //Main Function
    {
        OSCCON = 0xF2;

        Initial_PORT(); 
        Initial_Interrupts(); 
        Initial_ADC(); 
      while(1)
      {
        adc_volt = (float)(5*((float)(adc_value)/1023));
        adc_value = adc_read(0); 
        CCPR4L = adc_value;

      if(adc_value < 255)
     {
         CCPR4L = CCPR4L + 25;
      } else if(adc_value > 29)
     {
        CCPR4L = CCPR4L - 25;
      }
     }
    }
    #4
    qhb
    Superb Member
    • Total Posts : 9951
    • Reward points : 0
    • Joined: 2016/06/05 14:55:32
    • Location: One step ahead...
    • Status: offline
    Re: How to change PWM using ADC 2019/04/23 00:44:19 (permalink)
    0
    parkcoding
    okay, but it doesn't work.

    What doesn't work?
    You appear to have ignored most of the advice you have been given, including putting "code" tags around your code.
     

    haha

    Why laugh when people are giving serious help?
     
    #5
    parkcoding
    New Member
    • Total Posts : 20
    • Reward points : 0
    • Joined: 2019/03/13 16:17:10
    • Location: 0
    • Status: offline
    Re: How to change PWM using ADC 2019/04/23 01:22:19 (permalink)
    -1 (1)
    I'm sorry if you're upset.
     
    I want to check the change in LED brightness by adjusting the PWM with variable resistance. But I can't.
     
     
     
    #include <xc.h>

    #pragma config DEBUG = OFF //Debug off
    #pragma config XINST = OFF //Extended Instruction off
    #pragma config WDT = OFF //Watchdog Timer off
    #pragma config FOSC = HS 
    #define _XTAL_FREQ 25000000 

    unsigned int adc_value = 0; //adc_value Initilaize
    float adc_volt = 0; //adc_volt Initilaize
    unsigned char num = 0; 

    void Initial_PORT(void) //Port Initialize Function
    {
        TRISAbits.TRISA0 = 1;      //
        PORTAbits.RA0 = 1;          //
    }

    void Initial_Interrupts(void) //Interrupt Initialize Function
    {
        RCONbits.IPEN = 1; //Interrupt Priority enable
        INTCONbits.GIE = 1; //Global Interrupt enable
        INTCONbits.PEIE = 1; //Peripheral Interrupt enable
        PIR1bits.ADIF = 0; //A/D unable
        PIE1bits.ADIE = 1; //A/D enable
    }

    void Initial_ADC() //A/D Initialize Function
    {
    /*ADCON2 = 0xFF*/
        ADCON2bits.ADFM = 1; //right justified
        ADCON2bits.ACQT2 = 1; //20TAD
        ADCON2bits.ACQT1 = 1;
        ADCON2bits.ACQT0 = 1;
        ADCON2bits.ADCS2 = 1; //clock derived from A/D RC oscillator
        ADCON2bits.ADCS1 = 1;
        ADCON2bits.ADCS0 = 1;
    /*ADCON1 = 0x0E*/
        ADCON1bits.VCFG1 = 0; //Voltage : AVss
        ADCON1bits.VCFG0 = 0; //Voltage : AVdd
        ADCON1bits.PCFG3 = 1; //AN0 configuration Control bits.
        ADCON1bits.PCFG2 = 1;
        ADCON1bits.PCFG1 = 1;
        ADCON1bits.PCFG0 = 0;

    /*ADCON0 = 0x03*/
        ADCON0bits.ADCAL = 0; //A/D Calibration bit 
        ADCON0bits.CHS3 = 0;   //AN0 Channel
        ADCON0bits.CHS2 = 0;
        ADCON0bits.CHS1 = 0;
        ADCON0bits.CHS0 = 0;
        ADCON0bits.ADON = 1; //A/D Conversion Status Bit
        ADCON0bits.GODONE = 1; // A/D on bit

    }


    unsigned int adc_read(unsigned char) //A/D read
    {
        unsigned int adc_buf; 
        ADCON0bits.GO = 1; 
        while(ADCON0bits.GODONE);  
        adc_buf = (unsigned int)(ADRESH <<8) + ADRESL; 
        return adc_buf; 
    }
     
    void main(void) //Main Function
    {
        OSCCON = 0xF2;

        Initial_PORT(); 
        Initial_Interrupts(); 
        Initial_ADC(); 

      while(1)
      {
        adc_volt = (float)(5*((float)(adc_value)/1023));
        adc_value = adc_read(0); 
        CCPR4L = adc_value;

      if(adc_value < 255)
     {
         CCPR4L = CCPR4L + 25;
      } else if(adc_value > 29)
     {
        CCPR4L = CCPR4L - 25;
      }
     }
    }
    #6
    pcbbc
    Super Member
    • Total Posts : 900
    • Reward points : 0
    • Joined: 2014/03/27 07:04:41
    • Location: 0
    • Status: online
    Re: How to change PWM using ADC 2019/04/23 02:05:47 (permalink)
    +2 (2)
    1. You're still enabling interrupts, with no ISR defined to handler them.  Your code will crash.
    void Initial_Interrupts(void) //Interrupt Initialize Function
    {
        RCONbits.IPEN = 1; //Interrupt Priority enable
        INTCONbits.GIE = 1; //Global Interrupt enable
        INTCONbits.PEIE = 1; //Peripheral Interrupt enable
        PIR1bits.ADIF = 0; //A/D unable
        PIE1bits.ADIE = 1; //A/D enable
    }

    You do not need any of these lines, or if you keep them you must define an ISR.
     
    2. You still aren't putting [CODE]code tags[/CODE] (in lower case) around your code.
    #7
    mpgmike
    Super Member
    • Total Posts : 123
    • Reward points : 0
    • Joined: 2014/01/23 17:27:06
    • Location: NJ
    • Status: online
    Re: How to change PWM using ADC 2019/04/23 08:19:46 (permalink)
    +1 (1)
    Simply put,

    unsigned char AdcVal;  //Declare a 1-byte variable
    ADCON2 = 0x2C;  //Left Justify, & Timing Settings; Check this to be sure
    ADCON0 = //(ADC Channel as per Data Sheet, leave GO = 0)
    CCP4CON = 0x0F;  //PWM Mode
    T2CON = //Configure Timer 2 as per CCP section in Data Sheet
    T2PR = //    "     "     "
    ADCON0bits.GO = 1;
    while(ADCON0bits.GO = 1);
    AdcVar = ADRESH;
    CCPR4L = AdcVar;

    #8
    PStechPaul
    Super Member
    • Total Posts : 2205
    • Reward points : 0
    • Joined: 2006/06/27 16:11:32
    • Location: Cockeysville, MD, USA
    • Status: offline
    Re: How to change PWM using ADC 2019/04/23 11:01:00 (permalink)
    0 (2)
    I'm not going to bother even trying to help the OP, if he refuses to follow the requests of those who are taking the time and effort to do so. I also gave a downvote to his latest post. Also, isn't there at least one other thread about this same project?
     
    https://www.microchip.com/forums/FindPost/1093309/?
     
    https://www.microchip.com.orums/FindPost/1094759/?
    post edited by PStechPaul - 2019/04/23 11:12:37

     
    #9
    Jump to:
    © 2019 APG vNext Commercial Version 4.5