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

Looking for SW serial port example under interrupt control

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



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

Looking for SW serial port example under interrupt control
PostPosted: Thu Mar 18, 2004 4:51 pm     Reply with quote

I'm writing an application that has to read data from one serial RS-232 device, process the data and then pass it on to a second serial device. One of these devices can use the inbuilt USART of my PIC18F458, but the other device must be handled by a software driven serial port.

Because I have several other ports to manage as well and the data can arrive any moment in time, I'm looking for a bit banging example under interrupt control. I rather don't use an external UART if I can save the money doing it in software.

I found an example in the book Serial PIC'n by Roger Stevens but haven't managed yet to port the assembly code to my CCS-compiler. Also I'm not so sure this code can handle higher data rates.

What clock rates are you people running your PICs at? A nice round value like 20MHz or a multiple of 1024Hz, like 19,66MHz so you can easily use the Timer0 overflow?

What experiences do you people have using bit banging? Is it reliable?

Hints, tips or example code are appreciated.
ritchie



Joined: 13 Sep 2003
Posts: 87

View user's profile Send private message

PostPosted: Thu Mar 18, 2004 5:18 pm     Reply with quote

Try this forum link http://www.ccsinfo.com/forum/viewtopic.php?t=17448&highlight=intext

Scroll to the bottom of the page... their u can see an example on how to implement software-based UART using external interrupt.

BTW, their is a limitation of software UART in terms of baud rate due to latency issue. I guess you have to check or conduct test on the speed you are going to use.

Hope this helps....

Smile Razz
Haplo



Joined: 06 Sep 2003
Posts: 659
Location: Sydney, Australia

View user's profile Send private message

PostPosted: Thu Mar 18, 2004 5:39 pm     Reply with quote

Or you can connect your RX line to a capture pin and configure it to interrupt on the falling edge. I've used it before and it works like a charm.
Guest








PostPosted: Sun Mar 21, 2004 6:08 pm     Reply with quote

Haplo wrote:
Or you can connect your RX line to a capture pin and configure it to interrupt on the falling edge. I've used it before and it works like a charm.


Do you have a sample snippet in using the capture pin and configured to interrupt?

This might be better than the external interrupt.

Thanx
ritchie



Joined: 13 Sep 2003
Posts: 87

View user's profile Send private message

PostPosted: Sun Mar 21, 2004 6:27 pm     Reply with quote

Haplo wrote:
Or you can connect your RX line to a capture pin and configure it to interrupt on the falling edge. I've used it before and it works like a charm.


This is great software UART using CCP interrupt!!! at what speed did you configure the UART? Is it capable of handling 115200bps?

Is it possible to share a snippet in utilizing this method? CCP configuration and #int_ccp configuration?

Thanx
Haplo



Joined: 06 Sep 2003
Posts: 659
Location: Sydney, Australia

View user's profile Send private message

PostPosted: Sun Mar 21, 2004 10:07 pm     Reply with quote

Whether it is capable of 115200 or not depends on many factors such as your crystal speed and the other interrupts you are using. As for the code, there is not much to share. Initialise the capture module with

setup_ccp1(CCP_CAPTURE_FE);
enable_interrupts(INT_CCP1);


And then read a whole byte (and put it in your receive buffer) in the interrupt routine. Remember this method is only good enough if you can afford to wait for one whole byte in your interrupt routine. Otherwise you'll also need to use timer interrupts to be able to capture each bit one by one.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Tue Mar 23, 2004 2:46 am     Reply with quote

I do like the idea of using the capture register for receiving data!
This way I get an accurate 16-bit timestamp and have the advantage of being able to wake up from sleep-mode without using one of the EXT-INT lines.

Disadvantage is that for full-duplex transmissions I still need one of the timers for generating bit-time interrupts. And because it all works under interrupt I have to be very carefull not to generate jitter on the transmitting.

Quote:
And then read a whole byte (and put it in your receive buffer) in the interrupt routine. Remember this method is only good enough if you can afford to wait for one whole byte in your interrupt routine.


I don't like to block my interrupt routine for reading a whole byte! And I don't see the reason for blocking, why not implement it like this: In your interrupt routine you can save the timestamp and set the interrupt to trigger on the opposite edge. Then, next time the interrupt gets triggered you can read the time difference between the interrupts and from this derive the number of received bits with same level. Then set opposite edge again and repeat until the whole byte is received.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Tue Mar 23, 2004 4:01 am     Reply with quote

I'm sure it is possible to create full duplex serial communications in software, but I'm afraid it will take a lot of time to make it stable for commercial use. Especially I'm concerned about bit-jitter in the transmitting.

Just for fun a timing calculation:
Running at 20Mhz and transmitting data at 19200 baud gives me about 260 instructions / bit time for the transmit. Assuming the receiver will sample the data somewhere between 1/3 and 2/3 of the bittime gives a maximum allowed latency of 86 instructions.
Checking the generated code for #int_global gives an overhead of 45 instructions, so my transmit and receive functions will have to do their job in 41 instructions.... Is feasable, but tight.

A future development will require my device to accept 56k baud... I think it's better to safe development time and spend the saved the money on an additional hardware UART like the MAX3100 or MAX3110.
Haplo



Joined: 06 Sep 2003
Posts: 659
Location: Sydney, Australia

View user's profile Send private message

PostPosted: Tue Mar 23, 2004 6:54 am     Reply with quote

If you don't want to use CCS software interrupt and want to implement it yourself, you'd have to:
1.Get a capture interrupt to detect the start bit
2.Disable the capture interrupt
3.Load one of the timers so it would overflow in half-bit time
4.In the timer ISR read one bit and store it
5.Reload the timer, go to 3, continue until you receive the stop bit
6.Put all the bits together and create the data byte
7.Disable the timer interrupt, enable the capture interrupt and wait for the next byte to come.

This should be easy to do, none of the two ISRs will have more than a few instruction.
John P



Joined: 17 Sep 2003
Posts: 331

View user's profile Send private message

PostPosted: Wed Mar 24, 2004 10:58 am     Reply with quote

I have done this for 19200 baud, but it isn't true full duplex. I wanted to use a single timer for incoming and outgoing data, and keep the same timer running to operate other processor functions (minor glitches are acceptable). So my design shifts the timer trip point as needed to process incoming data bytes, which means that if an outgoing byte is in progress when the incoming byte begins, it'll get distorted and most likely won't be properly received. There are checksums included, though, so the computer that's on the other end of the line can verify the incoming packets and ask for a re-transmission if necessary.

This would all be a lot easier if half-duplex operation were usable. I could imagine various ways to set this up, depending on which direction of data has priority.
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