Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Hex to ASCII for UART

John99407

Junior Member level 2
Joined
Jul 14, 2019
Messages
22
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
209
0x41 is the ASCII code for 'A' I want to show "41" on hyper terminal without putch function and any other library

How can 41 shown on hyper terminal

C:
//PIC16F877A MPLAB XC8

// CONFIG
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
// End of configuration

#include <xc.h>
#define _XTAL_FREQ 20000000
#define Baud_rate 9600

void Initialize_UART(void) //Initializing UART module for PIC16F877A
{
    TRISC6 = 0; // TX Pin set as output
    TRISC7 = 1; // RX Pin set as input
 
    /**Initialize SPBRG register for required
    baud rate and set BRGH for fast baud_rate**/
    SPBRG = ((_XTAL_FREQ/16)/Baud_rate) - 1;
    BRGH = 1; // for high baud_rate
 
    SYNC = 0; // Asynchronous
    SPEN = 1; // Enable serial port pins

    TXEN = 1; // enable transmission
    CREN = 1; // enable reception
 
    TX9 = 0; // 8-bit reception selected
    RX9 = 0; // 8-bit reception mode selected
}

void UART_send_char(char c) //Function to send one byte of date to UART
{
    while(!TXIF); // Wait till the transmitter register becomes empty
    TXREG = c; //load the char to be transmitted into transmit reg
}

// Sends null-terminated ASCII string
void UART_send_string(char* p)
{
     char c;
     while((c = *p) != '\0')
     {
        UART_send_char(c);
        p++;
     }
}

void main(void)
{
    Initialize_UART(); //Initialize UART module
    char byte = 0x41;
    
}
 

betwixt

Super Moderator
Staff member
Joined
Jul 4, 2009
Messages
14,921
Helped
4,874
Reputation
9,766
Reaction score
4,661
Trophy points
1,393
Location
Aberdyfi, West Wales, UK
Activity points
126,953
You will have to convert the single character 'A' to two characters '4' and '1' then display them both.
There are several ways, easiest is to use the sprintf() command but it uses lots of memory or you can do it this way:
Code:
unsigned char BinToAsc(unsigned char BinValue)
{
    BinValue &= 0x0F;
    if(BinValue > 9) BinValue += 7;
    return(BinValue + '0');
}
Note that this only converts the lower 4 bits to it's ASCII equivalent so you need to call the routine twice, the first time for the high bits (shifted 4 bits to the right).

Code:
UART_send_char(BinToAsc('A' >> 4));
UART_send_char(BinToAsc('A'));

Brian.
 

KlausST

Super Moderator
Staff member
Joined
Apr 17, 2014
Messages
19,717
Helped
4,343
Reputation
8,695
Reaction score
4,304
Trophy points
1,393
Activity points
130,522
Hi,

you may also use a 16 character (0..9A..F) lookup table.

****
or you may use a different terminal software, because most of them are able to show received values as HEX.

Klaus
 

John99407

Junior Member level 2
Joined
Jul 14, 2019
Messages
22
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
209
You will have to convert the single character 'A' to two characters '4' and '1' then display them both.
There are several ways, easiest is to use the sprintf() command but it uses lots of memory or you can do it this way:

Note that this only converts the lower 4 bits to it's ASCII equivalent so you need to call the routine twice, the first time for the high bits (shifted 4 bits to the right).

Thanks! @betwixt for quick response. Actually i want to see the data of i2c device on computer screen using uart.

I'm sending multiple byte to slave and reading multiple byte from slave. I'm struggling to convert hex byte into ascii for slave device

C:
//PIC16F877A MPLAB XC8

// CONFIG
#pragma config FOSC = HS       // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF       // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)
// End of configuration

#include <xc.h>

#define _XTAL_FREQ 20000000
#define Baud_rate 9600

#define SLAVE_ADDRESS        0xA0         
#define POINTER_ADDRESS      0x00

#define error                  1

//Initializing UART module for PIC16F877A
void Initialize_UART(void)   
{
    TRISC6 = 0; // TX Pin set as output
    TRISC7 = 1; // RX Pin set as input
    SPBRG = ((_XTAL_FREQ/16)/Baud_rate) - 1;
    BRGH  = 1;  // for high baud_rate
    SYNC  = 0;    // Asynchronous
    SPEN  = 1;    // Enable serial port pins
    TXEN  = 1;    // enable transmission
    CREN  = 1;    // enable reception
    TX9   = 0;    // 8-bit reception selected
    RX9   = 0;    // 8-bit reception mode selected
}

//Function to send one byte of date to UART
void UART_send_char(char c) 
{
    while(!TXIF);  // Wait till the transmitter register becomes empty
    TXREG = c; //load the char to be transmitted into transmit reg
}

// Sends null-terminated ASCII string
void UART_send_string(char* p)
{
     char c;
     while((c = *p) != '\0')
     {
        UART_send_char(c);
        p++;
     }
}

void i2c_init(void)
{
    TRISCbits.TRISC3 = 1;   // SCL as input
    TRISCbits.TRISC4 = 1;   // SDA as input
    SSPCONbits.SSPM = 0b1000;  // Master mode using SSPADD as baud control
    SSPADD = 49;    //100kHz clock @ 20MHz Fosc
    SSPCONbits.SSPEN = 1;  //enable SSP
}

// Send an I2C START
void i2c_start(void)
{
    SEN = 1;   
    while (SEN);   
}

// Send an I2C STOP
void i2c_stop(void) 
{
    PEN = 1;   
    while (PEN);   
}

// Send an I2C REPEATED START
void i2c_restart(void)
{
    RSEN = 1;   
    while (RSEN);   
}

//Send one byte. Return ACK and NAK for I2C Bus
__bit i2c_SendByte(unsigned char dat)
{
    SSPBUF = dat;
    while (R_W);   
    return ACKSTAT;
}

//Receive one byte. flag=0 to send ACK, or 1 to send NAK
unsigned char i2c_ReceiveByte(unsigned char flag)
{
    RCEN = 1;         
    ACKDT = (__bit)flag;
    while (RCEN);       
    ACKEN = 1;           
    while (ACKEN);       
    return SSPBUF;
}


//Return 0 if no error
unsigned char WriteSlave(unsigned char slave_address, unsigned char pointer_address, unsigned char size, unsigned char * ptr)
{
    i2c_start(); // Send a start
 
    //send the I2C slave address low R/W bit
    if (i2c_SendByte(slave_address & 0xfe))
    {
        i2c_stop();
        return error;   //return error
    }
    
    //send the device register address
    if (i2c_SendByte(pointer_address))
    {
        i2c_stop();
        return error;   
    }
    
    for (; size>0; --size)
    {
        if (i2c_SendByte(*ptr++))
        {
            i2c_stop();
            return error;   
        }
        
    }
    i2c_stop();
    return 0;   //no error
}


unsigned char ReadSlave(unsigned char slave_address, unsigned char  pointer_address, unsigned char size, unsigned char * ptr)
{
     i2c_start();
      
    //Send the I2C slave address, R/W bit high)
    if (i2c_SendByte(slave_address | 0x01))
    {
        i2c_stop();
        return error;   
    }
    
    for (; size>0; --size)
    {
        unsigned char flag = (size == 1);   
        *ptr++ = i2c_ReceiveByte(flag);
    }
    i2c_stop();
    return 0;   //Return 0 if all OK, 1 if bus error
}

unsigned char BinToAsc(unsigned char BinValue)
{
    BinValue &= 0x0F;
    if(BinValue > 9) BinValue += 7;
    return(BinValue + '0');
}

void main(void) 
{
     unsigned char SlaveSend, SlaveRead;
     unsigned char Slave_data[] = { 0x01,0x02,  0x03, 0x04, 0x05, 0x06, 0x07 };
    
     unsigned char Slave_Read_data[8];

    Initialize_UART();    //Initialize UART module
    
    SlaveSend = WriteSlave(SLAVE_ADDRESS, POINTER_ADDRESS, 8, Slave_data);
            
    SlaveRead = ReadSlave(SLAVE_ADDRESS, POINTER_ADDRESS,  8, Slave_Read_data);

    while (1);
    
}
 

betwixt

Super Moderator
Staff member
Joined
Jul 4, 2009
Messages
14,921
Helped
4,874
Reputation
9,766
Reaction score
4,661
Trophy points
1,393
Location
Aberdyfi, West Wales, UK
Activity points
126,953
Precisely! - John99407, you have to pass the character (or byte from the I2C device) to BinToAsc() as I described in the second code part of post #2. Substitute the byte for the 'A' and let the UART_send_char() pass it to the serial output.

Brian.
 

John99407

Junior Member level 2
Joined
Jul 14, 2019
Messages
22
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
209
Precisely! - John99407, you have to pass the character (or byte from the I2C device) to BinToAsc() as I described in the second code part of post #2. Substitute the byte for the 'A' and let the UART_send_char() pass it to the serial output.

Brian.

would it look like this

C:
void main(void) 
{
     unsigned char SlaveSend, SlaveRead;
     unsigned char Slave_data[] = { 0x01,0x02,  0x03, 0x04, 0x05, 0x06, 0x07 };
    
     unsigned char Slave_Read_data[8];

    Initialize_UART();    //Initialize UART module
    
    SlaveSend = WriteSlave(SLAVE_ADDRESS, POINTER_ADDRESS, 8, Slave_data);
            
    SlaveRead = ReadSlave(SLAVE_ADDRESS, POINTER_ADDRESS,  8, Slave_Read_data);
    
    UART_send_char(BinToAsc(Slave_Read_data[0] >> 4));
    UART_send_char(BinToAsc(Slave_Read_data[0]));

    while (1);
    
}
 

KlausST

Super Moderator
Staff member
Joined
Apr 17, 2014
Messages
19,717
Helped
4,343
Reputation
8,695
Reaction score
4,304
Trophy points
1,393
Activity points
130,522
Hi,

basically yes.

I´d transmit a " " after the two nibbles.
and I´d use a loop 0...7 to read transmit all Slave_Read_Data

sending CR, LF or CrLf after the loop could be useful, too.

Klaus
 

LaTeX Commands Quick-Menu:

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top