Author Topic: 5 data bits via UART  (Read 1640 times)

0 Members and 1 Guest are viewing this topic.

Offline Kittu20Topic starter

  • Regular Contributor
  • *
  • Posts: 96
  • Country: in
5 data bits via UART
« on: September 18, 2023, 12:26:58 pm »
Hello everyone

I've been working with UART communication and typically use the standard 8N1 configuration. However, I recently came across a scenario where I want to configure UART for 5 data bits (5N1). I've already written code to handle UART communication for 8N1, but I'm unsure about how to transfer only 5 bits of data.

Can you provide  code examples on how to transmitting and receiving data for 5N1  ?

Code: [Select]

#include <xc.h>
#include <stdio.h>
#include"config.h"


void initializeOscillator(void);
void initializeEUSART1(void);

/*****
*   NOTE:    This function configures the oscillator settings for the microcontroller.
*            It sets the IRCF bits to 110 for HF-INTOSC/2 (8 MHz, default).
*****/
void initializeOscillator(void)
{
    OSCCON  = 0x60;     // Set IRCF bits to 110 for HF-INTOSC/2 (8 MHz, default)
    OSCCON2 = 0x00;
    OSCTUNE = 0x00;
    REFOCON = 0x00;
}


void initializePort() {
    // Set LATx registers to initial states (all low)
    LATA = 0x00;
    LATB = 0x00;
    LATC = 0x00;
    LATD = 0x00;
    LATE = 0x00;
 

    // Set TRISx registers to configure pins as outputs (all output)
    TRISA = 0x00;   
    TRISB = 0x00;     // RB0 is RED, RB1 is YELLOW and RB2 is GREEN LED
    TRISC = 0x80;     // RC7 is TX and RC6 TX
    TRISD = 0x00;   
    TRISE = 0x00;   

    // Additional configuration for unused peripherals
    ANCON0 = 0x00;     // Set all analog pins to digital mode
    ANCON1 = 0x00;     // Set all analog pins to digital mode
    CM1CON = 0x00;     // Turn off Comparator 1
    CM2CON = 0x00;     // Turn off Comparator 2
    ADCON0 = 0x00;     // Disable A/D conversion
    ADCON1 = 0x00;     // Disable A/D conversion
    ADCON2 = 0x00;     // Disable A/D conversion
}

/*****
*
*   NOTE:    This function configures the EUSART1 settings for communication.
*
*****/
void initializeUART1() {
 
    // Configure BAUDCON1 register
    // Bit 7: ABDOVF = 0 (Auto-Baud Acquisition Rollover Status bit - Cleared in software)
    // Bit 6: RCIDL = 0 (Receive Operation Idle Status bit - Receive operation is active)
    // Bit 5: RXDTP = 0 (Received Data Polarity Select bit - Receive data is not inverted)
    // Bit 4: TXCKP = 0 (Clock and Data Polarity Select bit - Idle state for transmit is high level)
    // Bit 3: BRG16 = 1 (16-Bit Baud Rate Register Enable bit - 16-bit Baud Rate Generator)
    // Bit 2: Unimplemented: Read as ?0? (Reserved, read as '0')
    // Bit 1: WUE = 0 (Wake-up Enable bit - RX pin is not monitored or rising edge is detected)
    // Bit 0: ABDEN = 0 (Auto-Baud Detect Enable bit - Baud rate measurement is disabled or completed)

    BAUDCON1 = 0b00001000; // Set BRG16 bit to 1 (16-Bit Baud Rate Register Enable)
 
    // Calculate and set SPBRG1 for a baud rate of approximately 9600 at 8 MHz
    SPBRG1 = 207;
    SPBRGH1 = 0;
 

    // TXSTA1 register configuration
    // Bit 7: CSRC = 0 (Clock Source Select bit - Don't care in Asynchronous mode)
    // Bit 6: TX9 = 0 (8-bit transmission)
    // Bit 5: TXEN = 1 (Transmit is enabled)
    // Bit 4: SYNC = 0 (Asynchronous mode)
    // Bit 3: SENDB = 0
    // Bit 2: BRGH = 1 (High-speed baud rate)
    // Bit 1: TRMT = 1 (TSR is empty initially)

    TXSTA1 = 0b00100100; // Configure TXSTA1 register


    // RCSTA1 register configuration
    // Bit 7: SPEN = 1 (Serial Port Enable bit - Serial port is enabled)
    // Bit 6: RX9 = 0 (8-bit reception)
    // Bit 5: SREN = 0 (Single Receive Enable bit - Don't care in Asynchronous mode)
    // Bit 4: CREN = 1 (Continuous Receive Enable bit - Enables receiver)
    // Bit 3: ADDEN = 0 (Address Detect Enable bit - Don't care in Asynchronous mode)
    // Bit 2: FERR = 0 (Framing Error bit - No framing error)
    // Bit 1: OERR = 0 (Overrun Error bit - No overrun error)

     RCSTA1 = 0b10010000; // Configure RCSTA1 register

}


void hardwareInitialize() {
 
    // Initialize the oscillator
    initializeOscillator();
 
    // Initialize Port Pins
    initializePort();
 
    // Initialize Uart1
    initializeUART1();
 
}

/*****
*
*   NOTE:    This function waits until the transmitter buffer is empty (TXIF is set)
*            and then sends the character by placing it in the TXREG1 register.
*
*****/
void UARTWrite(char Character)
{
    // Wait until the transmitter buffer is empty (TXIF is set)
    while (TXIF == 0);

    // Send the character by placing it in the TXREG1 register
    TXREG1 = Character;
}


/*****
*
*   NOTE:    This function waits until the receiver buffer is full (RCIF is set)
*            and then reads the received character from the RCREG1 register.
*
*****/
char UARTRead(void)
{
    // Wait until the receiver buffer is full (RCIF is set)
    while (RCIF == 0);

    // Read the received character from the RCREG1 register
    return RCREG1;
}

/*****
*
*  main - Main program function
*
*****/
void main(void)
{
    // Initialize hardware
    hardwareInitialize();

    // Delay for 5 seconds
    __delay_ms(5000);

    while (1)
    {
        // Define a character to send
        char Character = 'U';
        char ReceivedChar;
     
        ReceivedChar = UARTRead();         // Read a command from UART
   
        UARTWrite(ReceivedChar);           // Send the command back

        // Delay for 5 seconds before the next transmission
        __delay_ms(5000);
    }
}
 



« Last Edit: September 18, 2023, 12:30:53 pm by Kittu20 »
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12864
Re: 5 data bits via UART
« Reply #1 on: September 18, 2023, 01:09:45 pm »
From the look of your code, you are using an 8 bit PIC.  AFAIK there aren't any 8 bit PICs with 5 bit UART support (as mechanical teletypes were already a dead technology by the date Microchip was founded), but you can send 5 bit data by OR masking the three high bits to 1.  This gives you too many stop bits (5N4) but is compatible with a 5N1 receiver albeit with only 70% of the peak characters per second for the same baud rate.  This does *NOT* work for receiving 5N1 data unless there are at least three extra idle bits between characters, so if you need bidirectional comms or the full data rate your only option is to write a 5 bit capable bit-banged software UART.
« Last Edit: September 18, 2023, 10:34:22 pm by Ian.M »
 
The following users thanked this post: Kittu20

Offline jpanhalt

  • Super Contributor
  • ***
  • Posts: 3479
  • Country: us
Re: 5 data bits via UART
« Reply #2 on: September 18, 2023, 01:29:48 pm »
I suspect there are 3 viable options:
1) Bit bang for 5-bit,
2) Pack your 5-bit data into 8-bit bytes, or
3) Pad your data to give 8-bits.

I suspect you are not interested in bit banging, but here's an example I got from Mike (K8LH) years ago in case you are curious of what it looks like in PIC Assembly.  It can be adapted to 5 bit, but you will need to also get the receive end (e.g., Get232). 

Code: [Select]
;****************************************************************************** 
;                             PUT232 
; Put232 (9600 baud) -- Mike McLaren, K8LH (Jan-09)                                               
;****************************************************************************** 

Put232
movlb 2
movwf txbyte ; save Tx data byte             
movlw 10 ; 1 start + 8 data + 1 stop bit   
movwf bit_ctr ; setup bit counter               
bcf status,0 ; C = 0 (start bit)               
DelayCy (104*usecs-10) ; 104 usecs minus 10 cycles(added)
goto SendBit ; send start bit                 
NextBit
DelayCy (104*usecs-10) ; 104 usecs minus 10 cycles       
bsf status,0 ; always shift in a 'stop' bit   
rrf txbyte,f ; put data bit in Carry           
SendBit
movf LATD,W ; read port                       
iorlw 1<<1 ; set Ser_out pin bit to 1       
btfss status,0 ; if data bit = 1 skip, else     
xorlw 1<<1 ; set Ser_out pin bit to 0    
movwf LATD ; precise update intervals       
decfsz bit_ctr,f ; done? yes, skip, else           
goto NextBit ; send next bit                   
retlw 0 ;
"DelayCy" is a macro.  You will need to insert an appropriate delay for your baud rate.



 
« Last Edit: September 18, 2023, 01:33:01 pm by jpanhalt »
 
The following users thanked this post: Kittu20

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 5914
  • Country: es
Re: 5 data bits via UART
« Reply #3 on: September 18, 2023, 02:24:03 pm »
Stop bit is a "1":


So, it's very simple, use the 8-bit UART, set the 3 MSB to 1, so the last 3 bits and the stop are merged together:

Code: [Select]
TX = DATA_5B | 0xE0;
This makes the uart to send:
Start D0 D1 D2 D3 D4 1 1 1 Stop
A 5-bit uart receiver will take D5 as the stop bit, the remaining data is 1 so no new start will happen.

This "hack" will work with any number of bits between 1 and 8, but the PIC will be still sending 8bits, so the effective data rate won't be faster, if that was you target.
« Last Edit: September 18, 2023, 02:33:47 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 
The following users thanked this post: PCB.Wiz

Offline Kittu20Topic starter

  • Regular Contributor
  • *
  • Posts: 96
  • Country: in
Re: 5 data bits via UART
« Reply #4 on: September 18, 2023, 02:26:59 pm »
I've come across numerous documents and online tutorials that discuss the ability to transfer data with 5 to 9 bits, but most examples and practical applications seem to focus on the standard 8-bit configuration. This has sparked my curiosity about experimenting with 5 or 6 data bits. When shifting the data position to achieve 5 bits, there's still the transmission of 8 bits.

Could you share your experiences on how one might effectively experiment with data configurations of 5 or 6 bits, and what considerations are important when attempting such configurations? Additionally, have you encountered any real-world scenarios where non-standard data bit configurations were beneficial
« Last Edit: September 18, 2023, 02:28:52 pm by Kittu20 »
 

Offline jpanhalt

  • Super Contributor
  • ***
  • Posts: 3479
  • Country: us
Re: 5 data bits via UART
« Reply #5 on: September 18, 2023, 03:29:34 pm »
Could you share your experiences on how one might effectively experiment with data configurations of 5 or 6 bits, and what considerations are important when attempting such configurations? Additionally, have you encountered any real-world scenarios where non-standard data bit configurations were beneficial
Just bit-bang and set bit_ctr to whatever you want +2.   As mentioned, you need the Get232 code, which has a very similar structure.

Real world?  PIC's hardware does allow 9-bit.
 

Offline Doctorandus_P

  • Super Contributor
  • ***
  • Posts: 3367
  • Country: nl
Re: 5 data bits via UART
« Reply #6 on: September 18, 2023, 03:59:19 pm »
Read the datasheet of your microcontroller.
Some microcontrollers can be set up to do 5 bit data with the U(s)ART.
 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3240
  • Country: gb
Re: 5 data bits via UART
« Reply #7 on: September 18, 2023, 04:30:34 pm »
Could you share your experiences on how one might effectively experiment with data configurations of 5 or 6 bits,

As others have already said you can only configure your UART for 5 bit data if the UART supports this.  Some do, some don't.  The code you posted suggest you are using a PIC of some type, but you haven't told us which one.  If your UART does not support 5 bit operation, then you will have to bit bang the data i.e. software emulation of the UART.
 

Offline Doctorandus_P

  • Super Contributor
  • ***
  • Posts: 3367
  • Country: nl
Re: 5 data bits via UART
« Reply #8 on: September 18, 2023, 05:04:26 pm »
Bit banging works adequately for "low baudrates" (and "low" depends on the uC you use and how much other things it has to do)

And as other's have already mentioned, pre-formatting the data works, and in it's simplest form you will then just send the data with 4 stop bits, but any "receiving end" should be able to handle that. If you want to send more data, and can't afford to send 5 stop bits for each byte, then you can use dirty tricks such as resetting your U(s)ART after the 5 data bits have been sent.

Receiving 5N1 data is easy if there is enough room between the bytes, but if it's sent as a continuous 5n1 steam, then it's probably either bitbanging or using a U(s)ART that supports 5-bit data.
 

Online PCB.Wiz

  • Super Contributor
  • ***
  • Posts: 1551
  • Country: au
Re: 5 data bits via UART
« Reply #9 on: September 18, 2023, 09:15:34 pm »
I've come across numerous documents and online tutorials that discuss the ability to transfer data with 5 to 9 bits, but most examples and practical applications seem to focus on the standard 8-bit configuration. This has sparked my curiosity about experimenting with 5 or 6 data bits.
When shifting the data position to achieve 5 bits, there's still the transmission of 8 bits.
Nope, not if the UART supports 5 bits.  (see #3)

Could you share your experiences on how one might effectively experiment with data configurations of 5 or 6 bits, and what considerations are important when attempting such configurations?
Err ? Find UARTS that supports the 5 or 6 bits you seek, and try them ?

Additionally, have you encountered any real-world scenarios where non-standard data bit configurations were beneficial
The obvious saving is time. Other reasons may be more obtuse, like if you wanted to avoid casual hacking, or lock customers into your systems...

These modes are historic, as in really historic...  ;)

https://en.wikipedia.org/wiki/Baudot_code

So you can see where 5 bit UART came from.
 

Offline jpanhalt

  • Super Contributor
  • ***
  • Posts: 3479
  • Country: us
Re: 5 data bits via UART
« Reply #10 on: September 18, 2023, 09:27:17 pm »
Mid-range PIC's do not support 5-bit UART.  Based on the TS's latest post, I suspect this is just a "what if" waste of time, as the TS has failed to give any specifics whatsoever.
 

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14489
  • Country: fr
Re: 5 data bits via UART
« Reply #11 on: September 18, 2023, 09:40:25 pm »
A couple notes:
- The OP didn't bother to say which MCU they were trying to use and made people guess from the posted piece of code. All we know is that it looks like a PIC supported by the XC compiler, probably an 8-bit PIC and XC8, although I'm not even sure. Frankly I didn't bother checking out if the few registers used in the code were indicative of a particular PIC model, there are literally hundreds.
- If it turns out it doesn't natively support 5-bit data frames, then as said above, you could use some tricks (with limitations) or just bit-bang it (probably the easiest and making the most sense).
- We don't know what baud rate nor what system clock the OP is dealing with, so the bit-banging option may or may not be an option. Also, depending on which interrupts are enabled, it may require some particular care, like disabling interrupts while transmitting/receiving, or selectively disabling the ones appropriate, not completely trivial either.

Not to sound like a free lecture, but if you want more accurate, to-the-point answers while making people waste less time, giving more accurate requirements/context will go a long way. Actually, properly defining a problem is often 80% of the solution.

« Last Edit: September 18, 2023, 09:42:36 pm by SiliconWizard »
 

Offline Kittu20Topic starter

  • Regular Contributor
  • *
  • Posts: 96
  • Country: in
Re: 5 data bits via UART
« Reply #12 on: September 19, 2023, 01:35:48 am »
I apologize for not mentioning my microcontroller earlier. I'm using a PIC18F45K80. After reviewing the datasheet, specifically in Section 22.1 on page 327, it appears to me that this microcontroller only supports 8-bit or 9-bit communication
 
The following users thanked this post: Ian.M

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: 5 data bits via UART
« Reply #13 on: September 19, 2023, 05:25:06 am »


Quote from: Kittu20 on Today at 07:26:59 am
Additionally, have you encountered any real-world scenarios where non-standard data bit configurations were beneficial

My first project out of college involved interfacing a mainframe to a newswire that ran a 6bit version of baudot.  That was 1981.  I haven't seen anything shorter than 7 bits since, despite much of my career revolving round async UART communications.


 

Offline Smokey

  • Super Contributor
  • ***
  • Posts: 2597
  • Country: us
  • Not An Expert
Re: 5 data bits via UART
« Reply #14 on: September 19, 2023, 05:29:34 am »
I suspect there are 3 viable options:
1) Bit bang for 5-bit,
2) Pack your 5-bit data into 8-bit bytes, or
3) Pad your data to give 8-bits.
....

... 4) send the data in 40-bit (8-byte) buffers (or 8 x 5-bit transmissions at a time).
 
The following users thanked this post: SiliconWizard


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf