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 make line Break UART

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



Joined: 20 Jun 2010
Posts: 6

View user's profile Send private message

How to make line Break UART
PostPosted: Sun Jun 20, 2010 8:11 am     Reply with quote

Hi,
I need set break state on UART TX line for a different time.
I'm using 18F2550
I try to disable transceiver but don't work.

Can somebody help me with source how to make line break or with library for software UART with break function.

I'm using CCS C compiler

BR
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jun 20, 2010 11:13 am     Reply with quote

Quote:

I need set break state on UART TX line for a different time.
I'm using 18F2550

Look in the 18F2550 data sheet. It has an EUSART module, which has
the ability to send a Break. CCS has support for this, with the following
line of code:
Code:

setup_uart(UART_SEND_BREAK);
ivojk



Joined: 20 Jun 2010
Posts: 6

View user's profile Send private message

re:
PostPosted: Sun Jun 20, 2010 11:47 am     Reply with quote

Hi,
I know this but this break send only 12 bits.
I need to make a break for a more long time.
I need to set line in break for 20ms for 30ms and etc.
I need to tell how long to be line in break state.


BR
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jun 20, 2010 1:38 pm     Reply with quote

Try this routine. It should work.
Code:

#include <18F452.h>
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)

#define BAUDRATE 9600
#define TX_PIN  PIN_C6
#define RX_PIN  PIN_C7

#use rs232(baud=BAUDRATE, xmit=TX_PIN, rcv=RX_PIN, ERRORS)

void send_break(int8 time_ms)
{
// Disable the UART and send a Break
// for the specified time.
setup_uart(FALSE); 
output_low(TX_PIN);
delay_ms(time_ms);

// Re-enable the UART.
setup_uart(TRUE);
set_uart_speed(BAUDRATE);
}

//======================================
void main(void)
{
int8 i;

while(1)
  {
   // Send 10 bytes of 0x55 to show UART activity
   for(i=0; i<10; i++)
       putc(0x55);
   
   send_break(20);
  }

}

Also, what's your compiler version ? I think there is a problem with the
delay_ms() routines for the 18F4550 and 18F2550. For versions 4.100
to 4.107, they run 4x longer than they should. For example, a 1 ms
delay becomes 4 ms. I tested this in hardware. (I couldn't test
vs. 4.108 yet, because I need to get a new .CRG file from CCS before
I can run it). This problem may only affect the 18F4550-series of PICs,
because I tested vs. 4.107 with an 18F452, and delay_ms() works
correctly. When I get the new .CRG files from CCS, I'll test vs. 4.108.
If it fails, then I'll email CCS support about it.
ivojk



Joined: 20 Jun 2010
Posts: 6

View user's profile Send private message

re:
PostPosted: Sun Jun 20, 2010 3:01 pm     Reply with quote

Hi,
I'm using V4.107
For me delay_ms() work correct with this version.
With setup_uart() break work but I see other problem
I can't receive after this.


BR
Ttelmah



Joined: 11 Mar 2010
Posts: 19512

View user's profile Send private message

PostPosted: Sun Jun 20, 2010 3:15 pm     Reply with quote

I'd probably just disable the transmit part, and do direct I/O, rather than using the CCS functions. It may be that the latter get confused after the changes.
So something like:
Code:

#byte TXSTA=0xFAC
#bit TXEN=TXSTA.5
#byte C_LAT=0xF8B
#bit TXBIT=C_LAT.6

void send_break(int8 msec) {
    C_LAT=0; //ensure latch is low, before disabling UART TX
    TXSTA=0;
    delay_ms(msec);
    TXSTA=1;
}

This way the receive side of the UART remains enabled.
On the software UART, you can just output a low, delay, then set the line high, wait one bit time, and carry on using the software UART functions as normal (you must set it back 'high', or the start bit for the next character will be missed.

Best Wishes
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jun 20, 2010 3:15 pm     Reply with quote

It works for me. I compiled the following program with vs. 4.107 and
it gives this output:
Quote:

Start:asdfasdfasdfasdf

I typed asdf repeatedly, and it sends the characters to the PIC from
the terminal window on the PC, and the PIC sends them back to the PC.
It's working.

I did find the problem with the delay_ms() routine is actually a problem
with the default fuse settings in vs. 4.100 to 4.107 (and possibly later).
The compiler is using CPUDIV4 as the default. You can fix it by adding
CPUDIV1 to the list of #fuses as shown below:
Code:

#include <18F4550.h>
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP, CPUDIV1
#use delay(clock=4000000)

#define BAUDRATE 9600
#define TX_PIN  PIN_C6
#define RX_PIN  PIN_C7

#use rs232(baud=BAUDRATE, xmit=TX_PIN, rcv=RX_PIN, ERRORS)

void send_break(int8 time_ms)
{
// Disable the UART and send a Break
// for the specified time.
setup_uart(FALSE); 
output_low(TX_PIN);
delay_ms(time_ms);

// Re-enable the UART.
setup_uart(TRUE);
set_uart_speed(BAUDRATE);
}

//======================================
void main(void)
{
int8 c;

printf("Start:\n\r");
   
send_break(20);

while(1)
  {
   c = getc();  // Get a char from the PC
   putc(c);     // Send it back to the PC
  }


}
ivojk



Joined: 20 Jun 2010
Posts: 6

View user's profile Send private message

RE
PostPosted: Mon Jun 21, 2010 12:12 am     Reply with quote

Hi,
PCM programmer - can you try to receive with PIC after break? Sending work perfect but on me I can't receive.

Ttelmah - I will try later your code and write result.

BR
Ttelmah



Joined: 11 Mar 2010
Posts: 19512

View user's profile Send private message

PostPosted: Mon Jun 21, 2010 1:54 am     Reply with quote

Have you got 'errors' in your RS232 setup?. Are you receiving using an interrupt, or just waiting for characters?.
Problem is, what is going to happen while you are sending the 'break'.
'Errors', should always be used on the hardware UART, unless you are manually handling the error bits yourself. Should really be the 'default'.
My code will allow an interrupt driven receive to carry on working (only turns off the transmit component in the UART).

Best Wishes
ivojk



Joined: 20 Jun 2010
Posts: 6

View user's profile Send private message

re
PostPosted: Mon Jun 21, 2010 3:36 am     Reply with quote

Hi,
This is a part of my code about reading from UART

void read(void)
{
char Counter, i;

Counter = getc();
for (i=1; i < Counter; i++)
{
Buffer[i] = getc();
}
}

I don't use interupts. I call getc() and wait to receive.

BR
Ttelmah



Joined: 11 Mar 2010
Posts: 19512

View user's profile Send private message

PostPosted: Mon Jun 21, 2010 3:56 am     Reply with quote

You absolututely _must_ have ERRORS in your RS232 declaration then. Otherwise the receive side of the UART, _will_ hang.
It is really always far 'better' to use buffered interrupt driven receive, if you want to be sure of not missing anything. My guess would be that the other end sends a response when 'break' is seen (quite common - a lot of devices give back their ID, or initialisation message, when a break is sent), and your receive UART is getting hung up, because this is not being read.

Best Wishes
ivojk



Joined: 20 Jun 2010
Posts: 6

View user's profile Send private message

RE
PostPosted: Mon Jun 21, 2010 5:09 am     Reply with quote

Hi,
Thanks for reply
Can you show me simple example about right way to receive?

Maybe this code is good:
Code:

char  Buff;
char  Counter;

#int_RDA
void  RDA_isr(void)
{
   disable_interrupts(GLOBAL);
   Buff = getc();
   put_usb();                // Send byte to PC by USB
   enable_interrupts(GLOBAL);
   
}

BR
Mcasclv



Joined: 21 Jun 2010
Posts: 1
Location: Barcelona

View user's profile Send private message MSN Messenger

PostPosted: Mon Jun 21, 2010 12:19 pm     Reply with quote

Hello! We are trying to communicate with a PIC 18F2550 BQ2013.
In the communication we use the UART, 8 data bits by sending two stop bits no parity, and a baudrate of 57600, and asynchronous mode. It is necessary to send a break to start the communication.
The reception and transmission is made to a single pin of the bq2013 (HDQ protocol).
We managed to send data but only received the same as sent.
Code:

#include <18F2550.h>
#device adc=8
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL3,CPUDIV1,VREGEN
#use delay(clock=48000000)
#use rs232(baud=57600,xmit=PIN_C6,rcv=PIN_C7,parity=N,bits=8,STOP=2,uart1)

/////////////////////////////////////////////////////////////////////////
#define USB_HID_DEVICE     FALSE             //deshabilitamos el uso de las directivas HID
#define USB_EP1_TX_ENABLE  USB_ENABLE_BULK   //turn on EP1(EndPoint1) for IN bulk/interrupt transfers
#define USB_EP1_RX_ENABLE  USB_ENABLE_BULK   //turn on EP1(EndPoint1) for OUT bulk/interrupt transfers
#define USB_EP1_TX_SIZE    2                 //size to allocate for the tx endpoint 1 buffer
#define USB_EP1_RX_SIZE    2                 //size to allocate for the rx endpoint 1 buffer

#include <pic18_usb.h>     //Microchip PIC18Fxx5x Hardware layer for CCS's PIC USB driver
#include <descriptor.h>    //ConfiguraciĆ³n del USB y los descriptores para el dispositivo
#include <usb.c>         

#byte TXSTA=0xFAC
#bit TXEN= TXSTA.5
#bit SYNC=TXSTA.4
#bit SENDB=TXSTA.3
#byte RCSTA=0xFAB
#bit SPEN=RCSTA.7
#byte SPBRGH=0xFB0
#byte SPBRG=0xFAF
#bit BRGH=TXSTA.2
#byte BAUDCON= 0xFB8
#bit BRG16=BAUDCON.3
#byte TXREG=0xFAD


#define LEDV    PIN_B6
#define LEDR    PIN_B7
#define TXPIN   PIN_C6
#define RXPIN   PIN_C7
#define LEDA    PIN_B0
#define ENCENDER  output_high
#define APAGAR output_low
 

#define control     bufferI[0]
#define direccion   bufferI[1]
#define dato        bufferO[0]
#define datoHdq     bufferII[0]
******************************************************

             ........

  TXEN=1;
               SYNC=0;
               SPEN=1;
               BRGH=1;
               SPBRGH=8;
               BRG16=0;
               SendBreak();
               
               TXREG=direccion;
               datoHdq=getc();

             .........

*****************************************
void SendBreak(void){
   setup_uart(FALSE);
   APAGAR(TXPIN);
   delay_us(190);
   ENCENDER(TXPIN);
   delay_us(40);
   setup_uart(TRUE);
   set_uart_speed(57600);
}

Gracias!!!
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