Jump to content


  • Content Count

  • Joined

  • Last visited

Everything posted by fred

  1. thanks twomers! I never realized to set PEIE for TMR1 and it was entering the interrupt routine cause of TMR0 overflow and not of TMR1... That's also explains why the delay between tmr1 overflow and starting the tmr1 routine never exceeded my setting for TMR0..
  2. I'm having some strange results using timer1. In MPLAB I just discovered when TMR1IF is set and TMR1 already passed 0 it just continues stepping a 'while' in main() before jumping to interrupt().... Is this normal behaviour or am I doing something wrong probably? I'm running a 16F648A at 4MHz some examples: TMR1 at measurepoint-1 0xFCD6 it has the value of 0x88 at measurepoint-2 TMR1 at measurepoint-1 0xFF00 it has the value of 0xBA at measurepoint-2 TMR1 at measurepoint-1 0xFA00 it has the value of 0xA6 at measurepoint-2 void interrupt( void ) { //Handle timer1 interrupt if( pir1 & (1<<TMR1IF) ) { //////////////////////// // measurepoint 2 // //////////////////////// TMR1handler(); clear_bit( pir1, TMR1IF ); } //Handle timer0 interrupt if( intcon & (1<<T0IF) ) { // timer0 code clear_bit( intcon, T0IF ); } if( intcon & (1<<INTF) ) { // RB0 falling edge interrupt if (( bitno == 0 ) && ( stream.num == 0 )) { clear_bit( t1con, TMR1ON ); TMR1start( 0xFFFF + 0x50 - 889 ); //////////////////////// // measurepoint 1 // //////////////////////// lValue= 1; bitValPeriod= 0; buffer.num= 0; } clear_bit( intcon, INTF ); } return; } btw. something likes to happen also on the RB0 interrupt. Stimulus is generating a 1->0 pulse at 90000 ticks. the tickcounter says 90200 at the start of the the generated RB0 interruptroutine for this
  3. When I link my project in sourceboost it links succesfull with still remaining 3 free bytes for code (.. ) When I link the same thing within the MPLAB it fails "Too much code to fit in ROM, overfilled by:27 locations." I copied the linker options from the sourceboost IDE in MPLAB IDE. When I look at the linker execution lines sourceboost added extra options however which probably causes extra optimization when linking. any ideas?? (to be sure it's the linker I first did a complete build of the project in MPLAB IDE and the relinked from within sourceboost IDE) linker execution line in sourceboost IDE "C:\Program Files\SourceBoost\boostlink.pic.exe" /ld "C:\Program Files\SourceBoost\lib" libc.pic16.lib DAC.obj DAC_DEVICE.obj DAC_LPH7779.obj FR_EEPROM.obj FR_LIB.obj LCD_LPH7779.obj clock.obj sTimer.obj /t PIC16F648A /d "G:\development\DAC Control" /p DAC -swcs 6 2 BoostLink Optimizing Linker Version 6.84 linker execution line mplab IDE Executing: "C:\Program Files\SourceBoost\boostlink.pic.exe" "G:\development\DAC Control\DAC_LPH7779.obj" "G:\development\DAC Control\FR_EEPROM.obj" "G:\development\DAC Control\FR_LIB.obj" "G:\development\DAC Control\LCD_LPH7779.obj" "G:\development\DAC Control\sTimer.obj" "G:\development\DAC Control\clock.obj" "G:\development\DAC Control\DAC.obj" "G:\development\DAC Control\DAC_DEVICE.obj" "C:\Program Files\SourceBoost\Lib\libc.pic16.lib" -O1 -p "DAC" -t 16F648A -swcs 6 2 BoostLink Optimizing Linker Version 6.84 the -O1 option was already there, I added the -swcs 6 2
  4. Orin the only references I have to opion_reg are in the init part at the start of main() set_bit( option_reg, PSA ); clear_bit( option_reg, T0CS ); clear_bit( option_reg, 7 ); // disable pullups clear_bit( option_reg, INTEDG); // falling edge I realize that the beginning might be destroyed by noise. What happens when I have a 'low' situation due to noise at the time a RC5 pulse train starts.. Pretty unpredicatble I think! What I'll do is validating the very first pulse duration which always should be a 1778us one. If that happens I'll ignore the rest of the train that has started apparently until the first overflow occurs and set IRreset. Hopefully this pulse train is immeditaley followed by a clean one.. I will check this first and see what the new results will be. fred [update edit] I introduced a variable streamValid. This one is set to false if the interval between the first two falling edges is outside the tollerance of 1778us. (GetIRSampleType( tmr1int ) != 1 ) From that point the values are not captured anymore and after the overflows occurs (end of pulse train) the sequence is to be considered as invalid at the start of the decode procedure. the ISR code and first lines of RC5decode() now looks like this void IR_ISR_handler( void ) { uint tmr1int; if ( (IRstreambit == 0xff) || (resetIR==1)) return; if ( IRstreambit > IRMAXPULSES ) { resetIR= 1; return; } tmr1int= StopTmr1()- TMR1BASE; if ( tmr1overflow == 1 ) { StartTmr1( 0xD8FF ); return; } clear_bit( intcon, INTE ); if ( tmr1overflow > 1 ) { if ( IRstreambit >= IRMINPULSES ) { IRstreambit= 0xff; } else { resetIR= 1; } return; } if ( IRstreambit > 0) { if (( IRstreambit == 1 ) && ( GetIRSampleType( tmr1int ) != 1 )) streamValid= 0; if ( streamValid ) { IRstream[IRstreambit- 1]= tmr1int; } } IRstreambit++; StartTmr1( TMR1BASE ); return; } // TMR1BASE is more or less the calculated value of 0xFFFF - (2*1778) - ( 1778 / 4 ) void RC5decode() { if ( IRstreambit != 0xff ) return; if (( resetIR ) || ( !streamValid )) { resetIR= 1; return; } //time to decode the captured stream of falling edges at this point! The first byte of the IR train pulses now look valid. In case when the toggle bit is '0' the long and medium sized interval are still reversed which is an invalid situation so decoding this one will always fail. I'm also still missing the last pulse. the result of this is that for most values the captured stream is valid as ok but decoding will give wrong results. for instance: A '0' press will return a command '1', a '1' press =>command 3, press'4' => command 0xd, press'6' => command also 0x0d. [/update]
  5. the timer is only enabled in StartTmr1() which is only called from within IR_ISR_handler() so it isn't running at the start. And if it would then the whole stream starts with timeroverflow set which will end the capturing immediately. in the main loop - IRstreambit is checked. when it has the value of 0xff (set in IR_ISR_handler()) the capturing has finished succesfully (hm. ) and the array content will be decoded outside the interrupts. At the end of the decoding resetIR is set - resetIR is checked. when it's set all used variables and the array will be reset, timer1 stopped (possibly again) and finally enabling INTE. that's why I was stopping INTE at the start of IR_ISR to prevent new interrupts coming in between leaving the interrupt handling and resetting the array before the content could be decoded when relevant. You are right : At a first glance it doesn't look so bad. That's the bizar thing... If you look at the picture you will see that there should be 9 times 1712us after the longer pulse however. there are only 8 so one is missing ervery time..! Another strange one which theroretical is impossible but a bit harder to explain: the value of 3515 can never be follwed by 2667 at this time. the value of 3515 (=2 periods with only a falling edge at the end) can never start at the beginning of a period!! in a period you always have to deal with a 0->1 or 1->0. if this value starts at the start of a period it would be 0->0 which is impossible in a biphase coding..! As you can see in the picture there should always be a 2667 (1.5 period) and a 3515 combination with toggle '1' and machine code x10 after the two initial startbits ps. I'm very happy that someboby is looking with me at this problem because the whole ting is driving me crazy.. It's probably a simple and stupid thing but I just don;t see it. Thanks!! Fred
  6. I will make that change. Unfortunately I don't beleave this is what is going on in my situation and solving my problem however. I'll try to illustrate what's happening (oops this is getting a bit off topic now. Hopefully this is not a big problem and the moderator will let it go or move it to a new topic because I get bogged on this..!) With this code I'm capturing (at least I'm trying to.. ) the time intervals of falling edges when receiving an IR RC% pulse train. When the stream is valid I can only distinguish 3 type of intervals: 1778us (1 period), 2667us (1.5period) or 3556us (2 periods) My IRsender sends IR using machine code 16. Here I illustrate what pulses theoratical are on rb0 when pressing the button '0' two times. (the toggle bit - bit3 - flips when the same key is pressed once more) Now what''s happening in real live... I press 3 times. After each time the captured array (containing the timer1 values) is displayed. (this results include the adjustments Orion suggested) The results are shown in this picture after subtracting the offset (TMR1BASE in de code which has the value of 4000) the values represents the usecs: (1712 is the average value to let it look like a bit less messy. the least min value is 0x1643 and the max is 0x165E. so the variation is max 27 which is pretty accurate I think) This looks bizar to me and I must make somewhere a verry fundamental mistake... - The very first element seems to be pretty unreliable.. - each next indiviual element just look to be valid which can't be occasional or a noise issue.. - after the '2' type the stream looks very good but except I'm missing one more pulse everytime.. - when the toggle bit is '1' the '3' and '2' interval types are reversed When I repeat the same captures more times the results stay the same! Except the very first element varies. I also tried another remote control and the results are similar. I get a bit frustrated by now because I think (uptil now ) the alorithm I made is pretty nice but apparently I can't get it implemented.
  7. I think you're right about INTE. This is because I added if ( tmr1overflow ) resetIR= 1; else IR_ISR_handler(); recently during it's interrupt. Before that it could be relevant. I'll put it on comment. StartTmr1 en StopTmr1 looks like this void StartTmr1( unsigned int numval ) { _cnvint_ value; value.num= numval; tmr1h= value.hl.hi; tmr1l= value.hl.lo; set_bit( t1con, TMR1ON ); return; } inline uint StopTmr1(void) { _cnvint_ value; uint numval; clear_bit( t1con, TMR1ON ); value.hl.hi = tmr1h; value.hl.lo = tmr1l; numval= value.num; return(numval); } fred
  8. Hi Orin it's a 16F648A receiving an infrared RC5 signal on rb0 What basically happens is this: void interrupt( void ) { //Handle timer1 interrupt if( pir1 & (1<<TMR1IF) ) { if (( IRstreambit > 0 ) && ( IRstreambit != 0xff )) { tmr1overflow+= 1; IR_ISR_handler(); } clear_bit( pir1, TMR1IF ); } //falling edge portB.0 if( intcon & (1<<INTF) ) { if ( tmr1overflow ) resetIR= 1; else IR_ISR_handler(); clear_bit( intcon, INTF ); } return; } void IR_ISR_handler( void ) { uint tmr1int; if ( (IRstreambit == 0xff) || (resetIR==1)) return; if ( IRstreambit > IRMAXPULSES ) { resetIR= 1; return; } clear_bit( intcon, INTE ); tmr1int= StopTmr1(); if ( tmr1overflow > 0 ) { if ( tmr1overflow == 1 ) { StartTmr1( 0xD8FF ); } else { if ( IRstreambit >= IRMINPULSES ) { IRstreambit= 0xff; } else { resetIR= 1; } } return; } if ( IRstreambit > 0 ) { IRstream[IRstreambit- 1]= tmr1int; } IRstreambit++; StartTmr1( TMR1BASE ); set_bit( intcon, INTE ); clear_bit( intcon, INTF ); return; } IR_ISR_handler() is called within each interrupt. During the time that one of the interrupts is handled I want to have a status quo situation. I'm pretty struckling with this 'project' for some time now because I'm getting some strange timing results and really can't find what's happening until now. When I use stimilus (MPLAB) to simulate a RC5 pulse train on rb0 and which is generating these interrupts, everything looks pretty well but in 'real live' it isn't and I don't think it's a circuit problem either. So when I read something like then I'm more than curious if that's relevant here aswell
  9. The routine can be called from within two interrupts: 1/ timer1 2/ rb0 falling edge during handling from a timer1 interrupt a rb0 interrupt might occur or a timer1 interrupt in the situation it's handling the falling edge interrupt. To prevent this I'm just disabling both interrupts at the start of the routine and reactivate them at the end
  10. I'm using the MPLAB environment in combination with sourceboost IDE just for one functionality: 'Stimilus' next to their debugger It's a perfect way to simulate a pulse train on a pin to find some hard to track problems. Their solution to specify such a 'train' is horrible however and it should not be so hard to do a better job doing this (I think... ) Would be great to have something similar in Sourceboost IDE!
  11. Oops, there is a problem starting interrupts gain within an interrupthandler? I'm using a common interrupt handler for TMR1 and RB0. At the beginning of the handler I stop both interrupts and at the end I start them both again. This can give problems? Is there an easy way to get around that? I can't use flags to start them again later somewhere in main() because there 's a chance to miss an interrupt or run into timing problems then. [edit]hmm sorry Chris, I hope I'm not stealing your topic now..![/edit]
  12. it's working. Less work than expected... thnx mark
  13. I want to use the mplab debugger for a project. Is there a way to convert\integrate existing project file(s) to mplab or do I really have to build separate mplab projects from scratch?
  14. hm, put it in eeprom using #pragma and then move it to ram initially at runtime takes probably less space. ugly solution however.
  15. huh.... that's new to me and I'm\ confused now. isn't this something which is done by the compiler when the aray space is preserved in the data area? I thought that this is the major difference between defining char *array and char array[15] where the first is only the pointer and the 2nd pointing to the allocated data space! So defining a big character table doesn't only cost a lot of data space but even more code to have it initialized even when it's all static data?
  16. I have an array of ints. without initializing the array the linker reports free 40 words ROM initializing costs 66 words...? uint IRstream[15]; // free 40 words //changing the line above in uint IRstream[15]={ 63507,3507, 63507, 63507, 63507, 63507, 63507, 63507, 63507, 63507, 63507, 63507, 0,0,0 }; // too much code to fit in ROM, overfilled with 20 locations.... ??
  17. Dave, Unfortunately the "Code window Function" is not there when linking fails (Sometimes I temporarely put some code on comment to get that window generated..) I only use int's when I really need them. (that's not often!) For conversions between the two I created this construction which appears to be very efficient. in combi with timer1: typedef union { unsigned int num; struct { unsigned char lo; unsigned char hi; } hl; } _cnvint_ cnvint; int value; cnvint.hl.lo= tmr1l; cnvint.hl.hi= tmr1h; value= cnvint.num; this one is a bit harder for me however.. I expect that simple loops like this do contain a relatively lot of overhead and are probably more efficient to create using inline asm (when you know how to.. ) unsigned char i; volatile bit signalOn@ for( i= 100; i; i--) { delay_us(10); if ( signalOn ) break; }
  18. I'm working on a 'project' which reaches the available 4K code space limits of the 16f648. The problem is that it's not 100% bug free yet (is this even possible.. ) so sometimes I have to add\change a line of code. This brings me immediately into new problems because the linker will fail then because of overfilling the available memory with some words.. It appears to be very difficult to gain some bytes by rewriting peaces of code. I already changed some algorythms and did some recoding. Sometimes I rewrite a line - having the idea it's more efficient - and instead of gaining something I'll lose 80 bytes or it doesn't make any diffrence. The behaviour looks pretty unpredictable sometimes. Probably I'm just exceeding a boundary or so somewhere which gives a big boost in gaining\loosing bytes. Does somebody have some tips which can help me to find the very last bytes of code space ...
  19. Roger!!! thanks uhhh, so delay_us(0) results in 0.01ms + (0 * 0.001ms) = 10us..!?
  20. I'm running at 4000000 clock and using a delay_us( 10 ); Boostc gives me the warning Caution: Delay inaccurrate: 'delay_us', Delay overhead:0.01ms, Unit delay:0.001ms How do I interpret the overhead and unit delay....? delay_us( 1 ) -> 12us delay_us(12) -> 23us delay_us(13) -> 24us or delay_us(1) -> 12us delay_us(12) -> 12us delay_us(13) -> 13us or ???
  21. set breakpoints in the debugger at the beginning and end of the code you want to evaluate. in the debugger you can see the amount of ticks. so when you let it run from breakpoint to breakpoint you are able to see how manny ticks it took. If I don't oversee something here ( ) this should be a working method to determine the exact time it takes to run that peace of code.....
  22. probably using a two switch construction then because copying to a buffer first doesn't help me much to save memory in this situation. The real used tables are a larger as shown in my example.. ok, thanks
  23. I have several arrays (LCD bitmaps) stored in rom memory because there is not enough ram to hold them all. Optimized my code as much as possible but still running out of rom memory a little bit unfortunately.... There's enough ram left to move a few of the arraytables back to ram which would solve my problem. In a switch construction I'm assigning the appropriate table to a variable but here I have to deal with the problem that the types do not match anymore.. to illustrate my problem rom unsigned char *lcd_CW16bData1 = { 0x0,0x88, 0x1,0x10, 0x2,0x20, 0x70,0x40, 0xF8,0x86, 0x0,0x0, 0x0,0x0 }; rom unsigned char *lcd_CW16bData2 = { 0x0,0x88, 0x1,0x10, 0x2,0x20, 0x70,0x40, 0xF8,0x86, 0x0,0x0, 0x0,0x0 }; rom unsigned char *lcd_CW16bData3 = { 0x0,0x88, 0x1,0x10, 0x2,0x20, 0x70,0x40, 0xF8,0x86, 0x0,0x0, 0x0,0x0 }; unsigned char lcd_CW16bData99[14] = { 0x0,0x88, 0x1,0x10, 0x2,0x20, 0x70,0x40, 0xF8,0x86, 0x0,0x0, 0x0,0x0 }; //etc. rom unsigned char *table; switch (condition ) { case 0: table= lcd_CW16bData1; break; case 4: table= lcd_CW16bData2; break; case 5: table= lcd_CW16bData3; break; default: table=lcd_CW16bData99; // etc. }; display(table); In this example I moved lcd_CW16bData99 from rom to Ram data. This generates the next error(s) warning: conversion from 'unsigned char[]' to 'rom unsigned char*' internal error: failed to generate assignment expression error: failed to generate expression Is there a (simple) way to get around this..?
  24. Ok Dave. Your reply gives me enough answer.. Sometimes it's a bit hard to explain the exact situation briefly and I understand that this example is a bit cryptic but in the basis it covers pretty much what I'm doing. (hm, is this english.. )
  • Create New...