Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

first c18 code; final few probems(eeprom, array size);

Status
Not open for further replies.

Dr_Doggy

Well-Known Member
for those who have been following me you will be happy to hear that I got my code switched from cow to c, and the cube is running great, so the only sub left to write is my RXSERIAL which as it sound reads the serial port; and writes it to my EXTERNAL EEPROM, \

however i have found a few walls that i cant seem to get around:

a) first and farmost, I need a input buffer to write the 252 byte serial data to, to hold the info durring the rx, while it waits for processing. initally i declared the array as DIN1[]; to which i found no error but found that the stack was overflowing and reading from somewhere else altogether, so then i changed DIN[253], however complier now gives me an error 1300; stack frame to large, so doing resarch i cleaned up all my unused declarations and changed all my int's to unsigned chars(that s all i need anyway), with that i was able to get my stack size up to 120, from 60 or 80, I also read a trick that you can use pointers or something, but i'd like to avoid that if i can since they seem a little confusing, PLUS during my reading everyone who was having large buffer issues were using much larger arrays, and cow didnt have this problem, so i am surprised that i am now, im sure its something simple im missing.?
THE 18f4620 should be able to handle this....

b) i borrowed the following code from another thread here, and it seems to work ok, but it causes me grief if i use it in this loop, where the variable CNT gets set and stuck at 0 after the second or third cycle(all that i can see is that maybe: EECON2 = 0xaa; <---arnt those supposta be capital a's)

for (CNT=1;CNT<80;CNT++) {WriteEEPROM (CNT,10);}



unsigned char ReadEEPROM(unsigned char address){
EECON1=0; //ensure CFGS=0 and EEPGD=0
EEADR = address;
EECON1bits.RD = 1;
return(EEDATA);
}

void WriteEEPROM(unsigned char address,unsigned char data){
char SaveInt;
SaveInt=INTCON; //save interrupt status
EECON1=0; //ensure CFGS=0 and EEPGD=0
EECON1bits.WREN = 1; //enable write to EEPROM
EEADR = address; //setup Address
EEDATA = data; //and data
INTCONbits.GIE=0; //No interrupts
EECON2 = 0x55; //required sequence #1
EECON2 = 0xaa; //#2
EECON1bits.WR = 1; //#3 = actual write
INTCON=SaveInt; //restore interrupts
while(!PIR2bits.EEIF); //wait until finished
EECON1bits.WREN = 0; //disable write to EEPROM
}

c) since im here, im also wondering about assembly, i wanted to avoid it all together but i never knew how close to it i was anyway, reading the datasheets im seeing the similarities but maybe there is a SIMPLE tutorial that guides me through all that garble?
 
I could describe the process but microchip has documented how to create large arrays.
Not sure where

You create a new code segment just for the array in the linker command file.
Then in the C code you switch to that segment prior to declaring it then back to code after it.

With a bit of googling you or someone should find it.
 
I use a 2k buffer for my LCD... In C18 you have to copy and paste the relevant LKR script from the LKR directory... c:/mcc18/lkr to your working directory..

Change the databank section ... my example
Code:
ACCESSBANK NAME=accessram  START=0x0		END=0x7F
DATABANK   NAME=gpr0       START=0x80		END=0xFF
DATABANK   NAME=gpr1       START=0x100		END=0x1FF
DATABANK   NAME=big        START=0x200		END=0x9FF	PROTECTED
DATABANK   NAME=gpr10      START=0xA00		END=0xAFF
DATABANK   NAME=gpr11      START=0xB00		END=0xBFF
DATABANK   NAME=gpr12      START=0xC00		END=0xCFF
DATABANK   NAME=gpr13      START=0xD00		END=0xDFF
DATABANK   NAME=gpr14      START=0xE00		END=0xEFF
DATABANK   NAME=gpr15      START=0xF00		END=0xF7F
ACCESSBANK NAME=accesssfr  START=0xF80		END=0xFFF	PROTECTED

SECTION    NAME=CONFIG     ROM=config
SECTION    NAME=buffer_scn RAM=big

STACK SIZE=0x100 RAM=gpr14

Notice the databank section big is 0x200 -> 0x9FF = 2047k
Then give it an alias... SECTION NAME=buffer_scn RAM=big

You can then add this in your main code..
Code:
#pragma udata buffer_scn
static char buffer[2048];
#pragma udata

char * backbuffer = &buffer[0];
By giving yourself a pointer to the buffer.... char *backbuffer.. you can access as you wish.

Oh one other thing.... this is a snippet from a pic18f4620... it has nearly 4k... if your processor has 1.5k.. try not to change the stack size... if you do don't pass many function parameters...
 
Last edited:
....finally i need to get my int0 working, iv referenced to the examples and from what i gather iv added to my main code:

RCON=0b1000000;
INTCON=0b11010000;
INTCON2=0b01000000;

then i added this at the begining before main:

#pragma code InterruptVectorHigh = 0x08
void InterruptVectorHigh (void)
{
_asm
goto RXSERIAL
_endasm
}


RXSERIAL is the sub i want interrupt0 to call, is this right, i think maybe im missing something??
 
hmm, i seem to be having a problem with INTCON where it is doing things to the other ports, besides B0, if i take out that line itself code works, but when i add that line it glitches unrelated things, datasheet says intconBIT4 is INT0enable, bit 2 is INT0flag, and bit 7 is global high enable,

does global high mean that all high interrupts are on? should i use INTCON=0b00010000 ?
and can INTCON=0b00010000 be used as reset flag aswell?
 
I never set priority levels when I only use one interrupt... I set INTCON to 0x90... GIE and INT0IE..

does global high mean that all high interrupts are on? should i use INTCON=0b00010000 ?
and can INTCON=0b00010000 be used as reset flag aswell?

Doesn't set the GIE.... you should use 10010000 as before (without the low).

ALSO... Remember. If the INT0 pin is an alternative analogue input.... disable it or the interrupts wont work.
 
Last edited:
does ADCON0.0 turn the whole thing off? i am trying that.
but the only code that is flying is when i use ADCON1=0b00000111, that i got somewhere from a previous example for something,
but i am very sure i have no analog inputs here, (TRISB=01000101shouldnt be a problem?)
and as far as i inturpurt the datasheet ADCON1=****1111 is all digital on the kmap, but that doesn't work for me either?
 
To turn off all Analog pins and make it Digital you need ADCON1 =%00001111


If you set ADCON1 to 0 you turn them all on

You want to set these bits to 1111 bit 3-0 PCFG3:pCFG0: A/D Port Configuration Control bits: have a look at page 262 of the data sheet.

you set to 1111 and you get all digital D D D D D D D D D D D D D
 
Last edited:
ya, me too sry, im using the 18f4620 actually, and was able to get it working, but it is strange since it is working at 0x08, but it also works on 0x07, (i spent some time going through them from 0-F), I also was able to get my serial register to work great so the dataarray workstoo!

however i am running to a slight glitch where i am noticing that when i write to my SPI flash it is missing a write cycle somewhere, it is strange since it is only happening on the "BLUE" flash ic, writeprotect and dataout(toflash) is on port B1&2, but i dont think its those ones since WP & DO are all the same wire as the other SPI FLASHes, the chip select for blue is on port d.0 so i doubt thats the problem either,

it is espically random since the write cycle writes 252 bytes * 6 pages, and the glitch appears on random pages where a full page is blank, also resetting chip causes either a page to glitch in the same place, somewhere else, sometimes after 2 or 3 resets the glitch pans out and the data resets properly,

again this started when i enabled the interrupt...
 
Last edited:
heh TICKETY BOO! Im surprised that was the prob epically since the serial comm port was off when it was happening...

now all thats left is this eeprom! BUT ima take a few and see if i can get it on my own, i have a feeling that was some not so good code...

but in the mean time thnx again boys! it feels soooo good to finally see this thing tickin!

I also had a non-related question, about the a/d, if i wanted to use it as a HV detector, is it safe to take my series Mohm resistors to break the voltage down and feed to a/d from a basic voltage divider circuit, i just wonder if the a/d pin may add some thevenin resistance, LOL, i use a meter coil w needle right now but there is quite the power loss since the needle needs a few mA to run, which adds up across all those resistors...

oh ya, and is it possible for a function to return 2 variables?
 
Good luck!!

Yes! in a sort of way... Two int's can be merged into a long. Two bytes into an int..... However you can return structures (pointers actually, but it doesn't seem like it)

Code:
struct PARAM
   {
    int   myint;
    char  mychar;
   };

struct PARAM   dofunction( int x,  int y);

I shouldn't really do that..... posting without testing, but you get the idea.
 
Last edited:
ya, i get it,

and i was able to get everything up, however i am running in to the same problem where i am loosing a few BLOCKS of data, the read cycle is reading full pages of data, im using internal eeprom byte0 for my page count(or value for BLOCK), and the rest of the eeprom for the waitarray value(which just tells the pic how much to repeat a page, and when 0 resets the back to the first write PAGE) from byte 1-14.

the rest of the internal eeprom is temporally used to record the 232 input, (we can ignore the first 14 blocks), on each rx it reads the cycle, puts it in to the buffer, writes to the eeprom, it should also seperate each page, then loads buffer to the external FLASH with the coresponding colors,

But what seems to be happening is that the first page is loading, writing and playing back ok, but then i send the second page it loads and writes ok, but for some reason during that time the first page is lost off the flash, sometimes the green page makes it through, but the red and blue are showing blank(0xFF), i checked for a bogus erase or write, but i cannot find what is causing this, I also added an "interrupt off" to ensure it wasnt that, like it was last time,
this is the same problem I had in GCGB which in when i decided it was time to switch to c to see my values better,
enclosed is the results of the eeprom and rx serial loop; again, i dont think it is in the read loop, and the eeprom looks ok to me, but maybe related? maybe there is a better way to what im doing?


btw, my eeprom function was ok, except :

while(!PIR2bits.EEIF); //wait until finished

just had to be changed to a delay
 
Last edited:
It's very difficult, if not impossible, to debug a little section of code. Can you post something that will at least compile?

I ran your code through my code tidy program so it was correctly indented and I'll post it here as you may assume it's doing something different to what it is actually doing.
Code:
void RXSERIAL (void){
    LATAbits.LATA5 = 1;                                                 //OUTPUT OFF
    while(PORTDbits.RD7 == 1){                                          //DTR
        while (PORTCbits.RC2 == 1){                                     //RTS 
            unsigned char  CNT;
            unsigned char  WAITPOS;
            unsigned char  CNT2;
            unsigned char  TIMEOUT;
            unsigned char  CNT3;
            unsigned char  CNT4;
            unsigned char  SECTORA;
            unsigned char  BLOCKFF;
        
        
        
            INTCONbits.GIE=0;                                           //No interrupts
            LATBbits.LATB5 = 1;                                         //DSR ON
            LATEbits.LATE2 = 1;    
            Delay10TCYx(40);                                            //CTS
            for (CNT=1;CNT<253;CNT++){
                Delay10TCYx(70);
                TIMEOUT = 0;
                for (CNT2=1;CNT2<9;CNT2++){                        
                    TIMEOUT = TIMEOUT / 2;
                    if (PORTBbits.RB0 == 0){             
                        TIMEOUT = TIMEOUT + 128;                        //RX
                    }        
                    Delay10TCYx(80);
                }            
                if (TIMEOUT == 255) {TIMEOUT = 0;}
                CNT3 = CNT;
                buffer[CNT3] = TIMEOUT;
                TIMEOUT = 0;
                while((PORTBbits.RB0 == 0) & (TIMEOUT < 200)){
                    TIMEOUT = TIMEOUT + 1;
                    Delay10TCYx(1);
                }    
                Delay10TCYx(80);
            }
            LATEbits.LATE2 = 0;                                         //CTS  OFF
                     /*    END READ LOOP   */
        
            SECTORA = 1;
            BLOCKFF = readEE(0, 0);    
            CNT2 = BLOCKFF - 1;
            if (CNT2 == 1){
                for (CNT=14;CNT<253;CNT++){                             // DONT WRITE OVER WAITARRAY!!!
                    CNT3 = buffer[CNT];
                    writeEE(CNT2, CNT, CNT3);
                }
            }else{
                for (CNT=1;CNT<253;CNT++){
                    CNT3 = buffer[CNT];
                    writeEE(CNT2, CNT, CNT3);
                }
            }
        
                    //END TEST LOOP
        
            SECTORA = 1;
            BLOCKFF = readEE(0, 0);
            FLER (1, SECTORA, BLOCKFF, 1);
            FLER (2, SECTORA, BLOCKFF, 1);
            FLER (3, SECTORA, BLOCKFF, 1);
            READYCHIP (1);                                              //PROGRAMS GREEN
            INSTRUCT (2);
            INSTRUCT (SECTORA);
            INSTRUCT (BLOCKFF);
            INSTRUCT (1);
            for (CNT2=1;CNT2<253;CNT2++){ 
                if (CNT2<126) {CNT3 = (CNT2);CNT4 = buffer[CNT3];}  
                if (CNT2>126) {CNT3 = CNT2+1;CNT4 = buffer[CNT3];}
                if ((CNT4 == 1) || (CNT4 == 3) || (CNT4 == 5) || (CNT4 == 7))  {INSTRUCT (1);} else {INSTRUCT (0);}
            }
            LATDbits.LATD1 = 1;
            LATCbits.LATC0 = 1;
            LATCbits.LATC3 = 1;
        
            SECTORA = 1;
            BLOCKFF = readEE(0, 0);
            READYCHIP (2);                                              //PROGRAMS BLUE
            INSTRUCT (2);
            INSTRUCT (SECTORA);
            INSTRUCT (BLOCKFF);
            INSTRUCT (1);
            for (CNT2=1;CNT2<253;CNT2++){
                if (CNT2<126) {CNT3 = CNT2;CNT4 = buffer[CNT3];}
                if (CNT2>126) {CNT3 = CNT2+1;CNT4 = buffer[CNT3];}
                if ((CNT4 == 2) || (CNT4 == 3) || (CNT4 == 6) || (CNT4 == 7)) {INSTRUCT (1);} else {INSTRUCT (0);}
            }
            LATDbits.LATD1 = 1;
            LATCbits.LATC0 = 1;
            LATCbits.LATC3 = 1;
        
            SECTORA = 1;
            BLOCKFF = readEE(0, 0);
            READYCHIP (3);
            INSTRUCT (2);
            INSTRUCT (SECTORA);
            INSTRUCT (BLOCKFF);
            INSTRUCT (1);
            for (CNT2=1;CNT2<253;CNT2++){
                if (CNT2<126) {CNT3 = CNT2;CNT4 = buffer[CNT3];}
                if (CNT2>126) {CNT3 = CNT2+1;CNT4 = buffer[CNT3];}
                if ((CNT4 == 4) || (CNT4 == 5) || (CNT4 == 6) || (CNT4 == 7)) {INSTRUCT (1);} else {INSTRUCT (0);}
            }
            LATDbits.LATD1 = 1;
            LATCbits.LATC0 = 1;
            LATCbits.LATC3 = 1;
            WAITPOS = (((BLOCKFF - 1) * 2) + 1);                        //WRITE DIN126 & 252 TO WAITARRAY
            writeEE (0, WAITPOS, buffer[126]);
            WAITPOS = (((BLOCKFF - 1) * 2) + 2);
            writeEE (0, WAITPOS, buffer[252]);
            if ((buffer[126] == 0) || (buffer[252] == 0)){
                writeEE(0, 0, 1);                                       //CLOSES REPLAY LOOP
                goto EXITPOS;
             }else{            
                BLOCKFF++;
                writeEE (0, 0, BLOCKFF);                                //INCREMENTS BLOCKFF, READY FOR NEXT SET,
                goto EXITPOS2;
            }
        }
    }
    
    EXITPOS:
    LATBbits.LATB5 = 0;                                                 //DSR OFF
    EXITPOS2:
    LATAbits.LATA5 = 0;                                                 //OUTPUT ON
    INTCON = 0b10010000;
    Delay1KTCYx(80);    
    LATEbits.LATE2 = 1;                                                 //CTS
}
I must say I was a little alarmed to see the use of goto as it's generally never used unless it absolutely has to be. I have never used it. However, in this case it doesn't seem to be a problem.

Mike.
 
Last edited:
also i am watching those brackets carefully, which isnt it:(.
i was hesitating since this is a huge code, and will only work with my circuit here

the problem onlyy happens when: BLOCKFF=2 it writes to PAGE2 as it should but seems to bug out page 1(only the red and blue). green randomly works,

mind that when BLOCKFF=2, data loads to page2 properly

BUT if i send page one with WAITARRAY IS 0 and BLOCKFF stays on page 1, the load sequence works each and every time


but here it is....
 
Last edited:
Status
Not open for further replies.

Latest threads

Back
Top