View previous topic :: View next topic |
Author |
Message |
nemero16
Joined: 21 Nov 2009 Posts: 19
|
convert Decimal to Hex |
Posted: Sat Nov 21, 2009 7:45 pm |
|
|
Hi, I have written a program in C which writes an eeprom with uart, but I want to write address in decimal and not hex. When I use the uart command R and W ...example: read or write?:r block:125(instead of writing 7D) byte:AABBCCDD... as I can do? This is the code:
main.c :
Code: |
#include <16F876.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#FUSES NODEBUG //No Debug mode for ICD
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=seriale1)
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3)
#include "input.c"
#include "2416.c"
void main()
{BYTE *value[4], cmd;
EEPROM_ADDRESS address;
unsigned long int x;
init_ext_eeprom();
do {
do {
printf("\r\Read or Write?: ");
cmd=getc();
cmd=toupper(cmd);
putc(cmd);
} while ( (cmd!='R') && (cmd!='W') && (cmd!='T') );
if((cmd!='R') && (cmd!='W')){
}
else{
printf("\n\rBlock: ");
#if sizeof(EEPROM_ADDRESS)==1
address = gethex();
#else
#if EEPROM_SIZE>0xfff
address = gethex();
#else
address = gethex1();
#endif
address = (address<<8)+gethex();
#endif}
if(cmd=='R'){
unsigned int i;
unsigned int n=4;
READ_EXT_EEPROM( address, n);
printf("\r\nByte: ");
for (i=0; i<n; i++) {
printf("%X", data[i]);
}
printf("\r\n");
}
if(cmd=='W'){
unsigned int i;
unsigned int n=4;
printf("\r\nByte: ");
for(i=0; i<n; i++){
value[i]=gethex();}
WRITE_EXT_EEPROM( address, value, n);
printf("\r\n");
}
if(cmd=='T'){
int i;
unsigned int8 a;
unsigned int max_memory=128;
int n_byte_letti=4;
printf("\r\n");
printf("\r\n");
for (a=0; a<max_memory; a+=n_byte_letti) {
read_total_ext_eeprom(a, n_byte_letti);
printf("%u%c",a,')');
for (i=0; i<n_byte_letti; i++) {
printf("%X", data[i]);
}
printf(" ");
}
printf("\r\n");
}
} while(true);
}
|
and this is 2416.c:
Code: | #ifndef EEPROM_SDA
#define EEPROM_SDA PIN_C4
#define EEPROM_SCL PIN_C3
#endif
#use i2c(master, sda=EEPROM_SDA, scl=EEPROM_SCL)
#define EEPROM_ADDRESS unsigned int8
#define EEPROM_SIZE 1024
BYTE data[4];
void init_ext_eeprom() {
output_float(EEPROM_SCL);
output_float(EEPROM_SDA);
}
int1 ext_eeprom_ready() {
int1 ack;
i2c_start(); // If the write command is acknowledged,
ack = i2c_write(0xa0); // then the device is ready.
i2c_stop();
delay_ms(10);
return !ack;
}
void write_ext_eeprom(EEPROM_ADDRESS address, BYTE *data[4], unsigned int n_byte)
{int i;
if (n_byte>4) n_byte=4;
if (n_byte==0) return;
while(!ext_eeprom_ready());
i2c_start();
i2c_write(0xa0);
i2c_write(address);
for(i=0; i<n_byte; i++){
i2c_write(data[i]);}
i2c_stop();
delay_ms(10);}
void read_ext_eeprom(EEPROM_ADDRESS address, unsigned int n_byte)
{int i;
if (n_byte>4) n_byte=4;
if (n_byte==0) return;
while(!ext_eeprom_ready());
i2c_start();
i2c_write(0xa0);
i2c_write(address);
i2c_start();
i2c_write(0xa1);
for (i=0; i<n_byte; i++) {
data[i]=i2c_read(1);}
i2c_stop();
delay_ms(10);
return;
}
void read_total_ext_eeprom(EEPROM_ADDRESS address, unsigned int n_byte)
{int i;
if (n_byte>4) n_byte=4;
if (n_byte==0) return;
while(!ext_eeprom_ready());
i2c_start();
i2c_write(0xa0);
i2c_write(address);
i2c_start();
i2c_write(0xa1);
for (i=0; i<n_byte; i++) {
data[i]=i2c_read(1);}
i2c_stop();
delay_ms(10);
return;
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Nov 21, 2009 9:29 pm |
|
|
This CCS driver file has routines to get input from a terminal in other
ways than just Hex format. For example, you can get a number in
decimal integer format. Here is the file location:
Quote: | c:\program files\picc\drivers\input.c |
Also, it looks like you have modified the external eeprom routines,
and you have made mistakes. If you need routines to read and write
to an external eeprom, look in this file:
Quote: | c:\program files\picc\drivers\external_eeprom.c |
Use the CCS routines. That's why CCS included them with the compiler -
To make it easier to do the things you need. |
|
|
nemero16
Joined: 21 Nov 2009 Posts: 19
|
|
Posted: Sun Nov 22, 2009 6:21 am |
|
|
Yes, I have modified the library to add an EEPROM array... can you tell me where I made mistakes? I analyzed the input file that is included in my program but I do not know how to set it ... give me some help? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Nov 22, 2009 10:39 am |
|
|
Quote: | void main()
{
BYTE *value[4], cmd;
void write_ext_eeprom(EEPROM_ADDRESS address, BYTE *data[4], unsigned int n_byte)
|
In various places you have defined an array of pointers and it's clear
that you don't want an array of pointers, you want an array of bytes.
Get rid of the '*' in all your array declarations.
Quote: | void read_ext_eeprom(EEPROM_ADDRESS address, unsigned int n_byte)
.
.
.
for (i=0; i<n_byte; i++) {
data[i]=i2c_read(1);}
i2c_stop();
delay_ms(10);
return;
} |
In this function you are reading 4 bytes, but don't have a "NACK" on
the last read in the sequence. This NACK is required by the i2c
specification. In CCS, a NACK is done by giving the i2c_read() function
a parameter of 0.
Also, functions return automatically. You don't need a return statement
at the end. |
|
|
nemero16
Joined: 21 Nov 2009 Posts: 19
|
|
Posted: Sun Nov 22, 2009 12:18 pm |
|
|
mmm ok I have removed all the "*", although I've set for reading i2c_read (1) function I have no problem, if imposed i2c_read (0) function works the same? to convert from decimal to hex as I set the gethex ()? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Nov 22, 2009 3:22 pm |
|
|
You have created your own (buggy) routines to read and write 4 bytes to
eeprom. You don't need to do that. CCS has routines to do this.
These routines are in the external_eeprom.c file:
Quote: |
write_int32_ext_eeprom()
read_int32_ext_eeprom()
|
If you want to get the address in decimal, then use the get_int()
or get_long() routines in the input.c file. Use one of those routines
instead of the get_hex() routines. |
|
|
nemero16
Joined: 21 Nov 2009 Posts: 19
|
|
Posted: Sun Nov 22, 2009 3:35 pm |
|
|
But there is this in input.c file, but not get_int ():
Code: | #include <ctype.h>
BYTE gethex1() {
char digit;
digit = getc();
putc(digit);
if(digit<='9')
return(digit-'0');
else
return((toupper(digit)-'A')+10);
}
BYTE gethex() {
unsigned int8 lo,hi;
hi = gethex1();
lo = gethex1();
if(lo==0xdd)
return(hi);
else
return( hi*16+lo );
}
void get_string(char* s, unsigned int8 max) {
unsigned int8 len;
char c;
--max;
len=0;
do {
c=getc();
if(c==8) { // Backspace
if(len>0) {
len--;
putc(c);
putc(' ');
putc(c);
}
} else if ((c>=' ')&&(c<='~'))
if(len<=max) {
s[len++]=c;
putc(c);
}
} while(c!=13);
s[len]=0;
}
// stdlib.h is required for the ato_ conversions
// in the following functions
#ifdef _STDLIB
#if !defined(__PCD__)
signed int8 get_int() {
char s[5];
signed int8 i;
get_string(s, 5);
i=atoi(s);
return(i);
}
#endif
#if defined(__PCD__)
signed int16 get_int() {
char s[5];
signed int16 i;
get_string(s, 7);
i=atoi(s);
return(i);
}
#endif
#if !defined(__PCD__)
signed int16 get_long() {
char s[7];
signed int16 l;
get_string(s, 7);
l=atol(s);
return(l);
}
#endif
#if defined(__PCD__)
signed int32 get_long() {
char s[7];
signed int32 l;
get_string(s, 10);
l=atoi32(s);
return(l);
}
#endif
float get_float() {
char s[20];
float f;
get_string(s, 20);
f = atof(s);
return(f);
}
#endif |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Nov 22, 2009 3:49 pm |
|
|
Quote: | signed int8 get_int() { |
Look more closely. |
|
|
nemero16
Joined: 21 Nov 2009 Posts: 19
|
|
Posted: Sun Nov 22, 2009 3:53 pm |
|
|
ops... I had not seen .. hahaha, but writing this out an error ...:
address = get_int(); |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Nov 22, 2009 4:19 pm |
|
|
Read the input.c file comments above the get_int() function. It says:
Quote: |
// stdlib.h is required for the ato_ conversions
// in the following functions
|
This means you have to include the stdlib.h file, as shown below:
Quote: |
#include <stdlib.h>
#include "input.c"
#include "2416.c"
|
|
|
|
nemero16
Joined: 21 Nov 2009 Posts: 19
|
|
Posted: Sun Nov 22, 2009 4:34 pm |
|
|
compiles ok but the program does not work because when I enter the address in dec and it does not go on .... this is the code:
Code: | #include <16F876.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#FUSES NODEBUG //No Debug mode for ICD
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=seriale1)
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3)
#include <stdlib.h>
#include "input.c"
#include "2416.c"
void main()
{BYTE value[4], cmd;
unsigned int8 address;
init_ext_eeprom();
do {
do {
printf("\r\nLeggi o Scrivi?: ");
cmd=getc();
cmd=toupper(cmd);
putc(cmd);
} while ( (cmd!='L') && (cmd!='S') && (cmd!='T') );
if((cmd!='L') && (cmd!='S')){
}
else{
printf("\n\rBlocco: ");
address = get_int();
#if sizeof(EEPROM_ADDRESS)==1
address = get_int();
#else
#if EEPROM_SIZE>0xfff
address = get_int();
#else
address = get_int();
#endif
address = (address<<8)+get_int();
#endif}
if(cmd=='L'){
unsigned int i;
unsigned int n=4;
READ_EXT_EEPROM( address, n);
printf("\r\nByte: ");
for (i=0; i<n; i++) {
printf("%X", data[i]);
}
printf("\r\n");
}
if(cmd=='S'){
unsigned int i;
unsigned int n=4;
printf("\r\nByte: ");
for(i=0; i<n; i++){
value[i]=gethex();}
WRITE_EXT_EEPROM( address, value, n);
printf("\r\n");
}
if(cmd=='T'){
int i;
unsigned int8 a;
unsigned int max_memory=128;
int n_byte_letti=4;
printf("\r\n");
printf("\r\n");
for (a=0; a<max_memory; a+=n_byte_letti) {
read_total_ext_eeprom(a, n_byte_letti);
printf("%u%c",a,')');
for (i=0; i<n_byte_letti; i++) {
printf("%X", data[i]);
}
printf(" ");
}
printf("\r\n");
}
} while(true);
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Nov 22, 2009 5:03 pm |
|
|
My advice is to simplify your program. Cut out large sections of your
code and make it smaller. Test each little piece of the program.
Prove that it works. Then put it together again. |
|
|
nemero16
Joined: 21 Nov 2009 Posts: 19
|
|
Posted: Sun Nov 22, 2009 5:09 pm |
|
|
But the program works and also good ... it's just that I want to insert the address in decimal and not hex ... the part to change, or insert the get_int () is this:
Code: |
void main()
{BYTE *value[4], cmd;
EEPROM_ADDRESS address;
init_ext_eeprom();
do {
do {
printf("\r\Read or Write?: ");
cmd=getc();
cmd=toupper(cmd);
putc(cmd);
} while ( (cmd!='R') && (cmd!='W') && (cmd!='T') );
if((cmd!='R') && (cmd!='W')){
}
else{
printf("\n\rBlock: ");
#if sizeof(EEPROM_ADDRESS)==1
address = gethex();
#else
#if EEPROM_SIZE>0xfff
address = gethex();
#else
address = gethex1();
#endif
address = (address<<8)+gethex();
#endif}
........ |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Nov 22, 2009 5:14 pm |
|
|
Quote: |
#if sizeof(EEPROM_ADDRESS)==1
address = gethex();
#else
#if EEPROM_SIZE>0xfff
address = gethex();
#else
address = gethex1();
#endif
address = (address<<8)+gethex();
#endif}
........ |
Decide which line you want to use, and get rid of all the other lines,
and get rid of all the #if, #ifdef, #else, and #endif lines.
And change the line to address = get_int(); |
|
|
nemero16
Joined: 21 Nov 2009 Posts: 19
|
|
Posted: Sun Nov 22, 2009 5:57 pm |
|
|
ok, I removed everything and I left this:
Code: | if ((cmd = 'L') & & (cmd = 'S')) {
}
else {
printf ( "\ n \ rBlocco:");
address = gethex();} |
but when I go to write address = get_int () the program crashes and does not go forward .. I should set it first receives the value in decimal and then convert it to hex ...how can I do? |
|
|
|