CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Structuring a database in memory

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
NickStout



Joined: 09 Nov 2005
Posts: 12

View user's profile Send private message

Structuring a database in memory
PostPosted: Wed Nov 09, 2005 11:52 pm     Reply with quote

Hello,
I'm still VERY new to PIC programming, and I want to tackle what seems to be a very challenging topic: storing of a table of information in memory.

Right now, I have a list of five or six 8 byte long "tags" that I want to associate with a name and a long index of numbers. In text, it'd look like the following:

Tag S/N........Name...........values
E01234AF.....John Doe.......10 11 12 13 14 15 16 17 18 19 20
E01234BF.....Michael Doe...12 13 14 15 16 17 18 19 20 21 22
... etc

The problem is that there is no way that I know to read a text file from a PIC, let alone deal with it. I thought maybe I could use the EEPROM to store information, but I have absolutely no idea how I'd retreive it in one piece.
The code I'm writing has to be able to call this "look-up table" and match it with some data coming in serially, which I know how to do if I could figure out how to store this data, and more importantly, get it back in groups as shown.

I know this is a pretty big doozy for a first post, but I was just curious... Has anyone done anything of this sort in the past? If so, I could definitely use some guidance.

Thanks in advance.
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Nov 10, 2005 3:49 am     Reply with quote

If the table is relatively static, then you can sore it it progam memory on a flash based PIC such as the 18Fxxx.

You can reserve memory for your database using an option of the origin statement - this will enable you to both define the address in memory of your database as well as reserve program memory for it. You can prepopulate your database, if required using #ROM.

YOu can read and write program memory byte at a time using either standard CCS functions or using assembler table read and table write instructions.

Use your tag (which may be in program memory, ram or EEPROM) to determine the offset position into your database. Locate the record of interest (assuming fixed sized records) by

record_ptr = db_base_address + (record_len * tag_offset)
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Ttelmah
Guest







PostPosted: Thu Nov 10, 2005 4:05 am     Reply with quote

A number of important questions:
How large is 'large'?... If the list is a few hundred bytes, the solutions will be different from one that is many KB. Basically, if the total list is small (under 1KB), then on some PICs this may be able to use the EEPROM. If larger, but still only a few KB, it may be possible to put the list in the main program memory. If larger still, then you will need external memory, and possibly something like MMC storage.
Second question. How are the contents to be generated/changed?. If 'never', but just programmed initially, the 'best' solution will differ markedly from a table that needs to be frequently updated (both because of 'speed' issues, and 'life' issues on different memory types).
Third, how is the data scanned?. If the values are indexed by the 'tag', it may be best to store the tag itself seperately, in perhaps the main program memory, and then use a value stored with this to 'find' the main entry.

Best Wishes
NickStout



Joined: 09 Nov 2005
Posts: 12

View user's profile Send private message

PostPosted: Thu Nov 10, 2005 8:45 am     Reply with quote

Quote:
How large is 'large'?...


There should only be 5 or so "sets" of data. The tags only come in 8-byte segments, which I've determined I need to compare byte-by-byte to an incoming serial buffer. The names could be as long as 40 characters (but will probably be limited to 20. The extra data are calculated integer coefficients from a DSP. There could be as many as 1024 (the window of the DSP), but it's more likely it will be about 10-15.

So this list will be... maybe 1K for this experiment, but could be expanded to much larger, theoretically (up to 10K). This is a design project, which is why the limits are not hard and fast. If this was going out of the prototype stage, I'd worry more about the numbers, of course.

Quote:
How are the contents to be generated/changed?


The data is written to only in a "programming mode", but for now, I can safely say that it's a static set. In the programming mode, however, the list would simply be checked and appended to if another entry in the table was desired. It'd be great to be able to edit the list from another source (i.e. a dynamically generated text file that could be read into the PIC from a memory or edited from a PC. This would be the best solution to my programming woes).

Quote:
If the values are indexed by the 'tag', it may be best to store the tag itself seperately, in perhaps the main program memory, and then use a value stored with this to 'find' the main entry.


That's a fantastic idea. The tag is checked way before anything else, and once the tag is read (over RS232) for the first time, the program should be able to do a quick name and int list data gathering... those can be nicely indexed by the tag.
The downside to this is that the programmability of the system is shot to hell at that point, since programming the PIC's program memory while it's up and running wouldn't be simple - can't even use a bootloader! So ultimately, while this is a great idea, in practice probably isn't the solution I'm looking for.

The best solution, in my opinion, would be something that could be read by the PIC and a common PC (i.e. MMC card with a txt document), but I don't think anyone has successfully done this, since the architecture of these two devices is different.
But as both of you seem to have pointed out, it would be easier to index off the tag and store the rest of the table based off the tags in program memory or EEPROM. From a purely "static data" point of view, which approach seems to make more sense to you? What about the dynamic "programmable" approach?


Thank you for all of your help so far. I am continuing to learn how far the limits of the PIC go every time I work with it, so this project has been a very fun learning experience.
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Nov 10, 2005 6:33 pm     Reply with quote

Quote:


There should only be 5 or so "sets" of data. The tags only come in 8-byte segments, which I've determined I need to compare byte-by-byte to an incoming serial buffer. The names could be as long as 40 characters (but will probably be limited to 20. The extra data are calculated integer coefficients from a DSP. There could be as many as 1024 (the window of the DSP), but it's more likely it will be about 10-15.

So this list will be... maybe 1K for this experiment, but could be expanded to much larger, theoretically (up to 10K). This is a design project, which is why the limits are not hard and fast. If this was going out of the prototype stage, I'd worry more about the numbers, of course.
...

The downside to this is that the programmability of the system is shot to hell at that point, since programming the PIC's program memory while it's up and running wouldn't be simple - can't even use a bootloader! So ultimately, while this is a great idea, in practice probably isn't the solution I'm looking for



This could easily be achieved by storing the data in the PIC main program memory space. The program memory can be read and written as easily as the EEPROM and there is more than enough memory space on PICs to accommodate your data set as described. I wrote a "Christmas lights" program for a friend using a PIC18F1320. This is for those keen people that decorate the outside of their house with a large number of lights and then control how they are sequenced. The initial pattern is developed on a PC (using an EXCEL spreadsheet) and the patterns are then sent to the PIC using a variation of the intel hex file format and stored into the table memory space just like using a bootloader.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
NickStout



Joined: 09 Nov 2005
Posts: 12

View user's profile Send private message

PostPosted: Mon Nov 14, 2005 12:35 am     Reply with quote

Quote:
The program memory can be read and written as easily as the EEPROM and there is more than enough memory space on PICs to accommodate your data set as described.


I'm not quite sure I understand... so let me summarize an idea I had here and see if this is where you're going:

I have to be able to program the data table - add/delete/change. To do this, I was considering a mode where the PIC will interface with a PC serially. The PIC will send out something similar to the following to the PC via terminal:

1) User: John Doe, Tag: 12345678, Values: 12 32 85 734
2) User Jane Doe, Tag 12345679, Values: 12 13 15 219
3) User Joe Doe, Tag 12345681, Values: 12 13 17 222
A) Add a new user

Please select a user, or 'A' to add a new user:


The PIC would go into processing mode, and the PC would "program" the PIC's database.

Can it physically program the program memory and be saved when the PIC loses power? Without changing the C/assembly dynamically, I'm not sure this is possible... without storing it to memory at some point.

I would really love some implementation suggestions on this part. By what everyone's told me, it sounds like external memory is not the best idea, especially since it has to access it so much... but it might be possible to save the table to memory (EEPROM or External) and LOAD it into program memory on boot.

Thanks for all your help so far!
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Mon Nov 14, 2005 12:49 am     Reply with quote

NickStout wrote:

The PIC would go into processing mode, and the PC would "program" the PIC's database.

Can it physically program the program memory and be saved when the PIC loses power? Without changing the C/assembly dynamically, I'm not sure this is possible... without storing it to memory at some point.


Yes. This is definitely possible. As mentioned previously, the basics for this can be found in the bootloader.

Quote:

I would really love some implementation suggestions on this part. By what everyone's told me, it sounds like external memory is not the best idea, especially since it has to access it so much but it might be possible to save the table to memory (EEPROM or External) and LOAD it into program memory on boot.


External memory is also fine. As you have previously stated you data is relatively constant - you will not wear out the flash part by writing to it too frequently. BTW the problem is write related not read related.

Forget about your idea of "LOAD" to program memory. The Program Memory space is flash memory - once written there its good for a decade or so...
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
NickStout



Joined: 09 Nov 2005
Posts: 12

View user's profile Send private message

PostPosted: Mon Nov 14, 2005 4:21 pm     Reply with quote

Quote:
As mentioned previously, the basics for this can be found in the bootloader


Now we're getting into more specific code.
The bootloader examples gather the "program" from the RS232 in hex (according to the code, using some program I don't have - SIOW.EXE). I need more to be able to give the PIC parameters and it to save the database in... EEPROM?
I'm not sure how to proceed. I'm just editing arrays and then writing the array to the program memory, but I think the bootloader uses a whole program in 'compiled' .hex. I'm having trouble seeing how this would work, especially since I've never written a bootloader. Suggestions?
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Mon Nov 14, 2005 6:41 pm     Reply with quote

Quote:
The bootloader examples gather the "program" from the RS232 in hex (according to the code, using some program I don't have - SIOW.EXE).


SIOW.EXE is a terminal emulation program. Hyperterm works just as well for this purpose.

Quote:
I need more to be able to give the PIC parameters and it to save the database in... EEPROM?


This is not what I have been saying. The PIC (any 18F series) can store the database in its spare PROGRAM memory space. If you only had a small database then you could store it in EEPROM. The choice is yours.

Quote:
I'm just editing arrays and then writing the array to the program memory, but I think the bootloader uses a whole program in 'compiled' .hex. I'm having trouble seeing how this would work, especially since I've never written a bootloader. Suggestions?


The bootloader is reading in a record (structured line) usually termiated with a <CR> or <CR><LF>, examining the addressing information at the start of the record and storing the record in PROGRAM or EEPROM as determined by the addressing information associated with the record. Exactly how the addressing structure works is not of interest to you as you will have your own. What you are interested in in the bootloader example is how it reads and writes to program memory.

Do a search on the web for "intex hex format" record structure and you will find lots of examples detailing the record structure. Here is one such pointer http://www.rabbitsemiconductor.com/documentation/docs/refs/TN220/TN220.htm#1036448

Your program will need to implement its own parser to read in your records and from this determine where it should fit in the database. Fixed length records are the way to go for a simple implementation.

Here is the code listing for the "Christmas Flashing Light" program which displays patterns stored in PROGRAM memory. Patterns are loaded via the serial port.
Code:
//////////////////////////////////////////////////////////////////////////
//
//      Bob's Flashing LEDs V2
//      PIC 18F1320 Processor at 20MHz
//
//      Copyright (c) 2005, Andrew Smallridge
//
///////////////////////////////////////////////////////////////////////////

#include "Bob LEDs V2.h"
#include <string.h>
//#include <stdlib.h>
#build(reset=0x00:0x07)

#define   SR_Width 32   // width of the shift register

//   ; define ASCII constants
#define   Xon      0x11
#define   Xoff   0x13

#define Table 0x0C80
#define TableWidth 5
#define TableSize (0x1800-Table)/TableWidth-1
#rom Table = {0x8C01,0x01EF,0x0023,0x0000,0x0000}

#define RxBufLen 32
byte   RxBase[RxBufLen];
byte   RxHead;
byte   RxTail;

#define   CmdBufLen 16
byte   CmdBase[CmdBufLen];
byte   CmdHead;

short   do_shift;      // indicate bit shifting is active
byte   sequence[TableWidth];   #locate sequence = 0x40 // current display sequence
byte   bit_count;      // bits remaining to be displayed
boolean   done_data_bit;
boolean   comment;

#define C_ticks_20ms 200
byte   ticks_20ms;      // timer 0 ticks for 2mS

#define C_Toggle_time 25
byte   toggle_time;   // number of 20ms ticks before next LED toggle

int16 TableOffset;



void load_pattern();

#int_RDA
//void rx_handler()
void serial_isr()
   {
   char current;

   current = getc();
   if (current == 0x0d)
      comment = false;

   if (!comment)   // ignore comment
      {
      switch (current)
         {
         case 0x0a :   // ignore line feed
         case ' ' :   // ignore space
            return;
            break;

         case ';' :
            comment = true;
            return;
            break;

         case 0x0d :
            RxBase[RxHead++]=0;
            RxHead %= RxBufLen;   
            return;
            break;         

         default :
            RxBase[RxHead++]=current;
            RxHead %= RxBufLen;
            return;
            break;
         }
      }
   }


#int_timer0
void TMR0_isr()
///////////////////////////////////////////////////////////////////////////
//
// TMR0_isr
//
//   Timer 0 interrupt handler
//
//   Controls the shift clock and strobe pulse (active on rising edge)
//
//
///////////////////////////////////////////////////////////////////////////
   {
   // do_shift is true the we are in the middle of shifting out a data stream
   if (do_shift)
      {
      if (bit_test(SR_Clock))
         {
         // if the clock pulse was high then clear the clock pulse
         bit_clear(SR_Clock);
         done_data_bit = false;         
         // if all bits have been shifted then set the strobe
         if (!--bit_count)
            {
            bit_set(SR_Strobe);
            do_shift = false;
            }
         }
      else
         {
         // clock pulse was low while still shifting data
         // time to serialize out the next data bit?
         if (done_data_bit)
            {
            done_data_bit = false;
            bit_set(SR_Clock);
            }
         else
            {
            // here to shift out the next data bit
            if (Sequence[1] & 0x80)
               bit_set(SR_Data);
            else
               bit_clear(SR_Data);

            #ASM
            rlcf   0x044, F
            rlcf   0x043, F
            rlcf   0x042, F
            rlcf   0x041, F
            #ENDASM

            done_data_bit = true;
            }
         }
      }
   else
      bit_clear(SR_Strobe); // continuously clears the strobe bit...

   if (!--ticks_20ms)
      {
      // reinitialise the timer
      ticks_20ms = C_ticks_20ms;
      output_toggle(PIN_A1);   
      if(!--toggle_time)
         {
         output_toggle(PIN_A4);
         toggle_time = C_Toggle_time;
         }

      if (!--sequence[0])
         {
         bit_count = SR_Width;
         load_pattern();
         do_shift = true;
         }
      }
   }


void load_pattern()
///////////////////////////////////////////////////////////////////////////
//
// load_pattern
//
//   Loads the pattern register from the next table entry
//
//
///////////////////////////////////////////////////////////////////////////
   {
   int16 offset;
   int x;

   //   offset = TableWidth*TableOffset;
   // for loop used instead of multiple to prevent interrupts being disabled
   // when using multiple in the mainline
   for (x=0,offset=0; x< TableWidth; x++)
      offset += TableOffset;

   read_program_memory(Table + offset, sequence, TableWidth);

   if ((sequence[0] == 0xff) || (sequence[0] == 0))
      {
      TableOffset = 0;
      offset = 0;
      read_program_memory(Table + offset, sequence, TableWidth);;
      }
   else
      {
      if (++TableOffset >= TableSize)
         TableOffset = 0;
      }
   }



void dump_patterns()
///////////////////////////////////////////////////////////////////////////
//
// dump_patterns
//
//   Dumps the pattern table to the serial port
//
//
///////////////////////////////////////////////////////////////////////////
   {
   int x;
   char tens, units;
   int16 offset;
   int16 linenumber;
   boolean done;
   byte line[TableWidth];

   for (linenumber=0, done=false, offset=0; (linenumber < TableSize) && !done; linenumber++, offset += TableWidth)
      {
      read_program_memory(Table + offset, line, TableWidth);
      if ((line[0] != 0xff) && (line[0] != 0))
         {
         printf("!%04ld ",linenumber);
         units = (line[0] % 10) + '0';
         tens = (line[0] / 10) + '0';
         printf("%c%c ",tens,units);
         for (x=1; x < TableWidth; x++)
            printf("%x",line[x]);
         printf("\r\n");
         }
      else
         done = true;
      }
   }


unsigned int atoi_8(char *source)
///////////////////////////////////////////////////////////////////////////
//
// atoi_8
//
//   Convert two ASCII hex characters to int8
//
//
///////////////////////////////////////////////////////////////////////////
   {
   unsigned int result = 0;
   char ch;
   int x;

   for (x=0;(x<2) && *source; x++,source++) 
      {
      ch = toupper(*source);
      if (ch >= 'A')
         result = 16*result + (ch) - 'A' + 10;
      else
         result = 16*result + (ch) - '0';
      }
   return(result);
   }


unsigned int16 atoi_16(char *source)
///////////////////////////////////////////////////////////////////////////
//
// atoi_16
//
//   Convert four ASCII hex characters to int16
//
//
///////////////////////////////////////////////////////////////////////////
   {
   unsigned int16 result = 0;
   char ch;
   int x;

   for (x=0;(x<4) && *source; x++,source++) 
      {
      ch = toupper(*source);
      if (ch >= 'A')
         result = 16*result + (ch) - 'A' + 10;
      else
         result = 16*result + (ch) - '0';
      }
   return(result);
   }


unsigned int16 ASCII_16(char *source)
///////////////////////////////////////////////////////////////////////////
//
// ASCII_16
//
//   Convert four numeric ASCII characters to int16
//
//
///////////////////////////////////////////////////////////////////////////
   {
   unsigned int16 result;
   int x;

   x = 0;
   result = 0;
   while (isdigit(source[x]) && (x<4))
      result = 10*result + source[x++] -'0';
   return(result);
   }


unsigned int8 ASCII_8(char *source)
///////////////////////////////////////////////////////////////////////////
//
// ASCII_8
//
//   Convert two numeric ASCII characters to int8
//
//
///////////////////////////////////////////////////////////////////////////
   {
   unsigned int8 result;
   int x;

   x = 0;
   result = 0;
   while (isdigit(source[x]) && (x<2))
      result = 10*result + source[x++] -'0';
   return(result);
   }


void show_shadow(char *shadow)
   {
   int x,y;
   printf("Shadow Block\r\n");
   for (y = 0; y < 8; y++)
      {
      for (x = 0; x < 8; x++)
         printf("%x ", shadow[y * 8 + x]);
      printf("\r\n");
      }
   printf("\r\n");   
   }



void store_pattern(char *source)
///////////////////////////////////////////////////////////////////////////
//
// store_pattern
//
//   Stores the pattern in Program Memory
//
//
///////////////////////////////////////////////////////////////////////////
   {
   #define EraseSize 64
   byte shadow[EraseSize];
   int32 addr, page;
   int16 line;
   int8 offset, x;
   char rcb[TableWidth];   // record construction buffer

   // extract the line number   
   line = ASCII_16(&source[1]);
   if (line >= Tablesize)
      Line = Tablesize-1;

   // construct the record
   rcb[0] = ASCII_8(&source[5]);   // get the time
   for (x=0; x<4; x++)
      rcb[1+x] = atoi_8(&source[2*x+7]);

   // fetch contents of the target block in program memory
   addr = table + line * TableWidth;
   page = addr & ~((long)EraseSize-1);
   offset = (int8)(addr - page);
   read_program_memory(page, shadow, EraseSize);

   // update the contents of the target block
   x = 0;
   while ((offset < EraseSize) && (x < TableWidth))
      shadow[offset++] = rcb[x++];

   write_program_memory(page, shadow, EraseSize);

   // if a page wrap occurred then we need to complete writing the data
   // to the next page
   if (x<TableWidth)
      {
      page += EraseSize;   // point to the next page
      offset=0;         // updating from the start of the new page
      // fetch the next page block from program memory
      read_program_memory(page, shadow, EraseSize);
      while (x < TableWidth)
         shadow[offset++] = rcb[x++];
      write_program_memory(page, shadow, EraseSize);      
      }
   }


void SrvCmd(char *command)
///////////////////////////////////////////////////////////////////////////
//
// SrvCmd
//
//   Service Commands from the serial port
//
///////////////////////////////////////////////////////////////////////////
   {
   char const RESET[] = "RESET";
   char const DUMP[] = "DUMP";
   int x;

   switch (command[0])
      {

      case 'r' :
      case 'R' :

         // process the RESET command
         for (x=0; (x < 5) && (RESET[x] == toupper(command[x])) && command[x]; x++)
            ;
         if (x == 5)
            {
            printf("RESET request\r\n");
            delay_ms(10);
            reset_cpu();
            reset_cpu();
            }
         return;
         break;

      case 'd' :
      case 'D':
         // process the DUMP command
         for (x=0; (x < 4) && (DUMP[x] == toupper(command[x])) && command[x]; x++)
            ;
         if (x == 4)
            {
            printf("DUMP request\r\n");
            dump_patterns();
            }
         return;
         break;

      case '!' :
         // suspend the sender
         disable_interrupts(int_timer0);
         putc(Xoff);
         printf("%c",Xoff);
         delay_ms(1);
         store_pattern(command);
         enable_interrupts(int_timer0);
         putc(Xon);
         return;
         break;

      case 0x0d :
      case 0x0a :
      default:
         return;
         break;

      }
   }



void ServiceRxQ()
///////////////////////////////////////////////////////////////////////////
//
// ServiceRxQ
//
//   Basic polled Rx Q service subroutine (NON BLOCKING)
//   Receives a byte from the serial Rx buffer and queues it to the

//   command buffer
//
// On Exit:
//   RxTailC = RxHeadC   or CmdHead >= CmdBufLen
//
///////////////////////////////////////////////////////////////////////////
   {
   byte current;

   while ((RxTail != RxHead) & (CmdHead < CmdBufLen))
      {
      current = RxBase[RxTail++];
      RxTail %= RxBufLen;

      switch (current)
         {
         case 0:
         case 0x0d:      // <CR>
            CmdBase[CmdHead] = 0;   // terminate the string with a NULL
            SrvCmd(CmdBase);            // go service the console command
            CmdHead = 0;         //
            break;

         case 0x0a:      // ignore <LF>
            break;

         default :
            CmdBase[CmdHead++] = current;
            if (CmdHead >= CmdBufLen)
               CmdHead--;
            break;
         }
      }
   }




void main ()
   {
   int i;
   Boolean   Last_Level;

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);

   // initialise PORTs A and B
   output_a(PA_DefData);
   output_b(PB_DefData);
   set_tris_a(PA_DefTRIS);
   set_tris_b(PB_DefTRIS);

   // initiailse the serial receive buffer and command buffer
   RxHead = RxTail = 0;
   CmdHead = 0;

   load_Pattern();
   bit_count = SR_Width;
   comment = false;
   TableOffset = 0;

   // force a pattern load
   do_shift = false;
   sequence[0] = 1;      // force a pattern load
   ticks_20ms = 1;

   // setup timer 0 for bit shift clock
   setup_timer_0(RTCC_DIV_2 | RTCC_8_BIT);
   set_timer0(0);
   clear_interrupt(int_timer0);
   clear_interrupt(int_rda);

    printf("** Bob's LED System **\r\n");

   // initialise the status LED
   bit_clear(test_status);
   toggle_time = C_Toggle_time;

   // initialise the console receive USART status
   i = RCREG;
   i = RCREG;
   if (bit_test(RCSTA,OERR))
      {
      // here on overrun error - need to reset the USART
      bit_clear(RCSTA,CREN);      // clear continous receive bit
      bit_set(RCSTA,CREN);      // set continous receive bit
      }

   // Enable the serial interrupt
   enable_interrupts(global);
   enable_interrupts(int_rda);
   enable_interrupts(int_timer0);

   restart_wdt();
   setup_wdt(WDT_ON);
   Last_Level = bit_test(LED_status);
   putch(Xon);

   while (1)
      {
      ServiceRxQ();
      restart_wdt();
      }
   }


_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!


Last edited by asmallri on Wed Nov 23, 2005 12:53 am; edited 2 times in total
NickStout



Joined: 09 Nov 2005
Posts: 12

View user's profile Send private message

PostPosted: Mon Nov 14, 2005 10:57 pm     Reply with quote

Wow! That's some fairly dense code.
Thank you very much for all of your patient help. I'm implementing this on a PIC16F877, so I probably can use the hardware USART and hack down some of that code. I'll have to look over all of this and see if I can make sense of it. The only problem is that I'm not sure how much program memory I'll have when I add this bootloader. We'll have to see.

Thanks again for all the help. I'll let you know how it goes!
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Mon Nov 14, 2005 11:28 pm     Reply with quote

Quote:
The only problem is that I'm not sure how much program memory I'll have when I add this bootloader. We'll have to see.


You can alway move to a PIC18F processor. The PIC18F4520 has the same electrical pinout but have far more resources such as Program memory, ram etc.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group