Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[Moved] Silicon Labs IDE coding for a mobile oscilloscope meant for a PPG

Status
Not open for further replies.

Brien Cheow

Newbie level 6
Joined
Apr 29, 2015
Messages
11
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
168
i have done most of the coding but the problem i am experiencing now is that after the first round of signal sensing, it does not refresh and restart the process. The problem could be from the for(;;) loop because i tried leaving it out and it worked. but i need the for loop for my calculation.. please help...

Code:
/*
	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

//-----------------------------------------------------------------------------
// 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;
int s;
int p;
int *sp;
p = 0;
s = 0;

// 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 SPI interface, high bit first
void write_char(unsigned char);		// display an ASCII 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 = 1;
    TH0 = 0xD8;
    TL0 = 0xEF;
    EA = 1;
    ET0 = 1;
   
   while(TF0==0);

    TF0 = 0;
 
  
}
void timer0 (void) interrupt 1
{ 
   s++;
   s=s;
   sp = &s;
   
}


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(200);

   	 
// enable timer interrupts
//	ET0=1;
//	TMOD=0x21;
//	TR0=1;
//	EA=1;

  while(1)
  {

	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);
	     }
	  }
*/
	}

	
	LCD_Clear_Display();
	write_msg_xy(100, 55, sp);
 
 //for(;;)
     // {  int n;
      //   n = (ADC0);
      //  if(n>p)
           
	//	  p=n;
		   
	//	else
         
		//  timer0_interrupt_init();
       
             
//}

  } // 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);
}


// 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
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 

One issue is that you essentially have a superloop within a superloop, once the execution flow enters the for(;;) loop, game over.

Code:
  while(1)
  {

	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);
	     }
	  }
*/
	}

	
	LCD_Clear_Display();
	write_msg_xy(100, 55, sp);
 
 [COLOR="#FF0000"]//for(;;)
     // {  int n;
      //   n = (ADC0);
      //  if(n>p)
           
	//	  p=n;
		   
	//	else
         
		//  timer0_interrupt_init();
       
             
//}[/COLOR]

  } // end while(1)

Unfortunately, it not clear what the intended tasks are you desire to accomplish.

Can you elaborate on the intended task flow?

Without referring to your existing code, can you provide a detailed outline of the specific task, in order, you would like the application to perform?



Why not utilize an Interrupt Service Routine (ISR) to update the ADC value?

Or incorporate the updating of the ADC value in the timer ISR?

Or simply incorporate the task into the while(1) superloop?



BigDog
 
Dear BigDog this code is intended to basically display the signal on a 128x64 LCD screen with a BPM indicator. I have so far got timer0 to run optimally but i still cant seem to get it to start and stop when i hit 2 peaks of the signal. What i want timer0 to do is just to calculate the time elapsed in between the two peaks(Ps: Values for the y axis data are taken from ADC0) . Thanks for your help BigDog!
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top