Jump to content


  • Content Count

  • Joined

  • Last visited

Everything posted by Reynard

  1. Here is a couple of ideas for traversing your char array. They only access the array once saving a bit of time and code space (maybe). char j,k; j = 0; while ((k = row_1[j++]) != '\') { porta = k; } OR using a pointer: char *p,k; p = row_1; while ((k = *p++) != '\') { porta = k; } Putting an assignment within a conditional is not everyones cup of tea, especially if you are writing to MISRA specification. Use char for array index instead of int if you can get away with it. Cheers Reynard Edit: for some reason the zero gets removed from the '\' (slash-zero).
  2. Not sure if you have the correct manual for this chip You need to set pei1.SSPIE to enable the interrupts. RC5 has to be set for an output (SDO). Are you pulling the SS/ pin low ? There may be more, but this is a start. Cheers Reynard
  3. output_low_port_a is/was a built in function of the c2c compiler. These functions I think are now obsolete in BoostC and are replaced by the more generic set_bit and clear_bit functions. Cheers Reynard
  4. So it is Picxie. Kinda knocks it all on the head. ps. Read previous reply as semi-colon. Silly me.
  5. As Picxie says, let the compiler do it for you. If you really want to write your own context saving code, add the linker option "-isrnocontext" to stop the linker adding in the code. You cannot save your context at 0x0000 as this is the SFR area of the chip. You can use the common RAM area from 0x70-0x7f as this is available (for the 16F690) irrespective of what file address is selected. You can save context at 0x0020 (bank 0), but you must save the status register first, clear RP0 and RP1, save other registers, otherwise you will get some RAM corruption if the interrupt occured while a bank other than 0 was selected at the time. If you a putting assembler code within braces {} terminate the lines of code with a colon. For some reason the colon seems to only be required if there is a destination specified i.e. ,W or ,F Perhaps Dave or Pavel know why. Regards Reynard
  6. I have not done it myself, but I think you basically write your own wizard using the existing 4 as examples. Cheers Reynard
  7. Pavel, Your version didn't save anything when I tried it. V6.84 PIC 16F687 Speeds[0] = Speeds[1] = Speeds[2] = Speeds[3] = Speeds[4] = 0xFFFF; 0008 30FF MOVLW 0xFF 0009 00B7 MOVWF gbl_Speeds+D'8' 000A 00C0 MOVWF CompTempVar563 000B 30FF MOVLW 0xFF 000C 00B8 MOVWF gbl_Speeds+D'9' 000D 00C1 MOVWF CompTempVar564 000E 0840 MOVF CompTempVar563, W 000F 00B5 MOVWF gbl_Speeds+D'6' 0010 00C2 MOVWF CompTempVar565 0011 0841 MOVF CompTempVar564, W 0012 00B6 MOVWF gbl_Speeds+D'7' 0013 00C3 MOVWF CompTempVar566 0014 0842 MOVF CompTempVar565, W 0015 00B3 MOVWF gbl_Speeds+D'4' 0016 00C4 MOVWF CompTempVar567 0017 0843 MOVF CompTempVar566, W 0018 00B4 MOVWF gbl_Speeds+D'5' 0019 00C5 MOVWF CompTempVar568 001A 0844 MOVF CompTempVar567, W 001B 00B1 MOVWF gbl_Speeds+D'2' 001C 00C6 MOVWF CompTempVar569 001D 0845 MOVF CompTempVar568, W 001E 00B2 MOVWF gbl_Speeds+D'3' 001F 00C7 MOVWF CompTempVar570 0020 0846 MOVF CompTempVar569, W 0021 00AF MOVWF gbl_Speeds 0022 0847 MOVF CompTempVar570, W 0023 00B0 MOVWF gbl_Speeds+D'1' Cheers Reynard
  8. Excellent news Pavel. Cheers
  9. Keith, If it just 5 unsigned ints of 0xFFFF, then what you have is probably the shortest for code space. If the compiler was a little more smarter it would only load the W register once with 0xFF and save you another 9 code words. Cheers Reynard
  10. I have been caught out recently by not reading the errata sheets, which Microchip have plenty off. Look at the Rev A1 sheet for the 18F4520 issue #23. It explains problems with fast interrupts which may give random operation. Cheers Reynard I should have said before, try using the linker option -isrnoshadow, which uses RAM to save the important registers rather than restore from the shadow registers (fast) for high priority interrupts. Dave and Pavel have been here before.
  11. ROM arrays of all data types. Well, maybe not float. Initialised rom structures as well. You could create an array of low and high bytes for you intergers, then read two consectuive bytes to rebuild the int. My current home project, a digital inclinometer for my archery, uses an array of 127 ints which I binary search to convert sensor output into degrees. Don't tell anyone, but I have moved to another compiler to get my array of ints. Shhhhhhh.
  12. Should the compiler save the FSR1 registers as well or can we assume the compiler libraries (called from an ISR) will never use this register(s). Should the call tree know which "general" registers are used and save context as appropriate ?
  13. Looking at the assembler code, only the high priority interrupt uses the fast stack to restore STATUS, W, BSR. The low priority saves these registers in ram. Check the assembler code to see that registers that are used in your interrupt functions are saved and are not being corrupted (used) by the high priority interrupt function. The interrupt handlers seem to save PRODH and PRODL for some reason. I assume TMR0IF is being cleared. Cheers Reynard
  14. Looking at the EEPROM spec this device does not use clock stretching so cannot have any effect on the SCL signal i.e. SCL is input only. This device is a 400kHz max clock. You need to look at the software and calculate what clock frequency your master is driving the I2C port. If you have a scope, check clock frequency and data SDA setup and hold times. Is your I2C interface hardware or software generated ? You may be in the wrong forum for RENESAS ICEs. Cheers Reynard
  15. Your nested for loops work for me. The listing file may not produce sequential code addresses but if you follow the instructions using sequential addressing it does work. Cheers Reynard
  16. if you go into Option and turn on all warnings I get : For issue 1. Using V6.84. warning: conversion from 'unsigned short' to 'unsigned char', possible loss of data warning: expression is always true success For issue 2. failure error: missing right paren error in 'if' expression error: missing right paren error: missing semicolon error: failure Cheers Reynard
  17. Like any programming language if the function you want is not available then roll you own. I use a 12F629 in a battery operated remote temperature sensor. Every 1 minute I power up from sleep, read the temperature from a Dallas DS75 I2C sensor, send serial data to a 433MHz transmitter, powerdown and go to sleep again. The reciver is another PIC (16F687) which has a real UART. It checks the data integrity and then emulated the DS75 using I2C to the master controller. I transmit 5 byte of data using a simple bit-bash method. void TransmitData(U16 temp) { . . . // Get ready to transmit. xmitDataPtr = transData.transArray; xmitByteCount = sizeof(transData.transArray); xmitState = 0; xmitBit = true; // set up xmit data for a start bit (1). xmitBusy = true; // say we are busy. tmr1h = (T1_05MS_RELOAD >> 8); // preload timer 1 count. tmr1l = T1_05MS_RELOAD & 0xff; t1con.TMR1ON = true; // start timer again. pie1.TMR1IE = true; // enable timer 1 interrupts. } /**************************************************************** * Interrupt Service Routine Entry Point. * ****************************************************************/ void interrupt (void) { union { U16 timerWord; U8 timerByte[2]; } timer; if (pir1.TMR1IF) { // timer 1 interrupt ? pir1.TMR1IF = false; t1con.TMR1ON = false; // stop timer. timer.timerByte[1] = tmr1h; timer.timerByte[0] = tmr1l; timer.timerWord += T1_05MS_RELOAD; tmr1h = timer.timerByte[1]; // preload timer 1 count. tmr1l = timer.timerByte[0]; t1con.TMR1ON = true; // start timer again. TransmitIsr(); } } /**************************************************************** * Transmit Interrupt Service Routine. * * Only to be called from the ISR in Kernel.c * ****************************************************************/ void TransmitIsr(void) { if (xmitBit) { // output serial data bit. portOutput |= XMIT_PORT_BIT; // set output = 1. } else { portOutput &= ~XMIT_PORT_BIT; // set output = 0. } gpio = portOutput; // update output port. switch (xmitState) { case 0: // output start bit. xmitByte = *xmitDataPtr++; xmitBitCount = 8; // set data bit counter. xmitBit = (xmitByte & 0x01) ? false : true; xmitByte >>= 1; ++xmitState; break; case 1: // output data bits. if (--xmitBitCount > 0) { xmitBit = (xmitByte & 0x01) ? false : true; xmitByte >>= 1; } else { xmitBit = false; // output stop bit next. ++xmitState; } break; case 2: // output stop bit. if (--xmitByteCount > 0) { // any more data to send ? xmitBit = true; // yes, output another start bit. xmitState = 0; // back to state 0; } else { ++xmitState; } break; case 3: // stop bit complete. xmitBusy = false; // transmit no longer busy. t1con.TMR1ON = false; // stop the timer. pie1.TMR1IE = false; // stop timer 1 interrupts. break; } // end switch. } Change the timer 1 reload value to change baud rate. I use 0.5ms per bit. My application is transmit only so if you want to recieve as well you will need to detect the start bit and do centre bit sampling. Half duplex as well. It may not be the best code, but food for thought. Cheers Reynard
  18. Don't forget anselh = 0 Do you have anything attached to port C pins ? The F690 has Schmitt inputs which have different thresholds than the F610 so may effect the bit clear and set instructions as they are read-modify-write. Does the produced assembler code look correct ? Cheers Reynard
  19. Dude, Your array was declared as being in RAM which is why the compiler put it there. You have to use the "rom" keyword if you want your data to be placed in ROM. The snag is that BoostC does not allow int arrays in ROM. I hope this will be addressed soon in a future release. It is one of the downfalls of BoostC. Accessing data in ROM is going to cost you more code space which will make you run out of code space as well. Cheers Reynard
  20. Hi fred, Each non-zero byte that you put into your array will cost you 2 instructions (load and store). The zero byte store is just a clrf instruction. Your array will cost 54 ROM locations to fill it up. Cheers Reynard
  21. Hi Keith, This compiler is a bit different than MSC. Prototypes are required if you do a forward reference to a function. If you are in the habit of using them, then always use them. I do. If you go to Settings - Options and enable All warnings the compiler will warn you if you exceed 255 for a delay. There is no default interrupt handler that I can see. Keep GIE = 0 if you don't want you program to go into the woods. If I was sharing a variable with main and interrupt, I would probably make it volatile. It all depends on how your main code is written and how many times the variable is used in main. The compiler may retain the variable value between uses and the interrupt may change its value between uses. You could always devise a semaphore type system. Hitec is a very good compiler if you can afford it. Other low cost ones are MikroC and Wiz-C. Cheers Reynard
  22. Hi Cridarco, Why are you putting millisecond delays within a timer interrupt handler as you have a timer to create delays for you. Interrupts should be in and out quickly. Let the main loop deal with any data the interrupt may have generated or collected. If you must have a ms delay in the interrupt then write your own. Copy the assembler instruction that delay_ms() creates and chang any variables used to another name. Or, just put a for-loop inside the interrupt to set the required delay. Better to avoid long interrupt functions. Cheers Reynard.
  23. In terms of less code size you could do this: if ( num==4 ) { portc.4 = state; // don't have to check its value, methinks } else { // if num==5 if you want portc.5 = state; } Or you could play with test_bit(), set_bit(), clear_bit(), maybe. Also, you it might be worth changing the value of num to the actual value of the port rather than one or two... that way you can check the state and do: if ( state ) set_bit( portc, num ); else clear_bit( portc, num );
  24. In this case should'nt it be x=45? OOps, I see youir point - my mistake I think 0x00 is a perfectly good result. You are shifting in a '0' from the left 8 times not rotating a char 8 times. Cheers Reynard
  • Create New...