Hi all,
I managed to get my interrupts working, and i have figured out a way to calculate the heart rate which is:
z = 60/(0.39*R7) = 153.84/R7 = 154/R7
But when i tried this formula, the LCD only display 77 BPM and 154 BPM. It seems that the overflow counter, R7, only count 1 - 2.
This is my code:
;*************************************** ;-----------INTERRUPT CONFIGURATIONS----------- ;*************************************** SETB EA ; Enable Global Interrupts SETB ET0 ; Enable Timer 0 Interrupt SETB EX0 ; Enable External Interrupt 0 SETB PX0 ; External Interrupt 0 High Priority ;*************************************** ;------------TIMER 0 CONFIGURATIONS------------ ;*************************************** TIMER_0 EQU 65535 SETB IT0 ; External Interrupt 0 detect falling-edge MOV TMOD,#01H ; Set Timer 0 to Mode 1 MOV A,CKCON ; Move CKCON to Accumualtor CLR ACC.3 ; Set system clock to divided by 12 MOV 70H,#00H ; Move 0 to 70H MOV R7,#02H ; Move 4 to R7 MOV 62H,#01H ; Move 1 to 62H MOV TH0,#HIGH TIMER_0 ; Set High Byte of Timer 0 MOV TL0,#LOW TIMER_0 ; Set Low Byte of Timer 0 ;********************** ;-Wait Until 4th Pulse- ;********************** WAIT: CJNE R7,#00H,WAIT ; Compare and jump to subroutine "WAIT" if R7 != 0 CLR TR0 ; Stop Timer 0 ;****** ;-Math- ;****** MATH: MOV A,#9AH ; Move 154 to A MOV B,70H DIV AB MOV R6,A ;********************** ;-External Interrupt 0- ;********************** EX_INT0: DJNZ 62H,COUNT ; Decrement 62H and jump if != 0 SETB TR0 ; Start Timer 0 COUNT: DEC R7 ; Decrement R7 RETI ; Return from Interrupt ;*********************** ;-Timer 0 Overflow Flag- ;*********************** T0_INT: INC 70H ; Overflow Counter MOV TH0,#HIGH TIMER_0 ; Reloads Timer 0 with High Byte MOV TL0,#LOW TIMER_0 ; Reloads Timer 0 with Low Byte RETI ; Return from Interrupt
Any advice would be greatly apprectiated.
This is only for one heart beat.
You want a high-resolution timer. That means that you can't just use the overflow value. Timer overflows too seldom. You should also use a couple of bits from the timer registers, until you have enough frequency/timer resolution.
Just using the overflow value wll mean that when measuring, you will not be able to get a continuous range of output values.
The external interrupt 0 code should check if enough # of pulse beats have been received, and then retrieve further bits of timer resolution.
Don't you think that maybe you should sometimes revisit your earlier threads and read the comments there, before starting new threads. The information you received then specifically said that you might extend the timer range with an overflow. It did not say that you should only use the overflow counter, and ignore the values of the timer.
By the way, why don't you label your variables? How fun is a source line that says:
INC 70H ; Overflow Counter
You have to add a comment just to keep track of what the memory cell 70H is used for, instead of naming the memory cell...
This is only for one heart beat. What do you mean by that? Are you not using the R7 register to count number of heart beats?
Think about the following line:
MOV R7,#02H ; Move 4 to R7
Exactly how good is it to write a comment that tries to duplicate the function of the actual instruction? Which one is "correct" - the value 2 in the instruction, or the value 4 in the comment?
What do you mean by that? Are you not using the R7 register to count number of heart beats?
Yea, R7 to count the number of heart beats. I see... I'll improve my commants next time... The value 2 is correct... I typed wrongly in the comments...
Your comments should describe why you do things, instead of trying to duplicate the instructions. That reduces the possibility of instructions and comments saying two different things. It also makes the comment meaningful.
Note that two beat intervals is a bit little because of normal variance in the heart frequency. Also, you must synchronize the timer start with a heart beat, or you will get a huge error - your time may be a full heart beat interval wrong if timer is started directly before or directly after a heart beat.
You write: Yea, R7 to count the number of heart beats. I see...
It almost sounds like this is not your code, and that you where not aware that R7 counted # of heart beats.
Ok i'll take note of that... Thanks...
Its my code!!! The "I see... " part is for the comments part that you said.
I wrote "This is only for one heart beat" because i noticed the error in the comments and is afraid that you all might mix it up...
I'm trying to test for one heartbeat first before moving on to 4 pulses.
But your code does not measure the time for one heart beat interval, even if you initialize your register to 2. It measures the time between two or three heart beats, i.e. it measures randomly between one and two intervals.
But your code does not measure the time for one heart beat interval, even if you initialize your register to 2.
Huh? I don't understand...
Don't the external interrupt detect falling edges? So if i initialize the register to 2, the 1st pulse will decrement R7 and the 2nd pulse will make it 0, than the program will stop the timer...
Sorry, my fault. You do start the timer in the ext1 interrupt routine.
Oh.. Its ok... Thanks for your help... ^^
One question...
Does the 8051 have a range for detecting pulses?
For example, below/above certain frequencies or below/above certain amplitudes... How can i check?
You need an ADC input and a lot of code to perform that.
Exactly what is your problem?
I just want to know does the 8051 have a tange for detecting pulses as in range of amplitude or range of frequencies...
Because when i tried inputting 0.7Vp-p, it cannot detect the pulses... When i input high frequencies like 5Hz or above, it does not detect the pulses too...
When using an interrupt input, you must supply a TTL-level signal, as explained in one of your earlier threads. Digital pins requires digital signals!
If the voltages are within range - and your chip has an ADC - you may also send in an analog value to one of the ADC inputs. Then you will have to figure out if the specific chip has capture/compare support to react to a specific level. If not, you will have to react to every single sample, and consider what to do.
The easiest solution - already mentioned - is to use an OP as comparator, to decide if your input signal should be considered high or low. Temporal filtering (in case the comparator may generate multiple pulses) can be implemented in the interrupt service routine.
I see... So i have to find out the range using those methods above? Thanks...