Author Topic: thoughts on my project  (Read 11034 times)

0 Members and 1 Guest are viewing this topic.

Offline ali6x944Topic starter

  • Frequent Contributor
  • **
  • Posts: 577
  • Country: sa
thoughts on my project
« on: January 08, 2020, 07:00:39 pm »
Hi everyone,

I'm posting to ask your opinion of my program structure, anyway I can optimize it or reduce its complexity without resorting to using MCC.

so it is a derivation of an older project, I tried to reduce physical & syntax complexity by eliminating both the pain and confusion of using MCC and the low-power-mode pin:

https://www.microchip.com/forums/m1024225.aspx

this project is not fully improved this project is not complete!!
Code: [Select]
/***************************************************************************************************************************
 *
 * Author:Ali6x944
 * Date: 8/1/2020
 * Device: PIC16LF15313
 * Description: A program designed to run on PIC16LF15313, that facilitates a single-chip
 * solution to controlling 2 LED Panels/Arrays using a single multi-position slider switch and a pot to control brightness.
 *
 ***************************************************************************************************************************/
// PIC16LF15313 Configuration Bit Settings

// 'C' source line config statements

// CONFIG1
#pragma config FEXTOSC = OFF // External Oscillator mode selection bits (Oscillator not enabled)
#pragma config RSTOSC = HFINT1 // Power-up default value for COSC bits (HFINTOSC (1MHz))
#pragma config CLKOUTEN = OFF // Clock Out Enable bit (CLKOUT function is disabled; i/o or oscillator function on OSC2)
#pragma config CSWEN = OFF // Clock Switch Enable bit (The NOSC and NDIV bits cannot be changed by user software)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (FSCM timer disabled)

// CONFIG2
#pragma config MCLRE = ON // Master Clear Enable bit (MCLR pin is Master Clear function)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config LPBOREN = OFF // Low-Power BOR enable bit (ULPBOR disabled)
#pragma config BOREN = OFF // Brown-out reset enable bits (Brown-out reset disabled)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (VBOR) set to 1.9V on LF, and 2.45V on F Devices)
#pragma config ZCD = OFF // Zero-cross detect disable (Zero-cross detect circuit is disabled at POR.)
#pragma config PPS1WAY = ON // Peripheral Pin Select one-way control (The PPSLOCK bit can be cleared and set only once in software)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable bit (Stack Overflow or Underflow will cause a reset)

// CONFIG3
#pragma config WDTCPS = WDTCPS_31// WDT Period Select bits (Divider ratio 1:65536; software control of WDTPS)
#pragma config WDTE = OFF // WDT operating mode (WDT Disabled, SWDTEN is ignored)
#pragma config WDTCWS = WDTCWS_7// WDT Window Select bits (window always open (100%); software control; keyed access not required)
#pragma config WDTCCS = SC // WDT input clock selector (Software Control)

// CONFIG4
#pragma config BBSIZE = BB512 // Boot Block Size Selection bits (512 words boot block size)
#pragma config BBEN = OFF // Boot Block Enable bit (Boot Block disabled)
#pragma config SAFEN = OFF // SAF Enable bit (SAF disabled)
#pragma config WRTAPP = OFF // Application Block Write Protection bit (Application Block not write protected)
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot Block not write protected)
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration Register not write protected)
#pragma config WRTSAF = OFF // Storage Area Flash Write Protection bit (SAF not write protected)
#pragma config LVP = ON // Low Voltage Programming Enable bit (Low Voltage programming enabled. MCLR/Vpp pin function is MCLR.)

// CONFIG5
#pragma config CP = OFF // UserNVM Program memory code protection bit (UserNVM code protection disabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
#include <limits.h>
#include <stdint.h>

unsigned short RESULT; // ADC RESULT VARIABLE
__bit BIG_SW; // VARIABLE INDICATING STATE OF BIG_SWITCH CONTROLLING BIG PANEL
__bit SMALL_SW; // VARIABLE INDICATING STATE OF SMALL_SWITCH CONTROLING SMALL PANEL

int main(void)
{
    OSCFRQ=0b010; // OSCFRQ(HFFRQ0-2) SET OSCILLATOR TO 4MHz
   
    TRISAbits.TRISA0=0; // TRISA0(RA0) BIG LIGHT DRIVE, OUTPUT
    TRISAbits.TRISA1=0; // TRISA1(RA1) SMALL LIGHT DRIVE, OUTPUT
    TRISAbits.TRISA2=1; // TRISA2(RA2) ANALOG POT, INPUT
    TRISAbits.TRISA4=1; // TRISA4(RA4) BIG LIGHT SWITCH, INPUT
    TRISAbits.TRISA5=1; // TRISA5(RA5) SMALL LIGHT SWITCH, INPUT
    ANSELAbits.ANSA2=1; // ANSELA2(ANSA2) ANALOG POT, INPUT ANALOG
    CCP1PPSbits.CCP1PPS=0b00000; // BIG LIGHT DRIVER (PWM), OUTPUT
    CCP2PPSbits.CCP2PPS=0b00001; // SMALL LIGHT DRIVER (PWM), OUTPUT
   
    ADCON0bits.CHS=0b000010; // ANALOG CHANNEL SELECTION BITS (RA2)
    ADCON1bits.ADCS=0b111; // ADC COVERSION CLOCK SELECTION BITS (ADCRC)
    ADCON0bits.ADON=1; // ANALOG CHANNEL SELECTION BITS (ADCON HIGH)
    ADCON1bits.ADPREF=0b00; //ADC POSITIVE VOLTAGE REFRENCE CONFIGRATION bits (VREF+ IS VDD)
    ADCON1bits.ADFM=1; // ADC RESULT FORMAT SELECTION BITS (RIGHT JUSTIFIED)
   
    BIG_SW=PORTAbits.RA4; //READ RA4 AND ASSIGN IT TO BIG_SW
    SMALL_SW=PORTAbits.RA5; //READ RA5 AND ASSIGN IT TO SMALL_SW
   
    while(1)
    {
        ADCON0bits.GOnDONE=1; // ADC CONVERSION STATUS BITS
        while(ADCON0bits.GOnDONE==1); // WAIT WHILE ADC STATUS IS ON
        RESULT=0b0000000000; // CLEAR THE VARIABLE
        RESULT=ADRESH; // ADRESH IS IN THE LOWER 8 BITS
        RESULT=RESULT<<8; // ADRESH IS SHIFTED UP 8 BIT TO CORRECT LOCATION
        RESULT=RESULT|ADRESL; //ADRESL IS JOINTED TO THE RESULT VARIABLE
    }
   
    while(BIG_SW==1||SMALL_SW==1)
    {
        PMD1bits.TMR2MD=0b0; // TIMER2 MOUDLE ENABLED
       
        T2CLKCONbits.CS=0b0011; // TIMER2 CLOCK SOURCE SELECT BIT (HFINTOSC)
        CCP1CONbits.CCP1FMT=1; //CCPW PULSE WIDTH Alignment bit (RIGHT JUSTIFIED)
        CCP1CONbits.CCP1MODE=0b1111; // MODE IS SET TO PWM
       
    }
   
 
}


so TBH I am stuck trying to configure TIMER2 and CCP1 and 2 registers.

I am still a noobie who is figuring out how C standards and XC8 peculiarities tie together.

hopefully, I can implement low power mode using only a logical operand of BIG_SW and SMALL_SW for if neither one of them is high the low power mode is engaged.

as for the file this time I am only using a single main.c file without any config.h file or anything other files to keep it simple.

I would love to see your suggestions or good advice with regards to PWM situation 

thanks a lot.
 

Offline ali6x944Topic starter

  • Frequent Contributor
  • **
  • Posts: 577
  • Country: sa
Re: thoughts on my project
« Reply #1 on: January 09, 2020, 05:58:36 am »
how would the ccp module work?
 

Offline ali6x944Topic starter

  • Frequent Contributor
  • **
  • Posts: 577
  • Country: sa
Re: thoughts on my project
« Reply #2 on: January 12, 2020, 02:27:42 pm »
So here is what I cam up with for the weird ccp PWM module in the PIC16LF15313
Code: [Select]
/***************************************************************************************************************************
 *
 * Author:Ali6x944
 * Date: 8/1/2020
 * Device: PIC16LF15313
 * Description: A program designed to run on PIC16LF15313, that facilitates a single-chip
 * solution to controlling 2 LED Panels/Arrays using a single multi-position slider switch and a pot to control brightness.
 *   
 ***************************************************************************************************************************/
// PIC16LF15313 Configuration Bit Settings

// 'C' source line config statements

// CONFIG1
#pragma config FEXTOSC = OFF    // External Oscillator mode selection bits (Oscillator not enabled)
#pragma config RSTOSC = HFINT1  // Power-up default value for COSC bits (HFINTOSC (1MHz))
#pragma config CLKOUTEN = OFF   // Clock Out Enable bit (CLKOUT function is disabled; i/o or oscillator function on OSC2)
#pragma config CSWEN = OFF      // Clock Switch Enable bit (The NOSC and NDIV bits cannot be changed by user software)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (FSCM timer disabled)

// CONFIG2
#pragma config MCLRE = ON       // Master Clear Enable bit (MCLR pin is Master Clear function)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config LPBOREN = OFF    // Low-Power BOR enable bit (ULPBOR disabled)
#pragma config BOREN = OFF      // Brown-out reset enable bits (Brown-out reset disabled)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (VBOR) set to 1.9V on LF, and 2.45V on F Devices)
#pragma config ZCD = OFF        // Zero-cross detect disable (Zero-cross detect circuit is disabled at POR.)
#pragma config PPS1WAY = ON     // Peripheral Pin Select one-way control (The PPSLOCK bit can be cleared and set only once in software)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable bit (Stack Overflow or Underflow will cause a reset)

// CONFIG3
#pragma config WDTCPS = WDTCPS_31// WDT Period Select bits (Divider ratio 1:65536; software control of WDTPS)
#pragma config WDTE = OFF       // WDT operating mode (WDT Disabled, SWDTEN is ignored)
#pragma config WDTCWS = WDTCWS_7// WDT Window Select bits (window always open (100%); software control; keyed access not required)
#pragma config WDTCCS = SC      // WDT input clock selector (Software Control)

// CONFIG4
#pragma config BBSIZE = BB512   // Boot Block Size Selection bits (512 words boot block size)
#pragma config BBEN = OFF       // Boot Block Enable bit (Boot Block disabled)
#pragma config SAFEN = OFF      // SAF Enable bit (SAF disabled)
#pragma config WRTAPP = OFF     // Application Block Write Protection bit (Application Block not write protected)
#pragma config WRTB = OFF       // Boot Block Write Protection bit (Boot Block not write protected)
#pragma config WRTC = OFF       // Configuration Register Write Protection bit (Configuration Register not write protected)
#pragma config WRTSAF = OFF     // Storage Area Flash Write Protection bit (SAF not write protected)
#pragma config LVP = ON         // Low Voltage Programming Enable bit (Low Voltage programming enabled. MCLR/Vpp pin function is MCLR.)

// CONFIG5
#pragma config CP = OFF         // UserNVM Program memory code protection bit (UserNVM code protection disabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
#include <limits.h>
#include <stdint.h>

unsigned short RESULT; // ADC RESULT VARIABLE
__bit BIG_SW; // VARIABLE INDICATING STATE OF BIG_SWITCH CONTROLLING BIG PANEL
__bit SMALL_SW; // VARIABLE INDICATING STATE OF SMALL_SWITCH CONTROLING SMALL PANEL

int main(void)
{
    OSCFRQ=0b010; // OSCFRQ(HFFRQ0-2) SET OSCILLATOR TO 4MHz
   
    TRISAbits.TRISA0=0; // TRISA0(RA0) BIG LIGHT DRIVE, OUTPUT
    TRISAbits.TRISA1=0; // TRISA1(RA1) SMALL LIGHT DRIVE, OUTPUT
    TRISAbits.TRISA2=1; // TRISA2(RA2) ANALOG POT, INPUT
    TRISAbits.TRISA4=1; // TRISA4(RA4) BIG LIGHT SWITCH, INPUT
    TRISAbits.TRISA5=1; // TRISA5(RA5) SMALL LIGHT SWITCH, INPUT
    ANSELAbits.ANSA2=1; // ANSELA2(ANSA2) ANALOG POT, INPUT ANALOG
    CCP1PPSbits.CCP1PPS=0b00000; // BIG LIGHT DRIVER (PWM->RA4), OUTPUT
    CCP2PPSbits.CCP2PPS=0b00001; // SMALL LIGHT DRIVER (PWM->RA5), OUTPUT
   
    ADCON0bits.CHS=0b000010; // ANALOG CHANNEL SELECTION BITS (RA2)
    ADCON1bits.ADCS=0b111; // ADC COVERSION CLOCK SELECTION BITS (ADCRC)
    ADCON0bits.ADON=1; // ANALOG CHANNEL SELECTION BITS (ADCON HIGH)
    ADCON1bits.ADPREF=0b00; //ADC POSITIVE VOLTAGE REFRENCE CONFIGRATION bits (VREF+ IS VDD)
    ADCON1bits.ADFM=1; // ADC RESULT FORMAT SELECTION BITS (RIGHT JUSTIFIED)
   
    BIG_SW=PORTAbits.RA4; //READ RA4 AND ASSIGN IT TO BIG_SW
    SMALL_SW=PORTAbits.RA5; //READ RA5 AND ASSIGN IT TO SMALL_SW
   
    while(1)
    {
        ADCON0bits.GOnDONE=1; // ADC CONVERSION STATUS BITS
        while(ADCON0bits.GOnDONE==1); // WAIT WHILE ADC STATUS IS ON
        RESULT=0b0000000000; // CLEAR THE VARIABLE
        RESULT=ADRESH; // ADRESH IS IN THE LOWER 8 BITS
        RESULT=RESULT<<8; // ADRESH IS SHIFTED UP 8 BIT TO CORRECT LOCATION
        RESULT=RESULT|ADRESL; //ADRESL IS JOINTED TO THE RESULT VARIABLE
    }
   
    while(BIG_SW==1||SMALL_SW==1)
    {
        PMD1bits.TMR2MD=0b0; // TIMER2 MOUDLE ENABLED
        T2CONbits.CKPS=0b000; //TIMER2 PRESCALER SET TO 1:1
        T2CONbits.OUTPS=0b0000; //TIMER2 POST-SCALER SET TO 1:1
        T2PRbits.T2PR=0b01100011;  // PR2 REGESTER SET TO 99
        T2CLKCONbits.CS=0b0011; // TIMER2 CLOCK SOURCE SELECT BIT (HFINTOSC)
        if(BIG_SW==1)
        {
            CCP1CONbits.CCP1FMT=1; //CCPW PULSE WIDTH Alignment bit (RIGHT JUSTIFIED)
            CCP1CONbits.CCP1MODE=0b1111; // MODE IS SET TO PWM
            CCPR1Hbits.RH=RESULT&0b01;
            CCPR1Hbits.RH=RESULT&0b10;
            CCPR1Lbits.RL=RESULT<<8;
            T2CONbits.T2ON=0b1;
        }
        if(SMALL_SW==1)
        {
            CCP2CONbits.CCP2FMT=1; //CCPW PULSE WIDTH Alignment bit (RIGHT JUSTIFIED)
            CCP2CONbits.CCP2MODE=0b1111; // MODE IS SET TO PWM
            CCPR2Hbits.RH=RESULT&0b01;
            CCPR2Hbits.RH=RESULT&0b10;
            CCPR2Lbits.RL=RESULT<<8;
            T2CONbits.T2ON=0b1;
        }
    }
   
 
}

Any thoughts on it?
plz i need all the help i can get
[edit]
not sure of how those bitwise operations work  :-[
« Last Edit: January 12, 2020, 02:32:21 pm by ali6x944 »
 

Offline Prehistoricman

  • Regular Contributor
  • *
  • Posts: 216
  • Country: gb
Re: thoughts on my project
« Reply #3 on: January 12, 2020, 08:13:43 pm »
[edit]
not sure of how those bitwise operations work  :-[

What's the issue? You should be able to find a bunch of resources online regarding bitwise operations. Essentially, for registers, they will be setting or resetting particular bits to do a particular operation.

You're asking very general questions that probably most people don't know how to answer. If you have some specific issue related to a single operation (for example) then you're more likely to get an answer to question about it.
 
The following users thanked this post: ali6x944

Offline ali6x944Topic starter

  • Frequent Contributor
  • **
  • Posts: 577
  • Country: sa
Re: thoughts on my project
« Reply #4 on: January 15, 2020, 08:06:08 am »
[edit]
not sure of how those bitwise operations work  :-[

What's the issue? You should be able to find a bunch of resources online regarding bitwise operations. Essentially, for registers, they will be setting or resetting particular bits to do a particular operation.

You're asking very general questions that probably most people don't know how to answer. If you have some specific issue related to a single operation (for example) then you're more likely to get an answer to question about it.
sorry about that, I am kind of a huge noob in this regard so my questions may be quite general cus IDK what makes my programs fail -or work for that matter- :-//
however, there are 4 issues I am trying to solve:
1) configuration of pwm (ccp/timer2)
2) pps configuration ccp out
3)Adc configuration
4) program structure: loops inside main() vs. user-defined functions

this light dimmer controller is designed for video recording applications -so it has to be of high frequency- to avoid flickering.
I really don't have any issues with memory or ram usage so far, as I have most of the memory still vacant...
thx for all help and replys
 

Offline Prehistoricman

  • Regular Contributor
  • *
  • Posts: 216
  • Country: gb
Re: thoughts on my project
« Reply #5 on: January 15, 2020, 05:30:55 pm »
http://ww1.microchip.com/downloads/en/DeviceDoc/PIC16-L-F15313_23-Data-Sheet-40001897B.pdf

This is the data sheet for the PIC16LF15313. It contains info about all the registers you need to edit to configure those peripherals.
Section 14 is for IO. Section 29 PWM. Section 20 ADC.

You're still not asking specific questions. The idea behind helping people on a forum is that both sides need to contribute. Unless your task is trivial, nobody's going to solve it for you. And you need to help the helpers to help you.
You say you're stuck. Stuck trying to do what?!
 
The following users thanked this post: ali6x944

Offline ali6x944Topic starter

  • Frequent Contributor
  • **
  • Posts: 577
  • Country: sa
Re: thoughts on my project
« Reply #6 on: January 15, 2020, 07:39:59 pm »
@Prehistoricman, I am sorry if I was still vague :-[
so let's start with PWM, I was following a gr8 tutorial made by deep blue embedded about the subject:
https://deepbluembedded.com/pwm-pulse-width-modulation-tutorial/

and encountered a problem here as the ccp module in the pic16f877a has a separate slave register (CCPR1H) to load the duty cycle info from CCPR1L register with extra two bits from the CCP1CON register; while the pic16lf15313 has both registers stuck together in the diagram page.303, i am confused about if the ccpr1h is still a slave register or not, however, I have treated it as not after reading this in PWM configuration section page.304:
Quote
When TMR2 is equal to PR2, the following three events
occur on the next increment cycle:
• TMR2 is cleared
• The CCPx pin is set. (Exception: If the PWM duty
cycle = 0%, the pin will not be set.)
• The PWM duty cycle is transferred from the
CCPRxL/H register pair into a 10-bit buffer.
in this case, what exactly is the point of the FMT bit in CCP1CON if I can apparently write to both registers?
and can I treat them as one 16bit or one 8 and one 2-bit registers basically similar to the tutorial?
also, is there a more efficient way to load the value of the "RESULT" variable to both registers without doing any bitwise operations?
is a
Code: [Select]
#define _XTAL_FREQ
needed if I use an internal oscillator, or is setting OSCFRQ only more appropriate?
and for the oscillator, there is a bit to basically fine adjust the frequency OSCTUNE, do I have to declare it too or can I just leave it?
 

Offline Prehistoricman

  • Regular Contributor
  • *
  • Posts: 216
  • Country: gb
Re: thoughts on my project
« Reply #7 on: January 16, 2020, 02:52:35 am »
Great, that is much easier to answer.

@Prehistoricman, I am sorry if I was still vague :-[
so let's start with PWM, I was following a gr8 tutorial made by deep blue embedded about the subject:
https://deepbluembedded.com/pwm-pulse-width-modulation-tutorial/

and encountered a problem here as the ccp module in the pic16f877a has a separate slave register (CCPR1H) to load the duty cycle info from CCPR1L register with extra two bits from the CCP1CON register; while the pic16lf15313 has both registers stuck together in the diagram page.303, i am confused about if the ccpr1h is still a slave register or not, however, I have treated it as not after reading this in PWM configuration section page.304:
Quote
When TMR2 is equal to PR2, the following three events
occur on the next increment cycle:
• TMR2 is cleared
• The CCPx pin is set. (Exception: If the PWM duty
cycle = 0%, the pin will not be set.)
• The PWM duty cycle is transferred from the
CCPRxL/H register pair into a 10-bit buffer.
in this case, what exactly is the point of the FMT bit in CCP1CON if I can apparently write to both registers?
CCPR1H is not a slave register. I think the registers in the newer chip make a lot more sense. The CCPR1 H/L act as normal high/low registers stuck together to form a 16-bit word. The FMT value selects if the upper 10 bits or the lower 10 bits of that word are used in the comparison with the timer (this feature is a bit odd if you ask me).


Quote
and can I treat them as one 16bit or one 8 and one 2-bit registers basically similar to the tutorial?
You may be able to treat it as one register if your C library supports it. The name would probably be CCPR1.
Alternatively, yes, use both the high and low to set your 10-bit value.


also, is there a more efficient way to load the value of the "RESULT" variable to both registers without doing any bitwise operations?
is a
Code: [Select]
#define _XTAL_FREQ
needed if I use an internal oscillator, or is setting OSCFRQ only more appropriate?
and for the oscillator, there is a bit to basically fine adjust the frequency OSCTUNE, do I have to declare it too or can I just leave it?
RESULT is an unsigned short, which I think means a byte. I would advise not to use old C types but rather stdint types like uint8_t, int32_t, etc. as these are more explicit and readable. At the place I work, we run an automated tool that highlights use of built-in types as a problem.
I don't entirely understand you question about _XTAL_FREQ and OSCFRQ. If you want to set the PWM to be at a specific frequency, then you must know the clock frequency as well so you can properly calculate the number of cycles needed. If you're using the internal oscillator, then yes, set OSCFRQ and you can then base your later calculations off of whatever frequency you chose.
You may leave OSCTUNE.

Offline ali6x944Topic starter

  • Frequent Contributor
  • **
  • Posts: 577
  • Country: sa
Re: thoughts on my project
« Reply #8 on: January 16, 2020, 12:33:31 pm »
that is interesting, so in the uint16_t  would be the most suitable for the "RESULT" var, is there any possibility for uint10_t or some other unsigned 10-bit datatype in XC8?
Code: [Select]
uint16_t RESULT; // ADC RESULT VARIABLE
.
.
.
if(BIG_SW==1)
        {
            CCP1CONbits.CCP1FMT=1; //CCPW PULSE WIDTH Alignment bit (RIGHT JUSTIFIED)
            CCP1CONbits.CCP1MODE=0b1111; // MODE IS SET TO PWM
            CCPR1=RESULT;
            PIR4bits.TMR2IF=0b0;
            T2CONbits.T2ON=0b1;
        }

So this is how it will be implemented, right? from my understanding, it will be fully loaded by the variable, but will the extra 6 just be ignored with a right-justified RESULT var?
now do I need to configure the LAT register for the PWM out?
for the ADC setup, I think the only question that comes to mind is ADFM bit of the ADCON1 register is manipulating it necessary when I am loading the result?
Code: [Select]
ADCON0bits.CHS=0b000010; // ANALOG CHANNEL SELECTION BITS (RA2)
    ADCON1bits.ADCS=0b111; // ADC COVERSION CLOCK SELECTION BITS (ADCRC)
    ADCON0bits.ADON=1; // ANALOG CHANNEL SELECTION BITS (ADCON HIGH)
    ADCON1bits.ADPREF=0b00; //ADC POSITIVE VOLTAGE REFRENCE CONFIGRATION bits (VREF+ IS VDD)
    ADCON1bits.ADFM=1; // ADC RESULT FORMAT SELECTION BITS (RIGHT JUSTIFIED)
    .
    .
    .
    while(1)
    {
        ADCON0bits.GOnDONE=1; // ADC CONVERSION STATUS BITS
        while(ADCON0bits.GOnDONE==1); // WAIT WHILE ADC STATUS IS ON
        RESULT=0b0000000000; // CLEAR THE VARIABLE
        RESULT=ADRESH; // ADRESH IS IN THE LOWER 8 BITS
        RESULT=RESULT<<8; // ADRESH IS SHIFTED UP 8 BIT TO CORRECT LOCATION
        RESULT=RESULT|ADRESL; //ADRESL IS JOINTED TO THE RESULT VARIABLE
    }
 

 

 

Offline Prehistoricman

  • Regular Contributor
  • *
  • Posts: 216
  • Country: gb
Re: thoughts on my project
« Reply #9 on: January 16, 2020, 01:06:45 pm »
I'm saying there is a chance your library supports this 16-bit combined register CCPR1. Just try it! I don't know anything about it. You could also read the header files where these names are defined.
If you're using a proper IDE, you can follow names to where they are defined, so this is very helpful.

No, you don't get 10-bit data types.
Your DAC is 10-bit so you will have to use a 16-bit uint.

Can you expand on your question about the LAT register? I can't find it in the datasheet.

ADFM basically does the same thing as the FMT bit. Just as with FMT, I would set it and leave it (in setup code, not the loop).

Code: [Select]
RESULT=0b0000000000; // CLEAR THE VARIABLE
RESULT=ADRESH; // ADRESH IS IN THE LOWER 8 BITS
RESULT=RESULT<<8; // ADRESH IS SHIFTED UP 8 BIT TO CORRECT LOCATION
RESULT=RESULT|ADRESL; //ADRESL IS JOINTED TO THE RESULT VARIABLE

This code is not great. You don't have to clear RESULT before loading it with anything else. You should also make use of C's assignment operators. I would write this on one or two lines, as such:

Code: [Select]
RESULT = ADRESH << 8 | ADRESL; // Load ADC value

RESULT = ADRESH << 8; //Load ADC high value
RESULT |= ADRESL; //Load ADC low value
 
The following users thanked this post: ali6x944

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9964
  • Country: us
Re: thoughts on my project
« Reply #10 on: January 18, 2020, 10:07:50 pm »
Given that you never exit the while(1) loop, how do you expect to get to the  while(BIG_SW==1||SMALL_SW==1) loop?
 
The following users thanked this post: ali6x944

Offline ali6x944Topic starter

  • Frequent Contributor
  • **
  • Posts: 577
  • Country: sa
Re: thoughts on my project
« Reply #11 on: January 21, 2020, 03:45:15 pm »
Given that you never exit the while(1) loop, how do you expect to get to the  while(BIG_SW==1||SMALL_SW==1) loop?

can't the PIC run both loops? if not, what is the best way to exit the loop yet periodically read the pot ANSA2?

I'm saying there is a chance your library supports this 16-bit combined register CCPR1. Just try it! I don't know anything about it. You could also read the header files where these names are defined.
If you're using a proper IDE, you can follow names to where they are defined, so this is very helpful.

cool, I'm using MPLABX IDE, XC8 (2.00V), so if a word turns blue it is supported, right?
I searched about the definition in the project files and I came empty-handed, I think I'm missing something as usual |O 

Can you expand on your question about the LAT register? I can't find it in the datasheet.
ADFM basically does the same thing as the FMT bit. Just as with FMT, I would set it and leave it (in setup code, not the loop).
and with regards to LATx register, my question was:
do I need to configure the LATx register to get pwm out of the CCPx register? or is not need as the ccp_out pps is enough?
 

Offline Prehistoricman

  • Regular Contributor
  • *
  • Posts: 216
  • Country: gb
Re: thoughts on my project
« Reply #12 on: January 21, 2020, 11:42:48 pm »
Given that you never exit the while(1) loop, how do you expect to get to the  while(BIG_SW==1||SMALL_SW==1) loop?

can't the PIC run both loops? if not, what is the best way to exit the loop yet periodically read the pot ANSA2?
Haha... good joke.
I guess you have little programming experience. The fundamental idea behind C code is that it goes from top to bottom in order of execution. You have no defined exit to that first loop so the 2nd one will never get reached. Even if you did reach the second loop, you never update BIG_SW or SMALL_SW and you would probably fall out of main(). A good practice is to have an empty infinite loop at the end of main() so you will never ever return from main().
You need to have a think about how the processor will run the code you've written, and how you should rewrite it to function as you wish.


I'm saying there is a chance your library supports this 16-bit combined register CCPR1. Just try it! I don't know anything about it. You could also read the header files where these names are defined.
If you're using a proper IDE, you can follow names to where they are defined, so this is very helpful.

cool, I'm using MPLABX IDE, XC8 (2.00V), so if a word turns blue it is supported, right?
I searched about the definition in the project files and I came empty-handed, I think I'm missing something as usual |O 
I don't know how MPLABX functions. Again, just try it. The answers to these questions should become apparent just by pressing buttons and figuring out how the IDE works. You can always just build the project and see what fails (bad practice but it works).


Can you expand on your question about the LAT register? I can't find it in the datasheet.
ADFM basically does the same thing as the FMT bit. Just as with FMT, I would set it and leave it (in setup code, not the loop).
and with regards to LATx register, my question was:
do I need to configure the LATx register to get pwm out of the CCPx register? or is not need as the ccp_out pps is enough?
I don't see LATx configuring in the PWM section so yeah I assume that is not necessary. LATx is just the output data and if you're using a peripheral, there's no need to set this because it's bypassed.
You do however need to set the RxyPPS register as it says on page 314.
 
The following users thanked this post: ali6x944

Offline ali6x944Topic starter

  • Frequent Contributor
  • **
  • Posts: 577
  • Country: sa
Re: thoughts on my project
« Reply #13 on: March 12, 2020, 05:35:38 am »
hi again,
so I tried to make adc_result into a function but it seems not to work, the error messages seem confusing to me...
Code: [Select]
uint16_t RESULT; // ADC RESULT VARIABLE
__bit BIG_SW; // VARIABLE INDICATING STATE OF BIG_SWITCH CONTROLLING BIG PANEL
__bit SMALL_SW; // VARIABLE INDICATING STATE OF SMALL_SWITCH CONTROLING SMALL PANEL
void ADC_RESULT(uint16_t RESULT)
    {
        ADCON0bits.GOnDONE=1; // ADC CONVERSION STATUS BITS
        while(ADCON0bits.GOnDONE==1); // WAIT WHILE ADC STATUS IS ON
        RESULT = ADRESH << 8; //Load ADC high value
        RESULT |= ADRESL; //Load ADC low value
        return RESULT;
    }
int main(void)
{
    OSCFRQ=0b010; // OSCFRQ(HFFRQ0-2) SET OSCILLATOR TO 4MHz
   
    TRISAbits.TRISA0=0; // TRISA0(RA0) BIG LIGHT DRIVE, OUTPUT
    TRISAbits.TRISA1=0; // TRISA1(RA1) SMALL LIGHT DRIVE, OUTPUT
    TRISAbits.TRISA2=1; // TRISA2(RA2) ANALOG POT, INPUT
    TRISAbits.TRISA4=1; // TRISA4(RA4) BIG LIGHT SWITCH, INPUT
    TRISAbits.TRISA5=1; // TRISA5(RA5) SMALL LIGHT SWITCH, INPUT
    ANSELAbits.ANSA2=1; // ANSELA2(ANSA2) ANALOG POT, INPUT ANALOG
    CCP1PPSbits.CCP1PPS=0b00000; // BIG LIGHT DRIVER (PWM->RA4), OUTPUT
    CCP2PPSbits.CCP2PPS=0b00001; // SMALL LIGHT DRIVER (PWM->RA5), OUTPUT
   
    ADCON0bits.CHS=0b000010; // ANALOG CHANNEL SELECTION BITS (RA2)
    ADCON1bits.ADCS=0b111; // ADC COVERSION CLOCK SELECTION BITS (ADCRC)
    ADCON0bits.ADON=1; // ANALOG CHANNEL SELECTION BITS (ADCON HIGH)
    ADCON1bits.ADPREF=0b00; //ADC POSITIVE VOLTAGE REFRENCE CONFIGRATION bits (VREF+ IS VDD)
    ADCON1bits.ADFM=1; // ADC RESULT FORMAT SELECTION BITS (RIGHT JUSTIFIED)
   
    BIG_SW=PORTAbits.RA4; //READ RA4 AND ASSIGN IT TO BIG_SW
    SMALL_SW=PORTAbits.RA5; //READ RA5 AND ASSIGN IT TO SMALL_SW
   
   
   
    while(BIG_SW==1||SMALL_SW==1)
    {
        PMD1bits.TMR2MD=0b0; // TIMER2 MOUDLE ENABLED
        T2CONbits.CKPS=0b000; //TIMER2 PRESCALER SET TO 1:1
        T2CONbits.OUTPS=0b0000; //TIMER2 POST-SCALER SET TO 1:1
        T2PRbits.T2PR=0b01100011;  // PR2 REGESTER SET TO 99
        T2CLKCONbits.CS=0b0011; // TIMER2 CLOCK SOURCE SELECT BIT (HFINTOSC)
       
        CCP1CONbits.CCP1FMT=1; //CCPW PULSE WIDTH Alignment bit (RIGHT JUSTIFIED)
        CCP1CONbits.CCP1MODE=0b1111; // MODE IS SET TO PWM
        CCP2CONbits.CCP2FMT=1; //CCPW PULSE WIDTH Alignment bit (RIGHT JUSTIFIED)
        CCP2CONbits.CCP2MODE=0b1111; // MODE IS SET TO PWM
       
        if(BIG_SW==1)
        {
            ADC_RESULT();
            CCPR1=RESULT;
            PIR4bits.TMR2IF=0b0;
            T2CONbits.T2ON=0b1;
        }
        if(SMALL_SW==1)
        {
            ADC_RESULT();
            CCPR2=RESULT;
            PIR4bits.TMR2IF=0b0;
            T2CONbits.T2ON=0b1;
        }
    }
   
 
}
and the error messages were:
Code: [Select]
main.c:65:9: error: void function 'ADC_RESULT' should not return a value [-Wreturn-type]
        return RESULT;
        ^      ~~~~~~
main.c:106:24: error: too few arguments to function call, single argument 'RESULT' was not specified
            ADC_RESULT();
            ~~~~~~~~~~ ^
main.c:59:1: note: 'ADC_RESULT' declared here
void ADC_RESULT(uint16_t RESULT)
^
main.c:113:24: error: too few arguments to function call, single argument 'RESULT' was not specified
            ADC_RESULT();
            ~~~~~~~~~~ ^
main.c:59:1: note: 'ADC_RESULT' declared here
void ADC_RESULT(uint16_t RESULT)
^
3 errors generated.


BUILD FAILED (exit value 2, total time: 1s)
so I tried to fix it by removing the return RESULT, and the uint16_t RESULT from inside void ADC_RESULT(uint16_t RESULT)...
Code: [Select]
CLEAN SUCCESSFUL (total time: 1ms)
main.c:120:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
1 warning generated.
   
Memory Summary:
    Program space        used    88h (   136) of   800h words   (  6.6%)
    Data space           used     8h (     8) of   100h bytes   (  3.1%)
    EEPROM space         None available
    Data stack space     used     0h (     0) of    F0h bytes   (  0.0%)
    Configuration bits   used     5h (     5) of     5h words   (100.0%)
    ID Location space    used     0h (     0) of     4h bytes   (  0.0%)

BUILD SUCCESSFUL (total time: 2s)
Loading completed
however not really sure how to get rid of the 120:1: warning and not really sure what it does...
now is it necessary with my current code set up to do the same with the PWM ccp code sections?
also with this new ADC_result function, will the micro keep looping it when it enters either the if(SMALL_SW==1) or if(BIG_SW==1)?
 

Offline Prehistoricman

  • Regular Contributor
  • *
  • Posts: 216
  • Country: gb
Re: thoughts on my project
« Reply #14 on: March 12, 2020, 12:02:11 pm »
Functions always specify a result type before the function name. If it's any type except for void, that means the function returns a value. Functions that do return must have a return statement. Functions that don't return must not have a return statement.

In the way you've set up your ADC_RESULT function, you shouldn't return. You're using a global variable RESULT to store the ADC_RESULT rather than a return value and return statement.
You've also incorrectly set up ADC_RESULT to accept an argument called RESULT. You can remove that. That's why your calls to ADC_RESULT are causing errors.

Again, you don't want to ever leave main(). Your while loop will end if BIG_SW and SMALL_SW are not 1. The function will attempt to return to god knows where and if you're lucky, the microcontroller will reset.
And again, you're not updating BIG_SW or SMALL_SW. You only read from the GPIO port once.

So, my suggested changes are:
Remove the condition from the while loop and change it to while (true) or while (1). This is known as an infinite loop.
Inside the loop, read the button values into BIG_SW and SMALL_SW.
Think about all the register operations you have in the loop there. Do you need to run these all the time?
 
The following users thanked this post: ali6x944

Offline ali6x944Topic starter

  • Frequent Contributor
  • **
  • Posts: 577
  • Country: sa
Re: thoughts on my project
« Reply #15 on: March 12, 2020, 08:55:12 pm »
Functions always specify a result type before the function name. If it's any type except for void, that means the function returns a value. Functions that do return must have a return statement. Functions that don't return must not have a return statement.

In the way you've set up your ADC_RESULT function, you shouldn't return. You're using a global variable RESULT to store the ADC_RESULT rather than a return value and return statement.
You've also incorrectly set up ADC_RESULT to accept an argument called RESULT. You can remove that. That's why your calls to ADC_RESULT are causing errors.
ok cool, so the function ADC_RESULT will become:
Code: [Select]
uint16_t ADC_RESULT()
    {
        ADCON0bits.GOnDONE=1; // ADC CONVERSION STATUS BITS
        while(ADCON0bits.GOnDONE==1); // WAIT WHILE ADC STATUS IS ON
        RESULT = ADRESH << 8; //Load ADC high value
        RESULT |= ADRESL; //Load ADC low value
    }
main()
{
.
.
.
}
Again, you don't want to ever leave main(). Your while loop will end if BIG_SW and SMALL_SW are not 1. The function will attempt to return to god knows where and if you're lucky, the microcontroller will reset.
And again, you're not updating BIG_SW or SMALL_SW. You only read from the GPIO port once.
for the updating of BIG_SW and SMALL_SW value, how can I do it without interrupting the PWM and ADC read cycle?
I was planing the for the addition of a sleep condition in the loop were if neither BIG_SW and SMALL_SW==1 then the micro goes to sleep.
 
So, my suggested changes are:
Remove the condition from the while loop and change it to while (true) or while (1). This is known as an infinite loop.
Inside the loop, read the button values into BIG_SW and SMALL_SW.
Think about all the register operations you have in the loop there. Do you need to run these all the time?
for the run time I would say the ADC AND TMR2 CCP1 are the only things that should run all the time.
I am trying to figure out if the sleep condition gonna screw up with something...
 

Offline Prehistoricman

  • Regular Contributor
  • *
  • Posts: 216
  • Country: gb
Re: thoughts on my project
« Reply #16 on: March 12, 2020, 10:16:31 pm »
ok cool, so the function ADC_RESULT will become:
Code: [Select]
uint16_t ADC_RESULT()
    {
        ADCON0bits.GOnDONE=1; // ADC CONVERSION STATUS BITS
        while(ADCON0bits.GOnDONE==1); // WAIT WHILE ADC STATUS IS ON
        RESULT = ADRESH << 8; //Load ADC high value
        RESULT |= ADRESL; //Load ADC low value
    }
main()
{
.
.
.
}

Almost. Change the return type from uint16_t to void. This means the function does not return a value.

for the updating of BIG_SW and SMALL_SW value, how can I do it without interrupting the PWM and ADC read cycle?
I was planing the for the addition of a sleep condition in the loop were if neither BIG_SW and SMALL_SW==1 then the micro goes to sleep.
Reading two bits from IO is hardly interrupting. What do you think the problem might be? The PWM module should continue doing its thing regardless of how long ADC readout or IO polling might take.

If you want to move to dealing with sleep, there's a couple of things to consider:
Pressing the buttons should wake the microcontroller (right?), so they need to be interrupt-driven, and the IO needs to be set up to deliver interrupts.
Does the PWM module operate in sleep mode? Some chips have multiple levels of sleep.
 
The following users thanked this post: ali6x944

Offline ali6x944Topic starter

  • Frequent Contributor
  • **
  • Posts: 577
  • Country: sa
Re: thoughts on my project
« Reply #17 on: March 14, 2020, 08:19:31 am »
If you want to move to dealing with sleep, there's a couple of things to consider:
Pressing the buttons should wake the microcontroller (right?), so they need to be interrupt-driven, and the IO needs to be set up to deliver interrupts.
Does the PWM module operate in sleep mode? Some chips have multiple levels of sleep.
well, hopefully, it will wake up if the state of the SMALL/BIG_SW changes or if the value of RESULT variable changes? not sure if this is possible??
after a bit of reading thou I think going for a combination of doze mode during operation and idle mode in the off condition is a good idea:
Quote
11.1 DOZE Mode
DOZE mode allows for power saving by reducing CPU
operation and program memory (PFM) access, without
affecting peripheral operation. DOZE mode differs from
Sleep mode because the system oscillators continue to
operate, while only the CPU and PFM are affected. The
reduced execution saves power by eliminating
unnecessary operations within the CPU and memory.
When the Doze Enable (DOZEN) bit is set (DOZEN =
1), the CPU executes only one instruction cycle out of
every N cycles as defined by the DOZE<2:0> bits of the
CPUDOZE register. For example, if DOZE<2:0> = 100,
the instruction cycle ratio is 1:32. The CPU and
memory execute for one instruction cycle and then lay
idle for 31 instruction cycles. During the unused cycles,
the peripherals continue to operate at the system clock
speed
11.3 IDLE Mode
When the Idle Enable (IDLEN) bit is clear (IDLEN = 0),
the SLEEP instruction will put the device into full Sleep
mode (see Section 11.2 “Sleep Mode”). When IDLEN
is set (IDLEN = 1), the SLEEP instruction will put the
device into IDLE mode. In IDLE mode, the CPU and
memory operations are halted, but the peripheral
clocks continue to run. This mode is similar to DOZE
mode, except that in IDLE both the CPU and PFM are
shut off.
for one I will get a lower power consumption during operation and power-down, and relatively easy wake-up code -I think-.
the questions become how can I implement them in the loop?
I was thinking of something like this:
Code: [Select]
.
.
.
int main()
{
.
.
.
[the doze mode setup]
while(BIG_SW==1||SMALL_SW==1)
{
.
.
.
}
if (BIG_SW!=1&&SMALL_SW!=1)
{
[sleep mode setup]
}
}

 

Offline Prehistoricman

  • Regular Contributor
  • *
  • Posts: 216
  • Country: gb
Re: thoughts on my project
« Reply #18 on: March 14, 2020, 12:41:52 pm »
well, hopefully, it will wake up if the state of the SMALL/BIG_SW changes or if the value of RESULT variable changes? not sure if this is possible??
Not really. Sleep generally halts or resets the CPU. You have no variables, code execution, whatever. You won't be able to initiate ADC reads at all.
This doze mode is interesting though. It basically slows down the CPU. Probably doesn't save a lot of power compared to idle/sleep.

for one I will get a lower power consumption during operation and power-down, and relatively easy wake-up code -I think-.
the questions become how can I implement them in the loop?
I was thinking of something like this:
Code: [Select]
.
.
.
int main()
{
.
.
.
[the doze mode setup]
while(BIG_SW==1||SMALL_SW==1)
{
.
.
.
}
if (BIG_SW!=1&&SMALL_SW!=1)
{
[sleep mode setup]
}
}

That could work. You can move the sleep stuff to be after the loop. You drop out of the loop when neither button is pressed, then go to sleep.
Make sure you have the interrupts for wake-up set up on your two button GPIOs.
You should always (again) make sure that main() ends with an infinite loop. So after initialising sleep, loop forever.
 
The following users thanked this post: ali6x944

Offline ali6x944Topic starter

  • Frequent Contributor
  • **
  • Posts: 577
  • Country: sa
Re: thoughts on my project
« Reply #19 on: March 14, 2020, 03:11:32 pm »
That could work. You can move the sleep stuff to be after the loop. You drop out of the loop when neither button is pressed, then go to sleep.
Make sure you have the interrupts for wake-up set up on your two button GPIOs.
You should always (again) make sure that main() ends with an infinite loop. So after initialising sleep, loop forever.
well, can I implement that by a simple While(1) loop which the while(BIG_SW==1||SMALL_SW==1) and an if statement where the sleep instruction is placed?
and for the interrupts, I really don't know how to set up those :-[ ; but here I go so bear with me:
Quote
10.3 Interrupts During Sleep
Interrupts can be used to wake from Sleep. To wake
from Sleep, the peripheral must be able to operate
without the system clock. The interrupt source must
have the appropriate Interrupt Enable bit(s) set prior to
entering Sleep.
On waking from Sleep, if the GIE bit is also set, the
processor will branch to the interrupt vector. Otherwise,
the processor will continue executing instructions after
the SLEEP instruction. The instruction directly after the
SLEEP instruction will always be executed before
branching to the ISR. Refer to Section 11.0 “Power-
Saving Operation Modes” for more details.
so according to this, the peripheral used to wake up the CPU must be able to operate without the system clock, and here we will be using BIG/SMALL_SW as our interrupt source, the question is how many external interrupt pins do I have? here I found two different things in the datasheet, a External interrupt input and Interrupt-on-change input both can wake up the cpu from sleep...
so I looked up this IOC thingy and came up with this:
Quote
17.0 INTERRUPT-ON-CHANGE
An interrupt can be generated by detecting a signal that
has either a rising edge or a falling edge. Any individual
pin, or combination of pins, can be configured to
generate an interrupt. The interrupt-on-change module
has the following features:
• Interrupt-on-Change enable (Master Switch)
• Individual pin configuration
• Rising and falling edge detection
• Individual pin interrupt flags
Figure 17-1 is a block diagram of the IOC module.
so this looks more promising, so I have to set the ioc and IOCIE bit of the PIE0 registers for both RA4 and  RA5 which is my BIG/SMALL_SW pins to falling edge trigger...
So this is what I came with, notice I did not include the idle setup yet:
Code: [Select]
int main(void)
{
    OSCFRQ=0b010; // OSCFRQ(HFFRQ0-2) SET OSCILLATOR TO 4MHz
   
    TRISAbits.TRISA0=0; // TRISA0(RA0) BIG LIGHT DRIVE, OUTPUT
    TRISAbits.TRISA1=0; // TRISA1(RA1) SMALL LIGHT DRIVE, OUTPUT
    TRISAbits.TRISA2=1; // TRISA2(RA2) ANALOG POT, INPUT
    TRISAbits.TRISA4=1; // TRISA4(RA4) BIG LIGHT SWITCH, INPUT
    TRISAbits.TRISA5=1; // TRISA5(RA5) SMALL LIGHT SWITCH, INPUT
    ANSELAbits.ANSA2=1; // ANSELA2(ANSA2) ANALOG POT, INPUT ANALOG
    CCP1PPSbits.CCP1PPS=0b00000; // BIG LIGHT DRIVER (PWM->RA4), OUTPUT
    CCP2PPSbits.CCP2PPS=0b00001; // SMALL LIGHT DRIVER (PWM->RA5), OUTPUT
   
    ADCON0bits.CHS=0b000010; // ANALOG CHANNEL SELECTION BITS (RA2)
    ADCON1bits.ADCS=0b111; // ADC COVERSION CLOCK SELECTION BITS (ADCRC)
    ADCON0bits.ADON=1; // ANALOG CHANNEL SELECTION BITS (ADCON HIGH)
    ADCON1bits.ADPREF=0b00; //ADC POSITIVE VOLTAGE REFRENCE CONFIGRATION bits (VREF+ IS VDD)
    ADCON1bits.ADFM=1; // ADC RESULT FORMAT SELECTION BITS (RIGHT JUSTIFIED)
   
    BIG_SW=PORTAbits.RA4; //READ RA4 AND ASSIGN IT TO BIG_SW
    SMALL_SW=PORTAbits.RA5; //READ RA5 AND ASSIGN IT TO SMALL_SW
   
    PIE0bits.IOCIE=1;//INTERUPT-ON-CHANGE ENABLE BIT IS SET
    IOCANbits.IOCAN4=1;//INTERUPT-ON-CHANGE PORTA (RA4) NEGATIVE EDGE TRIGGERED
    IOCANbits.IOCAN5=1;//INTERUPT-ON-CHANGE PORTA (RA5) NEGATIVE EDGE TRIGGERED
   
    while(1)
    {
        while(BIG_SW==1||SMALL_SW==1)
        {
        PMD1bits.TMR2MD=0b0; // TIMER2 MOUDLE ENABLED
        T2CONbits.CKPS=0b000; //TIMER2 PRESCALER SET TO 1:1
        T2CONbits.OUTPS=0b0000; //TIMER2 POST-SCALER SET TO 1:1
        T2PRbits.T2PR=0b01100011;  // PR2 REGESTER SET TO 99
        T2CLKCONbits.CS=0b0011; // TIMER2 CLOCK SOURCE SELECT BIT (HFINTOSC)
       
        CCP1CONbits.CCP1FMT=1; //CCPW PULSE WIDTH Alignment bit (RIGHT JUSTIFIED)
        CCP1CONbits.CCP1MODE=0b1111; // MODE IS SET TO PWM
        CCP2CONbits.CCP2FMT=1; //CCPW PULSE WIDTH Alignment bit (RIGHT JUSTIFIED)
        CCP2CONbits.CCP2MODE=0b1111; // MODE IS SET TO PWM
       
        if(BIG_SW==1)
        {
            ADC_RESULT();
            CCPR1=RESULT;
            PIR4bits.TMR2IF=0b0;
            T2CONbits.T2ON=0b1;
        }
       
        if(SMALL_SW==1)
        {
            ADC_RESULT();
            CCPR2=RESULT;
            PIR4bits.TMR2IF=0b0;
            T2CONbits.T2ON=0b1;
        }
       
        }
        if (BIG_SW==0&&SMALL_SW==0)
        {
            SLEEP;
        }
   
   
    }
   
   
   
 
}
the sleep thou gave me an error:
Code: [Select]
main.c:130:13: error: use of undeclared identifier 'SLEEP'
 

Offline Prehistoricman

  • Regular Contributor
  • *
  • Posts: 216
  • Country: gb
Re: thoughts on my project
« Reply #20 on: March 14, 2020, 07:03:33 pm »
Is the instruction called sleep? If so, you can write it in inline assembly:

asm volatile("sleep")
 
The following users thanked this post: ali6x944

Offline ali6x944Topic starter

  • Frequent Contributor
  • **
  • Posts: 577
  • Country: sa
Re: thoughts on my project
« Reply #21 on: March 14, 2020, 07:07:39 pm »
it gave me another error:
Code: [Select]
main.c:130:13: error: use of undeclared identifier 'asm'
 

Offline Prehistoricman

  • Regular Contributor
  • *
  • Posts: 216
  • Country: gb
Re: thoughts on my project
« Reply #22 on: March 14, 2020, 07:58:32 pm »
Google says try to use __asm__ instead
 
The following users thanked this post: ali6x944

Offline ali6x944Topic starter

  • Frequent Contributor
  • **
  • Posts: 577
  • Country: sa
Re: thoughts on my project
« Reply #23 on: March 15, 2020, 05:49:36 am »
Google says try to use __asm__ instead
that works  :D
but will it wake up if the IOC flag is set? or does it need a special interrupt routine/function?
and for the doze mode will the reduction in cpu speed effect the RESULT update in the ccp register?
 

Offline Prehistoricman

  • Regular Contributor
  • *
  • Posts: 216
  • Country: gb
Re: thoughts on my project
« Reply #24 on: March 15, 2020, 01:06:51 pm »
but will it wake up if the IOC flag is set? or does it need a special interrupt routine/function?
and for the doze mode will the reduction in cpu speed effect the RESULT update in the ccp register?
Generally the CPU wakes up on interrupt. So interrupt on change should make wake on change. Just try it dude!
I don't see why CPU speed would affect any of the peripherals. The peripherals still run on the fast clock and they should operate as normal.
 
The following users thanked this post: ali6x944


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf