I've written several iterations of this and ran into some sort of road block that required a complete rewrite now. The initial problem was using too many functions and exceeding the stack, this required a complete rewrite of the program to make it more linear. I've done that, but now it seems to be giving me an error that suggests its out of memory. I've been able to narrow the problem down to what appears to be a single line of code the complier or linker doesn't like (line 161) If I comment that line out (there are similar lines also commented out, any of them will cause the error as well) the program compiles fine. You will see a lot of things commented out, this is me cutting back items to try to isolate the issue w/ the compiler, including messing around with the structures I created for some variables. I have the majority of the code confirmed working, but the timer logic does not work.
This is the complier output;
I'm still learning how these things work so bear with me.
Its confusing because I can set that variable in other places, but when I try to set the variable within the if statement it chokes. commenting out that one line (leaving the if statement) shows I still have almost 50% of my program and 40% of my data memory available. I'm not sure how to break this down so that it doesn't depend on contiguous memory (if that is even the problem).
I'm tempted at this point to just toss the hardware I built and rebuild on a more modern chip, but at the same time I'd like to understand some of these problems at the level this old school chip is forcing me to work at (no interrupts, etc).
This is the complier output;
Code:
CLEAN SUCCESSFUL (total time: 4ms)
make -f nbproject/Makefile-default.mk SUBPROJECTS= .build-conf
make[1]: Entering directory 'D:/travm/Documents/MplabXprojects2/BensTimer.X'
make -f nbproject/Makefile-default.mk dist/default/production/BensTimer.X.production.hex
make[2]: Entering directory 'D:/travm/Documents/MplabXprojects2/BensTimer.X'
"C:\Program Files\Microchip\xc8\v2.32\bin\xc8-cc.exe" -mcpu=16F54 -c -fshort-double -fshort-float -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"C:/Program Files/Microchip/xc8/v2.32/pic/include" -I"C:/Program Files/Microchip/xc8/v2.32/pic/include/c90" -I"C:/Program Files/Microchip/xc8/v2.32/pic/include/c99" -I"C:/Program Files/Microchip/xc8/v2.32/pic/include/legacy" -I"C:/Program Files/Microchip/xc8/v2.32/pic/include/proc" -mwarn=-3 -Wa,-a -DXPRJ_default=default -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-osccal -mno-resetbits -mno-save-resetbits -mno-download -mno-stackcall -mc90lib -std=c90 -gdwarf-3 -mstack=compiled:auto -o build/default/production/newmain.p1 newmain.c
newmain.c:116:30: warning: (373) implicit signed to unsigned conversion
newmain.c:125:37: warning: (373) implicit signed to unsigned conversion
newmain.c:134:37: warning: (373) implicit signed to unsigned conversion
newmain.c:160:34: warning: (373) implicit signed to unsigned conversion
"C:\Program Files\Microchip\xc8\v2.32\bin\xc8-cc.exe" -mcpu=16F54 -Wl,-Map=dist/default/production/BensTimer.X.production.map -DXPRJ_default=default -Wl,--defsym=__MPLAB_BUILD=1 -fshort-double -fshort-float -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"C:/Program Files/Microchip/xc8/v2.32/pic/include" -I"C:/Program Files/Microchip/xc8/v2.32/pic/include/c90" -I"C:/Program Files/Microchip/xc8/v2.32/pic/include/c99" -I"C:/Program Files/Microchip/xc8/v2.32/pic/include/legacy" -I"C:/Program Files/Microchip/xc8/v2.32/pic/include/proc" -mwarn=-3 -Wa,-a -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-osccal -mno-resetbits -mno-save-resetbits -mno-download -mno-stackcall -mc90lib -std=c90 -gdwarf-3 -mstack=compiled:auto -Wl,--memorysummary,dist/default/production/memoryfile.xml -o dist/default/production/BensTimer.X.production.elf build/default/production/newmain.p1
:0:: error: (1347) can't find 0x105 words (0x105 withtotal) for psect "maintext" in class "CODE" (largest unused contiguous range 0xFF)
(908) exit status = 1
nbproject/Makefile-default.mk:137: recipe for target 'dist/default/production/BensTimer.X.production.hex' failed
make[2]: Leaving directory 'D:/travm/Documents/MplabXprojects2/BensTimer.X'
nbproject/Makefile-default.mk:90: recipe for target '.build-conf' failed
make[1]: Leaving directory 'D:/travm/Documents/MplabXprojects2/BensTimer.X'
nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed
make[2]: *** [dist/default/production/BensTimer.X.production.hex] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
BUILD FAILED (exit value 2, total time: 1s)
Its confusing because I can set that variable in other places, but when I try to set the variable within the if statement it chokes. commenting out that one line (leaving the if statement) shows I still have almost 50% of my program and 40% of my data memory available. I'm not sure how to break this down so that it doesn't depend on contiguous memory (if that is even the problem).
I'm tempted at this point to just toss the hardware I built and rebuild on a more modern chip, but at the same time I'd like to understand some of these problems at the level this old school chip is forcing me to work at (no interrupts, etc).
Code:
/*
* File: newmain.c
* Author: travm
*
* Created on August 10, 2021, 8:53 AM
*/
#pragma config OSC = XT // Oscillator selection bits (RC oscillator)
#pragma config WDT = OFF // Watchdog timer enable bit (WDT enabled)
#pragma config CP = OFF // Code protection bit (Code protection off)
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#define _XTAL_ 4000000
/*
*
*/
/****Global Vars****/
const char (seg7set[11]) = {
0b00001000, //0
0b01101011, //1
0b01000100, //2
0b01000001, //3
0b00100011, //4
0b00010001, //5
0b00010000, //6
0b01001011, //7
0b00000000, //8
0b00000001, //9
0b01111111, //clear
};
bit ansel = 0;
bit tock = 0;
bit dottock = 0;
struct {
//unsigned ansel : 1;
unsigned tick : 7; // 7 bits = 128, allows rollover @ 250ms
unsigned lasttick :7;
unsigned seccnt : 2; // counted @ tick rollover, makes 1s count @ rollover
//unsigned tock : 1;
//unsigned dottock : 1;
} clocks = {0,0,0};
bit mode = 0 ;
bit buttonstate = 0;
char buttontick = 0;
/*struct {
unsigned state : 1;
unsigned tick : 8;
} button = {0,0};
*/
char minutes = 4 ;
struct {
unsigned secdigit1 : 4;
unsigned secdigit2 : 4;
} time = {0,0};
int main(void) {
/***********RUN ONCE**********/
TRISA = 0b1010; //RA3 gets tri-stated to turn off AN1 and AN2,
//RA1 must be high imp. its connected straight to ground
OPTION = 0b00000010; //Options - Prescaler set at 1:8
TRISB = 0b00000000; //All PortB Pins are I/O
char previousclk = 0 ;
char currentclk = 0;
char pba = 0b10000000;
RA3=1; //Anode 1 and 2 - tristate this pin to turn off
RB7=1; //Anode 3 start on Anode 3, or the if statement flow doesn't work
/*****Main Program Loop*****/
while(1)
{
//clocks
currentclk = TMR0;
if (previousclk > currentclk) //advance item clocks here
{
clocks.tick ++; // approx 2 ms tick, refer to option register to adjust
// 4 mhz clock / 1:4 instruction, 8 bit counter, 1:8 prescaler
ansel = 1;
tock = 0;
previousclk = currentclk;
}
else
{
previousclk = currentclk;
}
// need dotflash routine here, must shrink size
if (clocks.tick == 127 && tock == 0)
{
clocks.seccnt ++ ;
tock = 1;
dottock=0;
}
if ((clocks.seccnt == 1 || clocks.seccnt == 3)&& dottock == 0)
{
RA0 = RA0 ^ 1;
dottock = 1;
}
//Display
if (ansel==1) // This is the display multiplexor
{
if (RB7==1) //if anode RB7 is on - This services minutes
{
RB7=0; //clear the display
pba=0b00000000; //set the portB anode bit
// --X-------; //portB anode bit off
//set portB to proper digit
TRISA = 0b0010; //activate display
RA3=1;
PORTB = seg7set[minutes]+pba ;
}
else if (RA3==1) //this services seconds 10's
{
//Set portB to proper digit
RA3=0; //clear the display _ activate display
//RA3 is connected to transistor,
PORTB = seg7set[time.secdigit1]+pba ;
}
else if (RA3==0) //this services seconds 1's
{
TRISA = 0b1010; //
RB7=1;
pba=0b10000000; //set the portB anode bit
// --1-------; // PortB anode bit on
//activate display
PORTB = seg7set[time.secdigit2]+pba ;
}
ansel=0;
}
//Timer Logic
if (clocks.seccnt == 3 && mode == 1) // when in mode 1, count down
{
char placeholder = 0 ;
/* if (time.secdigit2 == 0)
{
placeholder = time.secdigit1 - 1;
time.secdigit1 = placeholder ;
time.secdigit2 = 9;
}
if (time.secdigit1 == 0)
{
placeholder = time.minutes - 1;
time.minutes = placeholder ;
time.secdigit1 = 9;
}
if ((time.secdigit1 == 0 && time.secdigit2 == 0) && time.minutes==0)
{
mode = 0;
} */
placeholder = time.secdigit2 - 1 ;
// time.secdigit2 = placeholder ;
mode = 0;
}
//Button Logic
//detect a button press
if (RA1==0 && buttonstate==0)
{
buttonstate=1;
clocks.lasttick=clocks.tick;
}
//Debouncer and detect long vs short hold - this can be shrunk but is most accurate
if (buttonstate==1)
{
if (clocks.lasttick==(clocks.tick+1)) // tick rollover, only counted while
{
if (buttontick < 8)
{
buttontick++; //BUTTON TICK ADVANCES @ 122hz (250ms)
clocks.lasttick=clocks.tick;
}
}
if ((RA1==1 && buttontick > 1) && buttontick < 8)
{
buttonstate=0;//Do Short Press stuff
//time.minutes = (currentclk & 0b00000011)+ (currentclk>> 2 & 0b00000011) + 3 ; // logic for selecting initial timer setting
//time.minutes=1;
//time.secdigit1=5;
//time.secdigit2=9;
//if (clocks.mode==1) clocks.mode=0;
//if (clocks.mode==0) clocks.mode=1;
//clocks.mode = clocks.mode ^ 1 ; //this should work, but doesnt?
buttontick=0;
}
if (RA1==1 && buttontick == 8)
{
buttonstate=0;//Do long press stuff
minutes=2;
time.secdigit1=5;
time.secdigit2=6;
mode=0;
buttontick=0;
}
}
}
return;
}