Jump to content


Photo

Float & Lcd


3 replies to this topic

#1 mityeltu

mityeltu

    Regular

  • EstablishedMember
  • Pip
  • 79 posts
  • Gender:Male
  • Location:Tennessee
  • Interests:Communications

Posted 04 July 2010 - 08:09 PM

I am working on a simple (I call it that) project to display the results of the pythagorean theorem. I have the user input 'a' and 'b' and then I want to display 'c'. The problem is getting 'c'. I know the format is |signbit(1)|exp(8)|mantissa(23)| So, my real question is, how can I format this for display on an LCD?

I tried the following, just to see if I could use a brute force method on it, but all I got were zero's. Does anyone have any suggestions?
I'm trying to use the 16f887 for this project.

#include <system.h>
#include <lcd_driver.h>
#include <float.h>

#define LCD_ARGS  2, /* Interface type&#58; mode 0 = 8bit, 1 = 4bit&#40;low nibble&#41;, 2 = 4bit&#40;upper nibble&#41; */ \
	1,	 /* Use busy signal&#58; 1 = use busy, 0 = use time delays */\
	PORTB, TRISB,  /* Data port and data port tris register */ \
	PORTB, TRISB,  /* Control port and control port tris register */ \
	1,	/* Bit number of control port is connected to RS */ \
	2,	/* Bit number of control port is connected to RW */ \
	3	 /* Bit number of control port is connected to Enable */

float a, b, c, a_sqr, b_sqr, c_sqr;
char i, out, x, y;

void main&#40;&#41;
{
intcon = 0;
adcon0 = 0;
ansel = 0;
anselh = 0;

trisa = 0;
trisb = 0;
porta = 0;
portb = 0;

lcd_setup&#40;&#41;;
//a^2+b^2=c^2
a = 1.0;
b = 1.0;
x = 2;
y = 0;
lprintf&#40;&#34;c=&#34;&#41;;
while &#40;1&#41;
	{
	a_sqr = float32_mul&#40;a, a&#41;;
	b_sqr = float32_mul&#40;b, b&#41;;
	c_sqr = float32_sub&#40;a_sqr, b_sqr&#41;;
	c = float32_sqrt&#40;c_sqr&#41;;
	//floats are 32 bits
	for &#40;i = 0; i < 31; i++&#41;
		{
		if &#40;test_bit&#40;c,i&#41;&#41;
			{
			out = 0x31;
			}
		else
			{
			out = 0x30;
			}
		lcd_gotoxy&#40;x,y&#41;;
		lcd_datamode&#40;&#41;;
		lcd_write&#40;out&#41;;
		x++;
		if &#40;x == 16&#41;
			{
			x = 0;
			y = 1;
			}
		}
		while &#40;1&#41;
		{}
	}

}


#2 mityeltu

mityeltu

    Regular

  • EstablishedMember
  • Pip
  • 79 posts
  • Gender:Male
  • Location:Tennessee
  • Interests:Communications

Posted 04 July 2010 - 08:15 PM

Ok, I saw one problem.... (BIG problem really) I was subtracting rather than adding.... That's fixed, but I would still rather have an EASY way to display this value rather than the brute force method I'm about to undertake.

#3 ChipGuy

ChipGuy

    Newbrie

  • EstablishedMember
  • 12 posts
  • Gender:Male
  • Location:Atlanta, GA (Alpharetta)

Posted 07 July 2010 - 06:32 PM

The solution I used for my recent Parallax RF Design Contest entry was to never use floating point math. It killed my PIC's remaining code
space to do so, and wasn't so efficient anyway.

So I had this:

integer number (ulong, or whatever) * floating point coefficient.

Example:

1,023 (0x03FF) * 0.003

can be expressed as:

1,023 x ( 3/1000) -> 1,023 x 3 x 1/1000

..and this gives an integer number 3096 x 1/1000

I then just divided by a 10's power divisor, then decrement divisor by 10 when the dividend was less than my divisor. For each division, increment a count and add 0x30 to the quotient (result) to get your ASCII characters. Insert decimal where you need to manually.



Example:

Display floating point value for 1023 x .003V = 3.069V


ASCII = 0x33, ".", 0x30, 0x36, 0x9

1023d * 3 = 3069

(Now divide and drop remainders)
3069 / 1000 = 3 + 0x30 = 0x33
3069 / 100 = 0 -> 0x30
3069 / 10 = 6 -> 0x36
3069 / 1 = 9 -> 0x39


..insert decimal point where needed. Change the divisor (power of tens) for the needed # of digits before and after the decimal point.

Store each in a string array and insert decimal point as you do so.

Then write the string array to the LCD.

That's what I did.

Hopefully some variation of this will help you. :angry:

Edited by ChipGuy, 07 July 2010 - 06:33 PM.


#4 hero_hont

hero_hont

    Newbrie

  • Members
  • 1 posts

Posted 20 August 2010 - 03:44 PM

I am working on a simple (I call it that) project to display the results of the pythagorean theorem. I have the user input 'a' and 'b' and then I want to display 'c'. The problem is getting 'c'. I know the format is |signbit(1)|exp(8)|mantissa(23)| So, my real question is, how can I format this for display on an LCD?

I tried the following, just to see if I could use a brute force method on it, but all I got were zero's. Does anyone have any suggestions?
I'm trying to use the 16f887 for this project.

#include <system.h>
#include <lcd_driver.h>
#include <float.h>

#define LCD_ARGS  2, /* Interface type&#58; mode 0 = 8bit, 1 = 4bit&#40;low nibble&#41;, 2 = 4bit&#40;upper nibble&#41; */ \
	1,	 /* Use busy signal&#58; 1 = use busy, 0 = use time delays */\
	PORTB, TRISB,  /* Data port and data port tris register */ \
	PORTB, TRISB,  /* Control port and control port tris register */ \
	1,	/* Bit number of control port is connected to RS */ \
	2,	/* Bit number of control port is connected to RW */ \
	3	 /* Bit number of control port is connected to Enable */

float a, b, c, a_sqr, b_sqr, c_sqr;
char i, out, x, y;

void main&#40;&#41;
{
intcon = 0;
adcon0 = 0;
ansel = 0;
anselh = 0;

trisa = 0;
trisb = 0;
porta = 0;
portb = 0;

lcd_setup&#40;&#41;;
//a^2+b^2=c^2
a = 1.0;
b = 1.0;
x = 2;
y = 0;
lprintf&#40;&#34;c=&#34;&#41;;
while &#40;1&#41;
	{
	a_sqr = float32_mul&#40;a, a&#41;;
	b_sqr = float32_mul&#40;b, b&#41;;
	c_sqr = float32_sub&#40;a_sqr, b_sqr&#41;;
	c = float32_sqrt&#40;c_sqr&#41;;
	//floats are 32 bits
	for &#40;i = 0; i < 31; i++&#41;
		{
		if &#40;test_bit&#40;c,i&#41;&#41;
			{
			out = 0x31;
			}
		else
			{
			out = 0x30;
			}
		lcd_gotoxy&#40;x,y&#41;;
		lcd_datamode&#40;&#41;;
		lcd_write&#40;out&#41;;
		x++;
		if &#40;x == 16&#41;
			{
			x = 0;
			y = 1;
			}
		}
		while &#40;1&#41;
		{}
	}

}


hih
when we want display LCD in the programming languages C you can study here:
#include
#include "lcd.h"
#include "lcdcmd.h"

/*
* Private prototypes:
*/
void LcdWriteCmd(unsigned char cmd);
bit isLcdBusy(void);
void waitUntilDone(void);


sbit LCD_E = P0^6;
sbit LCD_RW = P0^7;
sbit LCD_RS = P0^5;

sbit BUSY = P1^7;

/*
* Fetch LCD's busy flag.
* Put P1 into read mode before attempting to read!
*/
bit isLcdBusy(void) {
bit retbit;

retbit = 0;

PRT1CF = 0x00;
LCD_RW = 1;
LCD_RS = 0;
LCD_E = 1;
P1 = 0xFF;
retbit = P1^7;
LCD_E = 0;
PRT1CF = 0xFF;
LCD_RW = 0;
return (retbit);
} // isLcdBusy

void waitUntilDone(void)
{
bit retbit = 1;
PRT1CF = 0x00;
P1 = 0xFF;
LCD_RW = 1;
LCD_RS = 0;
while (retbit == 1)
{
LCD_E = 1;
retbit = BUSY;
LCD_E = 0;
} //while retbit == 1
PRT1CF = 0xFF;
LCD_RW = 0;
} // waitUntilDone()

/*
* Write a character to the display at the current cursor position.
*/
void LcdWriteChar(unsigned char dval)
{
LCD_RW = 0;
LCD_RS = 1;
LCD_E = 1;
P1 = dval;
LCD_E = 0;
waitUntilDone();
} // LcdWriteChar()

/*
* Write a string to the display, starting at the current cursor position.
*/
void LcdWriteString(unsigned char *str)
{
while (*str != '\0')
{
LcdWriteChar(*str);
++str;
}
} // LcdWriteString

/*
* Move the cursor to the specified row and column.
*/
void LcdMoveCursor(unsigned char row, unsigned char col)
{
LcdWriteCmd(LCD_MOVEDISPLAY | (row << 6) | col);
} // LcdMoveCursor

/*
* Write a command to the LCD.
*/
void LcdWriteCmd(unsigned char cmd)
{
LCD_RW = 0;
LCD_RS = 0;
LCD_E = 1;
P1 = cmd;
LCD_E = 0;
waitUntilDone();
} // LcdWriteCmd


/*
* Initialize the LCD.
*/

void LcdInit(void)
{
P1MODE = 0xFF; // enable port 1 digital inputs, needed for BUSY.
LCD_RW = 0;
LCD_RS = 0;
LCD_E = 0;

LcdWriteCmd(0x30);
LcdWriteCmd(0x30);
LcdWriteCmd(0x30);
LcdWriteCmd(LCD_SETIFLEN | LCD_SETIFLEN_N | LCD_SETIFLEN_DL);

// should be initialized here.

LcdWriteCmd(LCD_DISPEN); // display off, cursor off, no blink
LcdWriteCmd(LCD_CLEAR);
LcdWriteCmd(LCD_DISPEN | LCD_DISPEN_DISP); // | LCD_DISPEN_CURSOR);
LcdWriteCmd(LCD_MOVEDIR | LCD_MOVEDIR_ID);
} // LcdInit

/*
* Clear the LCD.
*/
void LcdClear(void)
{
LcdWriteCmd(LCD_CLEAR);
} // LcdClear()

/*
* Write the given pattern to the CGRAM at the given address.
*/
void LcdWriteCGRAM(unsigned char addr, unsigned char pattern)
{
// First, move the cursor into the CGRAM area:
LcdWriteCmd(LCD_MOVERAM | addr);
// Then write the pattern to that location:
LcdWriteChar(pattern);
} // LcdWriteCGRAM())

good luck....



Reply to this topic



  


0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users