mityeltu 0 Posted July 4, 2010 Report Share Posted July 4, 2010 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: mode 0 = 8bit, 1 = 4bit(low nibble), 2 = 4bit(upper nibble) */ \ 1, /* Use busy signal: 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() { intcon = 0; adcon0 = 0; ansel = 0; anselh = 0; trisa = 0; trisb = 0; porta = 0; portb = 0; lcd_setup(); //a^2+b^2=c^2 a = 1.0; b = 1.0; x = 2; y = 0; lprintf("c="); while (1) { a_sqr = float32_mul(a, a); b_sqr = float32_mul(b, b); c_sqr = float32_sub(a_sqr, b_sqr); c = float32_sqrt(c_sqr); //floats are 32 bits for (i = 0; i < 31; i++) { if (test_bit(c,i)) { out = 0x31; } else { out = 0x30; } lcd_gotoxy(x,y); lcd_datamode(); lcd_write(out); x++; if (x == 16) { x = 0; y = 1; } } while (1) {} } } Quote Link to post Share on other sites
mityeltu 0 Posted July 4, 2010 Author Report Share Posted July 4, 2010 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. Quote Link to post Share on other sites
ChipGuy 0 Posted July 7, 2010 Report Share Posted July 7, 2010 (edited) 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 July 7, 2010 by ChipGuy Quote Link to post Share on other sites
hero_hont 0 Posted August 20, 2010 Report Share Posted August 20, 2010 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: mode 0 = 8bit, 1 = 4bit(low nibble), 2 = 4bit(upper nibble) */ \ 1, /* Use busy signal: 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() { intcon = 0; adcon0 = 0; ansel = 0; anselh = 0; trisa = 0; trisb = 0; porta = 0; portb = 0; lcd_setup(); //a^2+b^2=c^2 a = 1.0; b = 1.0; x = 2; y = 0; lprintf("c="); while (1) { a_sqr = float32_mul(a, a); b_sqr = float32_mul(b, b); c_sqr = float32_sub(a_sqr, b_sqr); c = float32_sqrt(c_sqr); //floats are 32 bits for (i = 0; i < 31; i++) { if (test_bit(c,i)) { out = 0x31; } else { out = 0x30; } lcd_gotoxy(x,y); lcd_datamode(); lcd_write(out); x++; if (x == 16) { x = 0; y = 1; } } while (1) {} } } 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.... Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.