Electronics > Projects, Designs, and Technical Stuff
thoughts on my project
ali6x944:
it didn't work at all |O
IDK WTF is going on...
maybe I messed something up in my ccp register code or it is not leaving sleep
--- Code: ---/***************************************************************************************************************************
*
* 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>
/*VARIABLE DEFFENITION SECTION*/
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
/*FUNCTION INTITILIZATION SECTION*/
void 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 LOOP*/
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)
{
__asm__("SLEEP");
}
}
}
--- End code ---
Edit:
I just removed the sleep section and it does not seem to work...
this is the part that I removed:
--- Code: ---if (BIG_SW==0&&SMALL_SW==0)
{
__asm__("SLEEP");
}
--- End code ---
Prehistoricman:
Are you sure you ever enter sleep?
I keep telling you that you aren't updating the BIG_SW and SMALL_SW variables, but you aren't making any changes. Why?!
I suggest you get your code working, forgetting about sleep (because your LED panels will consume far more power than the microcontroller). Work up from something that works.
If you want to fix sleep, here's some ideas:
You might need an interrupt handler for the interrupts you just enabled. With nothing to reset the interrupt request, the micro will not trigger additional interrupts.
Blink an LED while the CPU is active. It will stop blinking when it goes to sleep.
ali6x944:
--- Quote from: Prehistoricman on March 15, 2020, 03:38:34 pm ---Are you sure you ever enter sleep?
I keep telling you that you aren't updating the BIG_SW and SMALL_SW variables, but you aren't making any changes. Why?!
I suggest you get your code working, forgetting about sleep (because your LED panels will consume far more power than the microcontroller). Work up from something that works.
--- End quote ---
cool, so how do I do that? I mean the BIG_SW and SMALL_SW variables continues update
Prehistoricman:
Well you already update them once:
--- Code: ---BIG_SW=PORTAbits.RA4; //READ RA4 AND ASSIGN IT TO BIG_SW
SMALL_SW=PORTAbits.RA5; //READ RA5 AND ASSIGN IT TO SMALL_SW
--- End code ---
So just run this inside the main loop.
Your comments kind of highlights the misunderstanding. It's not 'assigned'. The value of the pins is read and that value is put into the variable.
Consider this example:
x = 2
y = x
x = 3
What is y?
In normal languages, it will be 2. The assignment of x to y means "the value of x is copied to y". If you only run the copy once, you get one copy.
ali6x944:
ok so I think I did what u meant, and it didn't work, so I overdid it for good measure and it didn't work |O
--- Code: ---/*MAIN LOOP*/
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)
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)
{
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)
{
BIG_SW=PORTAbits.RA4; //READ RA4 AND ASSIGN IT TO BIG_SW
SMALL_SW=PORTAbits.RA5; //READ RA5 AND ASSIGN IT TO SMALL_SW
ADC_RESULT();
CCPR1=RESULT;
PIR4bits.TMR2IF=0b0;
T2CONbits.T2ON=0b1;
}
if(SMALL_SW==1)
{
BIG_SW=PORTAbits.RA4; //READ RA4 AND ASSIGN IT TO BIG_SW
SMALL_SW=PORTAbits.RA5; //READ RA5 AND ASSIGN IT TO SMALL_SW
ADC_RESULT();
CCPR2=RESULT;
PIR4bits.TMR2IF=0b0;
T2CONbits.T2ON=0b1;
}
}
}
}
--- End code ---
I tried all combinations of the main loop and the subloops but it didn't work, I even got a new chip just to check I am not crazy and it doesn't seem to work :-//
just as a form of sanity check, I went and removed the ccp and ADC stuff and just used the LATx register to output a high if its corresponding switch is high and it still didn't work :horse:
so just to check that my chip isn't dead or something, I got a new one and tried it out and it didn't work with and without the trimmed code :-BROKE
so I trimmed the whole program down to a just blink a led at lata0 and it finally worked :phew:
at this point, I have to follow an empirical approach, so I rewrote my program around the functioning blink program...
so here is a rundown of all the code that seems to be screwing with the operation of the code:
1)
--- Code: ---OSCFRQ =0b010; // OSCFRQ(HFFRQ0-2) SET OSCILLATOR TO 4MHz
--- End code ---
apparently, this code seems to slow down the CPU for some reason so I fixed it by increasing the clock:
--- Code: ---OSCFRQ =0b101; // OSCFRQ(HFFRQ0-2) SET OSCILLATOR TO 16MHz
--- End code ---
I also add a #define _XTAL_FREQ 4000000 to make the delay function work and will be removed later...
2)
reading and updating big switch, however, proved to be annoyingly difficult, I tried to do it inside the main loop, outside the main loop, in one IOC ISR, in two sperate IOC ISR, to the point of absolute insanity :scared:
at this point I admit couldn't conditionally toggle a GPIO on or off if my life depended on it :'(
3)
for both the ccp and ADC sanity check I had to rely on some conditional statement and let's just say that didn't go very well :palm:
Navigation
[0] Message Index
[#] Next page
[*] Previous page
Go to full version