Of course!
http://au.element14.com/mill-max/090...83?Ntt=1279883
Cheers
Barry
VK2XBP
Of course!
http://au.element14.com/mill-max/090...83?Ntt=1279883
Cheers
Barry
VK2XBP
Interrupts can be very useful for many different purposes ... this isn't one of them.
In fact, interrupts will only slow things down and reduce the resolution of your readings.
A variation of what Henrik was describing might look like this ...
The resolution with WORD variables for the counts is 9uS (16F1783 running at 32Mhz internal OSC).
If the counters are BYTEs, the resolution is 3.5 uS, as measured in the simulator.
With interrupts, using a BASIC language ISR, that resolution will suffer greatly.
Code:DEFINE OSC 32 ANSELA = 0 ANSELB = 0 Results VAR BYTE[9] Res0 VAR Results[0] Res1 VAR Results[1] Res2 VAR Results[2] Res3 VAR Results[3] Res4 VAR Results[4] Res5 VAR Results[5] Res6 VAR Results[6] Res7 VAR Results[7] Res8 VAR Results[8] IOCA VAR BYTE IOCB VAR BYTE Testing VAR PORTC.0 IOCBP = $FF IOCBF = 0 CLEAR WHILE !Testing : WEND PAUSE 20 WHILE Testing IOCA = IOCAF IOCAF = 0 IOCB = IOCBF IOCBF = 0 Res0 = Res0 + IOCA.0 Res1 = Res1 + IOCA.1 Res2 = Res2 + IOCA.2 Res3 = Res3 + IOCA.3 Res4 = Res4 + IOCA.4 Res5 = Res5 + IOCA.5 Res6 = Res6 + IOCB.0 Res7 = Res7 + IOCB.1 Res8 = Res8 + IOCB.2 WEND
DT
HI All,
I am so glad I didn't show any of you my ISR code...it is embarrassing compared to what Darrel has just shared!
I also need to display results as they occur on a 4x20 LCD. There are two different display screens, one that gives a visual representation if a fault has occurred on any particular data line and another that displays actual fault counts for all nine lines. I don't know the timing requirements for LCDOUT statements but I am sure they will add considerably to the 9uS resolution with WORD variables. I could control the LCDOUT routine such that it only updates the LCD screen if a new fault has occurred. Is it possible to do a comparison using this pseudo-code:
Results VAR WORD[9]
OldResults VAR WORD[9]
IF Results <> OldResults THEN
Goto Display Routine ' break to the routine that updates the LCD screen
OldResults = Results ' Reset OldResults
ENDIF
Cheers
Barry
VK2XBP
Hi Barry
You can buy a Saleae for 119Euros. Accepted that you'll need an old laptop for display. It'll store billions of samples @ 24Mhz, thats at least a decade better that Darrel is suggesting, and he writes great code. How many samples before the PIC runs out of memory?1/. Towlerg: "Why not use a logic analyser?" - simply because I don't have one. I also need to replicate this test in other parts of the world so I don't think purchasing multiple logic analysers is a cost effective approach to solving the problem.
Anyways, good luck with the project.
George
Hi George,
Yes, there are always a number of different ways to "skin a cat" but if I went with the logic analyser route then I would have nothing to design and build using a PIC
If we end up with more than a byte's worth of fault counts on any of the nine data lines within a one minute test period then we have more problems to worry about than a PIC running out of memory!
Cheers
Barry
VK2XBP
Hi All,
I am still waiting for my PIC16F1783 chips to arrive so I have been doing some testing with a PIC16F1829.
I am getting good results but unsure if my code can be improved. Here is the stripped down version for comment.
Any suggested improvements would be greatly appreciated.Code:' Connect LCD D4 to RC4 (Pin 6) ' Connect LCD D5 to RC5 (Pin 5) ' Connect LCD D6 to RC6 (Pin 8) ' Connect LCD D7 to RC7 (Pin 9) ' Connect LCD RS to RC3 (Pin 7) ' Connect LCD E to RC2 (Pin 14) ' Connect Data Line 1 to RA0 (Pin 19) ' Connect Data Line 2 to RA1 (Pin 18) ' Connect Data Line 3 to RA2 (Pin 17) ' Connect Data Line 4 to RA3 (Pin 4) ' Connect Data Line 5 to RA4 (Pin 3) ' Connect Data Line 6 to RA5 (Pin 2) ' Connect Data Line 7 to RB4 (Pin 13) ' Connect Data Line 8 to RB5 (Pin 12) ' Connect Data Line 9 to RB6 (Pin 11) #CONFIG __config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _MCLRE_OFF & _BOREN_OFF __config _CONFIG2, _PLLEN_ON & _LVP_OFF & _WRT_HALF #ENDCONFIG OSCCON = %11110000 ; Fosc = 32MHz ; Clock determined by Fosc<1:0> Config Word DEFINE OSC 32 ; Define socillator as 32MHz ' Define LCD registers and bits Define LCD_DREG PORTC Define LCD_DBIT 4 Define LCD_RSREG PORTC Define LCD_RSBIT 3 Define LCD_EREG PORTC Define LCD_EBIT 2 Define LCD_BITS 4 Define LCD_LINES 4 PAUSE 500 ' Pause to initialise LCD Display ' Define program variables DisplayFlag var BIT DisplayFlag = 0 Counter1 var BYTE Counter2 var BYTE Counter3 var BYTE Counter4 var BYTE Counter5 var BYTE Counter6 var BYTE Counter7 var BYTE Counter8 var BYTE Counter9 var BYTE IOCA var BYTE IOCB var BYTE Counter1 = 0 Counter2 = 0 Counter3 = 0 Counter4 = 0 Counter5 = 0 Counter6 = 0 Counter7 = 0 Counter8 = 0 Counter9 = 0 ANSELA = 0 ' Disable PORTA ADC ANSELB = 0 ' Disable PORTB ADC ANSELC = 0 ' Disable PORTC ADC DACCON0.7 = 0 ' Disable DAC CM1CON0.7 = 0 ' Disable comparator 1 CM2CON0.7 = 0 ' Disable comparator 2 TRISC = %00000001 ' Set PORTC.0 and PORTC.1 as digital input TRISA = %00111111 ' Set PORTA as digital inputs TRISB = %01110000 ' Set PORTB.4-6 as digital inputs OPTION_REG.7 = 0 ' Enable Weak Pull-ups WPUA = %00111111 ' Pull-ups enabled on PORTA.0 - 5 WPUB = %01110000 ' Pull-ups enabled on PORTB.4 - 6 WPUC = %00000001 ' Enable PORTC.0 pull-ups IOCAP = %00111111 ' Enable IOC rising edge on PORTA.0-5 IOCBP = %01110000 ' Enable IOC rising edge on PORTB.4-6 IOCAN = 0 ' Disable IOC falling edge on PORTA IOCBN = 0 ' Disable IOC falling edge on PORTB Main: IOCA = IOCAF ' Save IOCAF to IOCA IOCB = IOCBF ' Save IOCBF to IOCB IOCAF = 0 ' Reset IOCAF IOCBF = 0 ' Reset IOCBF IF IOCA > 0 OR IOCB > 0 THEN ' Test if IOC Flags have changed DisplayFlag = 1 ' If so, set Display flag ENDIF Counter1 = Counter1 + IOCA.0 Counter2 = Counter2 + IOCA.1 Counter3 = Counter3 + IOCA.2 Counter4 = Counter4 + IOCA.3 Counter5 = Counter5 + IOCA.4 Counter6 = Counter6 + IOCA.5 Counter7 = Counter7 + IOCB.4 Counter8 = Counter8 + IOCB.5 Counter9 = Counter9 + IOCB.6 IF DisplayFlag = 1 THEN ' Go to Display subroutine if DisplayFlag set Gosub Display DisplayFlag = 0 ' Reset DisplayFlag ENDIF GOTO Main Display: LCDOUT $FE, $80, " Fault Status " LCDOUT $FE, $C0, "1. ", DEC3 Counter1, " 2. ", DEC3 Counter2, " 3. ", DEC3 Counter3 LCDOUT $FE, $94, "4. ", DEC3 Counter4, " 5. ", DEC3 Counter5, " 6. ", DEC3 Counter6 LCDOUT $FE, $D4, "7. ", DEC3 Counter7, " 8. ", DEC3 Counter8, " E. ", DEC3 Counter9 Return
Cheers
Barry
VK2XBP
Hi Barry,
First suggestion is very minor but still, clear IOCAF immediately after reading it, ieThe longer the time is between reading it and clearing it is the bigger the risk of missing an "event" is. In this case, as I said, very minor but still.Code:IOCA = IOCAF ' Save IOCAF to IOCA IOCAF = 0 ' Reset IOCAF IOCB = IOCBF ' Save IOCBF to IOCB IOCBF = 0 ' Reset IOCBF
Next suggestion is to really try to tweak the display routine. Measure how long it takes now, then tweak it and compare. You want to make it as quick as you possibly can.
With tweaking I mean things like not rewriting static information each update. Instead, write the static information ONCE and then only update/overwrite what's actually needs to be updated.
You could, for example, use the bits in IOCA and IOCB to determine which counters content actually needs updating on the display. A possible drawback of doing this is that the execution time of the routine isn't constant so it's hard to tell exactly how fast the system will be able to detects consecutive events on the same "line". At the very least, don't rewrite that [ Fault Status ] - waste of time ;-)
As the code is currently written, I think you can skip the DisplayFlag semaphore and just doBut you may have something else in there preventing you from doing that, I don't know.Code:IF IOCA > 0 OR IOCB > 0 THEN ' Test if IOC Flags have changed GOSUB Display ENDIF
Another possible option to flip it around and have the Display routine as part of your main code (with the flag indicating it needs updating) and then GOSUB the code that checks the interrupt flags. That way can insert a GOSUB at various places WITHIN the Display routine (and the rest of the main loop) in an effort to really catch multiple events on the same line.
/Henrik.
Bookmarks