{
h= (ADC0>>4);
for(l=0; l<127; l++)
{
if(p<h+5)
{
p=h;
}
else
{
n=s;
break;
}
}
for(l=0; l<127; l++)
{
if(p>h-1)
{
p=h;
}
else
{
break;
}
}
for(l=0; l<127; l++)
{
if(p-1<h)
{
p=h;
}
else
{
a=s;
break;
}
}
v=a-n;
b =v*0^01;
f = (1/b)*60;
for (l=0; l<127; l++)
{
if(p>h-1)
{
p=h;
}
else
{
break;
}
}
}
}
{
h= (ADC0>>4);//initialisation for ADC0
for(l=0; l<127; l++)//For loop for sampling till peak is reached and after that break out of loop in else function.
{
if(p<h+5)//if old ADC0 value<Current ADC0 value+5
{
p=h; //Old ADC0 value=Current ADC0 Value
}
else
{
n=s;//Int variable to store value from running overflow counter at first peak
break;//Break out of for loop and move on to next for loop
}
}
for(l=0; l<127; l++)//For Loop to sample till bottom of sin wave is reached.
{
if(p>h-1)//If Old ADC0 value is more > current ADC0 value-1, Old ADC0 value = New ADC0 value.
{
p=h;
}
else
{
break;//Break out of for loop
}
}
for(l=0; l<127; l++)//For loop for continues sampling until peak is reached
{
if(p-1<h)//Same as previous peak detection loop.T his time i am storing the counter value in another int variable to calculate time elapsed between two peaks.
{
p=h;
}
else
{
a=s;
break;
}
}
v=a-n;//Time between two peaks of sin wave
b =v*0^01;//My counter s shows number of overflows my timer0 has, and for a single overflow it takes timer0 10ms, therefore i am converting the time to seconds as opposed to ms.
f = (1/b)*60; //1/T*60 for calculation of beats per minute.
for (l=0; l<127; l++)//This for loop is to bring Old ADC0 value back to bottom of sin wave before the whole process can be repeated.
{
if(p>h-1)
{
p=h;
}
else
{
break;
}
}
}
}
As for the question on why (p>h-1), i did it so that there is a threshold to be reached before the calculations begin
as opposed to putting (p>h).
if(p > h -1) {
p = h;
}
if(p > h) {
p = h;
}
if(p<h+5)//if old ADC0 value<Current ADC0 value+5
if(p<h+5)
#define SIG_HYS 5
if(p < h + SIG_HYS) {
Hi Dora!Hello!
I have just demonstrated above that:
is equivalent to:Code:if(p > h -1) { p = h; }
Therfore thers is no opposition between f(p > h -1) p = h and if(p > h) p = h. It's the same!!! Read my example again.Code:if(p > h) { p = h; }
Now you should consider replying to my first question: what are you trying to do?
The reply should not be "Coding for storing 2 values at different intervals from counter time" but more something like
"Try to measure the time difference between 2 peaks". Note that I'm not sure of this, it's an example.
Beside this, you have added comments, which is good, but most of them are almost useless.
Example:
Code:if(p<h+5)//if old ADC0 value<Current ADC0 value+5
I know what "if(p<h+5)" means, so the comment is useless. The problem is: why are you doing this test? Why
ADC0 value + 5 and not ADC0 value + 69 or -45? Where does this +5 come from? That should be explained in
your comments. Comments' purpose is not to translate C into english, but to explain what you do.
It's not mandatory to have one comment per line. The best is to find an explanation that explains what you do
in plain english.
And while I'm writing this, here is another advice: Never use hard-coded constants.
Code:if(p<h+5)
If this 5 has a well-defined meaning (for example some kind of hysteresis), then define a constant
Code:#define SIG_HYS 5 if(p < h + SIG_HYS) {
And to make it clear: don't use variables like p, v, n. If you read your code in 3 months from now, you will not even
understand it yourself. And don't use l as a variable because it can be confused with I (capital i) or even with 1.
And don't use capital I either.
Dora
(p<h+5)
As for the Value why it is +5 or -1
because i found it to be most effective to removing any other interference
could be a btr header
Loop {
Get sample;
Calculate variation since last sample;
If variation was positive AND is now negative AND greater than a preset theshold {
Store current time
Calculate difference with previous time, calculate bps, display result, etc
Update previous time stamp for next time
}
}
/*
Graphic LCD 64 by 128 pixels, Monochrome
SP5-GFX1
Connection to P2 of 8051 : Silicon Lab C8051F340
#1 GND
#2 +5V
#3 SI serial data -- P2.7
#4 SCL serial clock -- P2.6
#5 A0P 0 = select control, 1 = data port --- P2.5
#6 RESET low to reset LCD panel -- P2.4
#7 CS1 chip select, 0 = enable data transfer -- P2.3
#8 BL- Back light - GND
#9 BL+ Back light - +5V
Page memory for display : B0 to B7, eight pages, one page 128 bytes
each byte for 8 rows x 1 column, bit 0 at row 0, bit 1 at row 1 etc.
last edited : 15 Jan 2015.
Version 1.0
*/
//#include <reg51.h>
#include <c8051f340.h> // SFR declarations
#include "stdio.h"
//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------
#define SYSCLK 12000000 // SYSCLK frequency in Hz
sfr16 ADC0 = 0xbd; // ADC0 result register
sfr16 TMR2RL = 0xca; // Timer2 reload value
sfr16 TMR2 = 0xcc; // Timer2 counter
/*
sbit LCD_SI = P2^1;
sbit LCD_SCL = P2^2;
sbit LCD_A0P = P2^3;
sbit LCD_RESET = P2^4;
sbit LCD_CS1 = P2^5;
*/
sbit LCD_SI = P2^7;
sbit LCD_SCL = P2^6;
sbit LCD_A0P = P2^5;
sbit LCD_RESET = P2^4;
sbit LCD_CS1 = P2^3;
int i,j,k,m,s,p,n,l,a,v,b,f,h,x;
char fp[6];
char sp[6];
p = 0;
s = 0;
a = 0;
v = 0;
b=0;
n=0;
f=0;
x=1;
// 5 columns by 8 rows ASCII font, starting from SPACE, 0x20
code unsigned char font[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5f,0x00,0x00, // !
0x00,0x03,0x00,0x03,0x00,0x14,0x7f,0x14,0x7f,0x14, // "#
0x24,0x2a,0x7f,0x2a,0x12,0x23,0x13,0x08,0x64,0x62, // $%
0x36,0x49,0x55,0x22,0x50,0x00,0x05,0x03,0x00,0x00, // &'
0x00,0x1c,0x22,0x41,0x00,0x00,0x41,0x22,0x1c,0x00, // ()
0x14,0x08,0x3e,0x08,0x14,0x08,0x08,0x3e,0x08,0x08, // *+
0x00,0x50,0x30,0x00,0x00,0x08,0x08,0x08,0x08,0x08, // ,-
0x00,0x60,0x60,0x00,0x00,0x20,0x10,0x08,0x04,0x02, // ./
0x3e,0x51,0x49,0x45,0x3e,0x00,0x42,0x7f,0x40,0x00, // 01
0x42,0x61,0x51,0x49,0x46,0x21,0x41,0x45,0x4b,0x31, // 23
0x18,0x14,0x12,0x7f,0x10,0x27,0x45,0x45,0x45,0x39, // 45
0x3c,0x4a,0x49,0x49,0x30,0x01,0x71,0x09,0x05,0x03, // 67
0x36,0x49,0x49,0x49,0x36,0x06,0x49,0x49,0x29,0x1e, // 89
0x00,0x36,0x36,0x00,0x00,0x00,0x56,0x36,0x00,0x00, // :;
0x08,0x14,0x22,0x41,0x00,0x14,0x14,0x14,0x14,0x14, // <=
0x00,0x41,0x22,0x14,0x08,0x02,0x01,0x51,0x09,0x06, // >?
0x32,0x49,0x79,0x41,0x3e,0x7e,0x11,0x11,0x11,0x7e, // @A
0x7f,0x49,0x49,0x49,0x36,0x3e,0x41,0x41,0x41,0x22, // BC
0x7f,0x41,0x41,0x22,0x1c,0x7f,0x49,0x49,0x49,0x41, // DE
0x7f,0x09,0x09,0x09,0x01,0x3e,0x41,0x49,0x49,0x7a, // FG
0x7f,0x08,0x08,0x08,0x7f,0x00,0x41,0x7f,0x41,0x00, // HI
0x20,0x40,0x41,0x3f,0x01,0x7f,0x08,0x14,0x22,0x41, // JK
0x7f,0x40,0x40,0x40,0x40,0x7f,0x02,0x0c,0x02,0x7f, // LM
0x7f,0x04,0x08,0x10,0x7f,0x3e,0x41,0x41,0x41,0x3e, // NO
0x7f,0x09,0x09,0x09,0x06,0x3e,0x41,0x51,0x21,0x5e, // PQ
0x7f,0x09,0x19,0x29,0x46,0x46,0x49,0x49,0x49,0x31, // RS
0x01,0x01,0x7f,0x01,0x01,0x3f,0x40,0x40,0x40,0x3f, // TU
0x1f,0x20,0x40,0x20,0x1f,0x3f,0x40,0x38,0x40,0x3f, // VW
0x63,0x14,0x08,0x14,0x63,0x07,0x08,0x70,0x08,0x07, // XY
0x61,0x51,0x49,0x45,0x43,0x00,0x7f,0x41,0x41,0x00, // Z[
0x02,0x04,0x08,0x10,0x20,0x00,0x41,0x41,0x7f,0x00, // \]
0x04,0x02,0x01,0x02,0x04,0x40,0x40,0x40,0x40,0x40, // ^_
0x00,0x01,0x02,0x04,0x00,0x20,0x54,0x54,0x54,0x78, // `a
0x7f,0x48,0x44,0x44,0x38,0x38,0x44,0x44,0x44,0x20, // bc
0x38,0x44,0x44,0x48,0x7f,0x38,0x54,0x54,0x54,0x18, // de
0x08,0x7e,0x09,0x01,0x02,0x0c,0x52,0x52,0x52,0x3e, // fg
0x7f,0x08,0x04,0x04,0x78,0x00,0x44,0x7d,0x40,0x00, // hi
0x20,0x40,0x44,0x3d,0x00,0x7f,0x10,0x28,0x44,0x00, // jk
0x00,0x41,0x7f,0x40,0x00,0x7c,0x04,0x18,0x04,0x78, // lm
0x7c,0x08,0x04,0x04,0x78,0x38,0x44,0x44,0x44,0x38, // no
0x7c,0x14,0x14,0x14,0x08,0x08,0x14,0x14,0x18,0x7c, // pq
0x7c,0x08,0x04,0x04,0x08,0x48,0x54,0x54,0x54,0x20, // rs
0x04,0x3f,0x44,0x40,0x20,0x3c,0x40,0x40,0x20,0x7c, // tu
0x1c,0x20,0x40,0x20,0x1c,0x3c,0x40,0x30,0x40,0x3c, // vw
0x44,0x28,0x10,0x28,0x44,0x0c,0x50,0x50,0x50,0x3c, // xy
0x44,0x64,0x54,0x4c,0x44,0x00,0x08,0x36,0x41,0x00, // z{
0x00,0x00,0x7f,0x00,0x00,0x00,0x41,0x36,0x08,0x00, // |}
0x10,0x08,0x08,0x10,0x08,0x00,0x00,0x02,0x05,0x02 }; // ^degree
//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------
void delay(int d); // delay by d ms
void delaya(void); // a short delay
void SYSCLK_Init (void); // set CPU clock
void PORT_Init (void); // init CPU ports
void LCD_reset(void); // reset LCD
void LCD_command(unsigned char); // Send command code to LCD
void LCD_data(unsigned char); // ASCII character to be displayed on LCD
void SPI_send(unsigned char); // shift 8 bit data to LCD interface, high bit first
void write_char(unsigned char); // display an ASPI intSCII code at current position
void write_msg_xy(unsigned char, unsigned char, unsigned char*); // write strting at x col, y row
void set_xy(unsigned char x, unsigned char y); // set cursor position
void plot_xy(unsigned char x, unsigned char y);
//-----------------------------------------------------------------------------
//void timer0_interrupt(void) interrupt 1 using 1 //auto reload every 50us
//{
//}
void LCD_Clear_Display()
{
for(k=0; k<8; k++) // clear display
{
LCD_command(0xB0 + k); delay(20);
LCD_command(0x10); //high nibble of column address
LCD_command(0x00); // low 4 bits of column address
for(i=0; i<128; i++)
{
LCD_data(0x00);
}
}
}
void delay(int d) // delay for d ms
{
int i, j;
for(i=0; i<d; i++)
for(j=0; j<1179; j++);
}
void delaya() //a short delay
{
char j;
for(j=0; j<1; j++);
}
void timer0_interrupt_init()
{
TMOD = 0x01;
// TR0 = 0;
//TL0 = 0xEF;
//TH0 = 0xD8;
TR0 = 1;
EA = 1;
ET0 = 1;
// while(TF0==0);
//TF0 = 0;
}
void timer0 (void) interrupt 1
{
s++;
// sp = &s;
TL0 = 0xEF; //lower bit
TH0 = 0xD8; //higher bit
TF0 = 0;
}
void main (void)
{
PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer
// enable)
PORT_Init(); // Initialize Port I/O
SYSCLK_Init (); // Initialize Oscillator
// ADC init.
ADC0CN = 0x00; // ADC0 disabled, normal tracking,
// conversion triggered on TMR2 overflow
REF0CN = 0x03; //Internal voltage reference for ADC
AMX0P = 0x00; // 0x05=P2^6.. 0x13 ADC0 positive input = P1.1
AMX0N = 0x1F; // ADC0 negative input = GND
// i.e., single ended mode
ADC0CF = ((SYSCLK/3000000)-1)<<3; // set SAR clock to 3MHz
ADC0CF |= 0x00; // right-justify results
AD0EN = 1;
// SFRPAGE = TIMER01_PAGE; // Set SFR page
/*
TH0 = -151; // -149; // Init Timer0 High register
TL0 = TH0; // Set the intial Timer0 value
ET0=1; // Timer0 interrupt enabled
TCON = 0x10; // Timer0 ON
// TMOD = 0x02; // Timer0 in 8-bit reload mode
EA = 1; // allows interrupt
*/
//delay(200);
// initialize graphic LCD, set 8x8 fonts and graphic, OR mode for text and graphic
LCD_reset();
LCD_command(0xA2); // LCD bias, 1/9 bias
LCD_command(0xA0); // set normal display mode
LCD_command(0xC8); // set output mode
LCD_command(0x23); // set voltage regulator internal resistor
LCD_command(0x81); // electronic voltage double - two byte instruction
LCD_command(0x1D); // 6 bits, 0 to 0x2F, increase contrast
LCD_command(0x2B); // set power control circuit
LCD_command(0x40); // set start line = 0
LCD_command(0xAF); // setdisplay on
LCD_command(0x10); // lower 4 bits for high nibble of column address, 0 to 127
LCD_command(0x00); // lower 4 bits for low nibble of column address
LCD_command(0xB0); // set page address, B0 to B7 for 8 pages
LCD_Clear_Display(); //clear LCD screen
write_msg_xy(0, 0, "BVP(C)2015 NYP/BEMG 70BPM");
delay(30);
// enable timer interrupts
// ET0=1;
// TMOD=0x21;
// TR0=1;
// EA=1;
while(1)
{
timer0_interrupt_init();//initialise timer0 mode1
for(k=0; k<127; k++)
{
m= 63 - (ADC0>>4); //take high 6 bits from the 10-bit adc
plot_xy(k, m);
plot_xy(k, m-1); // add two more dots for thicker lines
plot_xy(k, m+1);
delay(30);
AD0BUSY = 1; // start ADC conversion
/*
if ((k & 0x1F) == 0 ) //draw straight lines
{
for(j=0; j<4; j++)
{
set_xy(k,4+j);
LCD_data(0xFF);
}
}
*/
{
//h= (ADC0>>4);
// for(l=0; l<50; l++)
while(1)
{
h= (ADC0>>4);
SPI_send;
LCD_reset;
LCD_command;
LCD_data;
write_msg_xy;
plot_xy;
set_xy;
if(p<h+4) p=h;
else
{
n=s;
break;
}
}
//for(l=0; l<50; l++)
while(1)
{
h= (ADC0>>4);
SPI_send;
LCD_reset;
LCD_command;
LCD_data;
write_msg_xy;
plot_xy;
set_xy;
if(p+1>h) p=h;
else break;
}
//for(l=0; l<50; l++)
while(1)
{
h= (ADC0>>4);
SPI_send;
LCD_reset;
LCD_command;
LCD_data;
write_msg_xy;
plot_xy;
set_xy;
if(p<h+4) p=h;
else
{
a=s;
break;
}
}
v = a-n;
b = v/100;
f = 60/b;
//for(l=0; l<50; l++)
while(1)
{
h= (ADC0>>4);
SPI_send;
LCD_reset;
LCD_command;
LCD_data;
write_msg_xy;
plot_xy;
set_xy;
if(p+1>h)
{
p=h;
}
else
{
break;
}
}
}
//delay(30);
} LCD_Clear_Display();
//sprintf(sp,"%4D",b);
//write_msg_xy(100, 55, sp);
} // end while(1)
} // end main
// configure I/O ports
void PORT_Init (void)
{
/*
P1SKIP=0x20;
P1MDOUT = 0x0F;
P2MDOUT = 0x3F;
// P3MDOUT = 0xFF; // for ULN2803 drivers
// P4MDOUT = 0xFF;
// P0MDOUT = 0xFF; // for LTC1298, LCD interfaces
P2MDIN &= 0x0BF; // P2.6 as ADC0
P0MDOUT |= 0x10; // Enable UTX as push-pull output
XBR0 = 0x01; // Enable UART on P0.4(TX) and P0.5(RX)
XBR1 = 0x40; //0x40; Enable crossbar and weak pull-ups
// P2 = 0xFF;
// P3 = 0xFF;
// P4 = 0xFF;
*/
P1MDOUT = 0x00; // enable P1 outputs
P2MDOUT = 0xFE;
P3MDOUT = 0xFF; // for ULN2803 drivers
P4MDOUT = 0xFF;
P0MDOUT = 0xFF; // for LTC1298, LCD interfaces
// P0MDOUT |= 0x10; // Enable UTX as push-pull output
// XBR0 = 0x01; // Enable UART on P0.4(TX) and P0.5(RX)
XBR1 = 0x40; //0x40; Enable crossbar and weak pull-ups
P2 = 0xFF;
P3 = 0xFF;
P4 = 0xFF;
}
//-----------------------------------------------------------------------------
// initializes the system clock to use the internal oscillator
void SYSCLK_Init (void)
{
OSCICN |= 0x03; // Configure internal oscillator
RSTSRC = 0x04; // Enable missing clock detector
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// LCD routnies
// send one byte to SPI interface
void SPI_send(unsigned char dd)
{
unsigned char i;
LCD_CS1=0;
for(i=0; i<8; i++)
{
LCD_SCL=0; // set clock pulse low first
if( dd & 0x80 ) // set data bit
LCD_SI=1;
else
LCD_SI=0;
LCD_SCL=1; // clock high
dd = dd <<= 1; // shifted to next bit
}
LCD_CS1=1;
delaya();
}
void LCD_reset()
{
LCD_RESET = 0;
delay(10);
LCD_RESET = 1;
delay(10);
}
void LCD_command(unsigned char ch) { //send a command byte to LCD
LCD_A0P = 0;
SPI_send(ch);
delaya();
}
void LCD_data(unsigned char ch) { //send a data byte to LCD data port
LCD_A0P = 1;
SPI_send(ch);
}
// print an ASCII code on LCD at current text position
void write_char(unsigned char ch)
{
unsigned char * fontptr, k;
fontptr = font + (ch-0x20) * 5; // get the font pattern, 8 by 5
for(k=0; k<5; k++)
LCD_data( *fontptr++);
}
// display a message at column x, row y
void write_msg_xy(unsigned char x, unsigned char y, unsigned char *chptr)
{
char * ptr;
ptr = chptr;
set_xy(x, y);
while(*ptr)
write_char(*ptr++);
}
void plot_xy(unsigned char x, unsigned char y) // draw a dot at position x, y, x: 0 to 127, y:0 to 63
{
char ypage, dd=1;
ypage = y >>3;
set_xy(x, ypage);
ypage = y & 0x7; //low 3 bits for dot position
dd = dd << ypage;
LCD_data(dd);
sprintf(fp,"%4D",n);
write_msg_xy(100, 55, sp);
sprintf (sp,"%4D",a);
write_msg_xy(100, 65,fp);
}
// set LCD display position
void set_xy(unsigned char x, unsigned char y)
{
LCD_command(0x10 | ( x>> 4) & 0x07 ); // lower 4 bits for high nibble of column address, 0 to 127
LCD_command(0x00 | x & 0x0F); // lower 4 bits for low nibble of column address
LCD_command(0xB0 | y & 0x07); // set page address, B0 to B7 for 8 pages
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
v = a-n; // The result is an integer, no surprise
b = v/100; // Here comes the surprise: the result is also an integer
f = 60/b; // Second surprise, f is also an integer
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?