CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

how to separate a float number to display into MAX7456

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
pic_micro



Joined: 07 Feb 2011
Posts: 26

View user's profile Send private message

how to separate a float number to display into MAX7456
PostPosted: Tue May 03, 2011 9:40 am     Reply with quote

I need help,

I working on the MAX7456 chip (overlay OSD)
I want to display a voltage such as 0-5 (include decimal point ex 3.5V) onto osd screen.

I can separate the number such as 1234 & display them onto osd with the following code
Code:
thousand = (n/1000);   //1000s
hundred = ( n%1000)/100;      // 100s digit
ten = ((n %1000)%100)/10;      // 10s digit
one = (n %1000)%10;      // 1s digit


but I ran out of idea how to display a float number (3.5)
the number is a 10bit ADC from chn0 of pic-demo2 plus.
I use the following formula to calculate the voltage.

Code:

volt = (n/1023) * 5;
      
      

Let say n = 716 which is volt = 3.5, how do I separate the whole number and the decimal to display them on the osd?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue May 03, 2011 10:30 am     Reply with quote

Use the sprintf() function. It converts the floating point number into
separate ASCII digits in an array. You can then take each digit from
the array and display it.
pic_micro



Joined: 07 Feb 2011
Posts: 26

View user's profile Send private message

seperate ADC and display it in MAX7456
PostPosted: Wed May 04, 2011 7:55 am     Reply with quote

I couldn't the way describe per PCM. So I use my own way
Code:
volt = (n/1023) * 5;
      d = volt * 100;

      a =  d / 100;
      b = (d % 100)/10;
      c = (d % 100)%10;

to seperate
the ADC result (n) and display it onto MAX7456 screen, but some how
if the ADC is max (1023) it displays 5.00V, if ADC is less than 1023 then it only display 0.00V on screen. Either my formula is wrong or my variable are wrong, I have tried my variable as long, float, char, int and nothing help.
Here are my code:

main.c
Code:
#include <16f877.h>
#device ADC=10
#fuses XT, NOWDT, NOPROTECT, NOBROWNOUT,  NOPUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#include <driver.c>


int thousand = 0, hundred = 0, ten = 0, one = 0;
long a, b, c, d;
float volt;
long n;

void main(void)
{
   max7456_init();
   enable();

   setup_port_a(AN0);
   setup_adc( ADC_CLOCK_INTERNAL );
   set_adc_channel( 0 );

   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);

   while(1)
   {

      delay_ms(1);
      n = Read_ADC();
      delay_ms(1);



      volt = (n/1023) * 5;
      d = volt * 100;

      a =  d / 100;
      b = (d % 100)/10;
      c = (d % 100)%10;
   

      if(a == 0 )
      {
         a = 0x0A;    //max7456 RAM location of character '0'
      }
      if(b == 0 )
      {
         b = 0x0A;
      }
      if(c == 0 )
      {
         c = 0x0A;
      }

      max7456_write(0x06, y+8);
      max7456_write(0x07, a);

      max7456_write(0x06, y+9);
      max7456_write(0x07, 0x41);  // decimal point  "."

      max7456_write(0x06, y+10);
      max7456_write(0x07, b);

      max7456_write(0x06, y+11);
      max7456_write(0x07, c);

      max7456_write(0x06, y+12);
      max7456_write(0x07, 0x20);  // Character "V"
   
   }
}


driver.c
Code:
#define MAX7456_CS     PIN_A1
#define MAX7456_CLK     PIN_C3
#define MAX7456_DI     PIN_C5
#define MAX7456_DO      PIN_C4


char x = 40;
char y = 190;
char z = 220;
char j = 83;

void max7456_write(int8 addr, int8 data)
{
   output_low(MAX7456_CS);
   spi_write(addr);
   spi_write(data);
   output_high(MAX7456_CS);
   delay_ms(1);
}

//============= Disable ========================
void Disable(void)      // Disable
{
   max7456_write(0x00, 0x00);
}


//============= Enable =======================
void Enable(void)
{
   max7456_write(0x00, 0x08);   // Enable NTSC
   max7456_write(0x04, 0x40);
}


//============= Enable =======================
void max7456_init(void)
{
   short int i;
   output_low(MAX7456_DI);
   output_low(MAX7456_CLK);
   output_high(MAX7456_CS);
   i=input(MAX7456_DO);

   setup_spi(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_16);
   
}


void lines(void)
{
   
   enable();

   // =========LINE1 ============
   x = 1;
   max7456_write(0x06, x);
   max7456_write(0x07, 0x01);
   delay_ms(10);

   // =========LINE2 ============
   x = 31;
   max7456_write(0x06, x);
   max7456_write(0x07, 0x02);
   delay_ms(10);

   // =========LINE3 ============
   x = 61;
   max7456_write(0x06, x);
   max7456_write(0x07, 0x03);
   delay_ms(10);

   // =========LINE4 ============
   x = 91;
   max7456_write(0x06, x);
   max7456_write(0x07, 0x04);
   delay_ms(10);

   // =========LINE5 ============
   x = 121;
   max7456_write(0x06, x);
   max7456_write(0x07, 0x05);
   delay_ms(10);

   // =========LINE6 ============
   x = 151;
   max7456_write(0x06, x);
   max7456_write(0x07, 0x06);
   delay_ms(10);
}



Can anybody tell me what cause problem in the code?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed May 04, 2011 12:39 pm     Reply with quote

There are many problems.

In your init code below, you took out the delay (typical 50 ms) which
the MAX7456 data sheet says must be in there.
Quote:

void max7456_init(void)
{
short int i;
output_low(MAX7456_DI);
output_low(MAX7456_CLK);
output_high(MAX7456_CS);
i=input(MAX7456_DO);

setup_spi(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_16);

// Missing the power-up delay line, here !!!
}

In addition to that, you have 4 lines of code to setup the i/o pin direction
and initialize the levels. But I suggest that you compile a little test
program just like this (below) and look at the .LST file:
Code:

#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)

//===========================
void main()
{
setup_spi(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_16);

while(1);
}


Here's the .LST file with comments added. It's setting the correct TRIS
for you. The initial output levels are set by the SPI module itself.
So all the setup lines that you're doing are unnecessary.
Code:

......... setup_spi(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_16); 
000F:  BCF    STATUS.RP0
0010:  BCF    SSPCON.SSPEN

0011:  BCF    @TRIS_C.5   // Set pin C5 (SDO) as an output
0012:  MOVF   @TRIS_C,W
0013:  BSF    STATUS.RP0
0014:  MOVWF  TRISC

0015:  BCF    STATUS.RP0 
0016:  BSF    @TRIS_C.4   // Set pin C4 (SDI) as an input
0017:  MOVF   @TRIS_C,W
0018:  BSF    STATUS.RP0

0019:  MOVWF  TRISC
001A:  BCF    STATUS.RP0
001B:  BCF    @TRIS_C.3  // Set pin C3 (SCLK) as an output
001C:  MOVF   @TRIS_C,W

001D:  BSF    STATUS.RP0
001E:  MOVWF  TRISC

001F:  MOVLW  31
0020:  BCF    STATUS.RP0
0021:  MOVWF  SSPCON
0022:  MOVLW  40
0023:  BSF    STATUS.RP0
0024:  MOVWF  SSPSTAT
.................... 



There is another problem right here (in bold) with your spi setup line.
Quote:
setup_spi(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_16);

Here are the #define statements that you should be using. They show
that you have specified SPI Mode 2.
Code:
#define SPI_MODE_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1  (SPI_L_TO_H)
#define SPI_MODE_2  (SPI_H_TO_L)
#define SPI_MODE_3  (SPI_H_TO_L | SPI_XMIT_L_TO_H)

There is a problem with that. It's the wrong mode. Look at Figure 14 on
page 21 of the MAX7456 data sheet:
http://datasheets.maxim-ic.com/en/ds/MAX7456.pdf
It shows that SCLK idles at a low level, and that it samples the data on
the rising edge. Then go to any website that has diagrams of SPI modes
such as this one:
http://www.totalphase.com/support/kb/10045/#modes
And you can see clearly that this is Mode 0. You can see that Mode 2,
which you specified is the total opposite of the correct mode. Your setup
line should look like this:
Quote:

setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_16);


Next, you have enabled external interrupts but you don't have an #int_ext
routine. Because of this, if you get an edge on the INT pin, your program
will crash.
Quote:
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);



There are some other minor problems, but I'm going to skip them for now.
I think your main problem is in the program design. If you look at various
CCS sample driver files, you'll notice that they always try to make a
character-based output routine. For example, in their LCD drivers
(whether for a character or segmented LCD), they always make an
lcd_putc() routine. There is a reason for this. CCS has special features
for string handling, such that once you have a character-based output
routine for your device, you basically have the "keys to the kingdom".
You can now use the special redirection feature of printf. Printf will format
your variable in whatever way you want, and then send it, one character
at a time, to your device output routine.

So I think the key to get your program working, is to make a character-
based output routine. Write a routine that will display one character
on the screen. It receives the character as a parameter. You can call
the routine "osd_putc()" or "max7456_putc()". If you do that, I think
most of your problems will go away.
pic_micro



Joined: 07 Feb 2011
Posts: 26

View user's profile Send private message

PostPosted: Wed May 04, 2011 2:09 pm     Reply with quote

The SPI_MODE_0 always error for me. So I decide to use the SPI_H_TO_L
instead and I can display the text on the screen ok.

Quote:
Executing: "C:\CCS_PIC\PCM\PICC\Ccsc.exe" "main2.c" +FM +DF +LN +T -A +M +Z +Y=9 +EA
*** Error 12 "C:\chai\CProjects\PICC Experiment\CCS\7seg\driver.c" Line 42(35,45): Undefined identifier SPI_MODE_0
1 Errors, 0 Warnings.
Halting build on first failure as requested.
BUILD FAILED: Wed May 04 15:45:27 2011
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed May 04, 2011 3:05 pm     Reply with quote

You have to put those #define statements for the SPI modes above main().
The compiler must see the definitions before it can use them.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group