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

Help me 16 bit decimal convert to BCD code

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



Joined: 09 Oct 2006
Posts: 12
Location: hoangsam

View user's profile Send private message AIM Address Yahoo Messenger ICQ Number

Help me 16 bit decimal convert to BCD code
PostPosted: Sat Apr 13, 2024 10:46 am     Reply with quote

Why not return BCD value in my program?

Code:

#include <16f887.h>
#device *=16
#device adc=10
#fuses nowdt,xt,noput,protect,nodebug,nobrownout,nolvp
#use delay(clock=4000000)
//#include <internal_eeprom.c>
//#bit  ResetRom = 0x05.5 //RA5 (PIN 7)
#byte PORTA = 0x05   
#byte PORTB = 0x06   
#byte PORTC = 0x07   
#byte PORTD = 0x08
#byte PORTE = 0x09
#byte TRISA = 0x85
#byte TRISB = 0x86
#byte TRISC = 0x87
#byte TRISD = 0x88
#byte TRISE = 0x89

#bit re0    =    0x09.0 // DS_PIN
#bit re1    =    0x09.1 //SHCP_PIN
#bit re2    =    0x09.2 //STCP_PIN
/* IC74HC595 */
#define SHCP_PIN  PIN_E1
#define DS_PIN   PIN_E0
#define STCP_PIN     PIN_E2

byte Lo_Data_DKX ;
byte Hi_Data_DKX ;
int16 a=10;
int16 b=0;
int16 c=0;
int16 d=0;
int16 Data_DKX = 0;
int16 Data_CHIA = 0;
int16 Data = 0;



void convert_data_DKX()
{
   
   Data_DKX = (((800*a)+(80*(b+25))+(8*c)+d));
   Data_CHIA = (Data_DKX)/2;

   Hi_Data_DKX = (unsigned char) ((((Data_CHIA / 1000) % 10) << 12) |(((Data_CHIA / 100) % 10) << 8) ) ;
   Lo_Data_DKX = (unsigned char) ((((Data_CHIA / 10) % 10) << 4) | (Data_CHIA % 10));

}


void IC_74hc595(int data)
{
int i;
output_low(SHCP_PIN);
for(i=0;i<=7;i++)
{

if((data & 0x80)==0)
{output_low(DS_PIN);
delay_us(50);}
else
output_high(DS_PIN);
data=data<<1;
output_high(SHCP_PIN);
output_low(SHCP_PIN);
}
}
void IC_74HC595_Output()
{
output_low(STCP_PIN);
delay_ms(50);
output_high(STCP_PIN);
output_low(STCP_PIN);
}
void write_to_595 (byte Lo_Data_DKX, Hi_Data_DKX)
{
      IC_74hc595(Hi_Data_DKX);
      IC_74hc595(Lo_Data_DKX);
      IC_74HC595_Output();
}
void send_data_DKX()
{
   convert_data_DKX();
   write_to_595(Lo_Data_DKX, Hi_Data_DKX);
}


void main(void)
{
   TRISA=0x00;    //PortA as OUTPUT, RA5 as INPUT
   TRISB=0xFF;    //PortB as INPUT
   TRISC=0x00;    //PortC as OUTPUT
   TRISD=0xFF;    //PortD as INPUT
   TRISE=0x00;    //PortE as OUTPUT
   PORTC=0;  //
   PORTE=0;
   
 while(true)
   {
     
      send_data_DKX();
                   
   }


}
Ttelmah



Joined: 11 Mar 2010
Posts: 19496

View user's profile Send private message

PostPosted: Sun Apr 14, 2024 1:52 am     Reply with quote

First thing. Document, document, document.
We have no idea of what you are actually trying to do, and you yourself,
if you come back to this code in a few years time, will also have no idea
what it is meant to do. Documentation is your friend, and gives a place
to start. It also will often make obvious what is going wrong.....

Now, I'll make some comments in your routine, and this may help you
get a key to the problem:
Code:

void convert_data_DKX()
{
   //Much better really to pass variables to the function rather than
   //using globals.
   Data_DKX = (((800*a)+(80*(b+25))+(8*c)+d));
   //Now what on earth is this meant to do?. You are passing it four
   //int16 values 10, 0, 0, 0
   //so 10*800 = 8000
   //80*25 = 2000
   //result will be 10000.
   //Why the strange multiplication, and the addition of 25?????

   Data_CHIA = (Data_DKX)/2;
   //Why over 2?. Now 5000. At least this can fit into four BCD
   //'digits'.

   Hi_Data_DKX = (unsigned char) ((((Data_CHIA / 1000) % 10) << 12) |(((Data_CHIA / 100) % 10) << 8) ) ;

   //Now this looks as if you are trying to code this is binary
   //nibbles, not 'BCD' digits. So you possibly want:
   // 0b0101 0000 (0x 50)
   // 0b0000 0000 (0x 00)

   //Big problem here is your cast. You are generating the nibble into the
   //high byte of a 16bit value, then casting this to an unsigned char. At
   //this point the high byte is _thrown away_. You get just the low byte
   //result 00.........

   //Given you want only the high byte here:

   Hi_Data_DKX=(((Data_CHIA/1000) %10) <<4) + (Data_CHIA/100)%10;
   //Now this gives the 'thousands' moved to the high nibble of the
   //resulting byte, and the hundreds in the low nibble. Exactly what
   //is needed.
   //This is exactly what you code below, but doing the high two digits.
   //The problem was you were generating '0x 5000', then taking the
   //low byte of this result. Answer = 0, not 0x50.... :(

   Lo_Data_DKX = (unsigned char) ((((Data_CHIA / 10) % 10) << 4) | (Data_CHIA % 10));

}
thanhhavdt



Joined: 09 Oct 2006
Posts: 12
Location: hoangsam

View user's profile Send private message AIM Address Yahoo Messenger ICQ Number

PostPosted: Sun Apr 14, 2024 8:57 am     Reply with quote

Thanks Ttelmah!!!
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