SUART on PIC18F14K22

General discussion relating to the library modules supplied with the compiler

Moderators: David Barker, Jerry Messina

Post Reply
blackcattech
Posts: 113
Joined: Mon Jan 11, 2010 10:39 pm
Location: Chesterfield

SUART on PIC18F14K22

Post by blackcattech » Thu Mar 08, 2012 11:25 am

Has anyone managed to get the Software UART working on the PIC18F14K22? I've been banging my head against a brick wall for ages with it and am still getting nowhere...

I am developing a sub-module for a product that doesn't normally use the UART, it uses I2C to communicate between modules. To test it I want to get data from it to a PC so as I've not implemented the I2C code yet I'm intending to use those pins to bit-bang data out to the PC.

The first problem is that the SUART module seems to completely mess up the baud rate calculation. I was trying to get 9600 baud initially, using sbr9600 got me about 6600 baud, measured on a 'scope. Changing to using sbr4800 made no difference. I then decided to try and get 1200 baud working as I was only clocking the PIC at 4MHz so I was wondering if I was trying to achieve too high a baud rate.

I tried calculating my own delay value and got a value of 813. The code viewer suggests a value of 51 based on a 20MHz oscillator. That is quite a difference - heaven known what baud rate 51 would end up giving at 20MHz but it wouldn't be 1200 baud!

Using 813 I get a measured 1200 baud on my scope, all well and good.

However, the data I'm getting out is complete gibberish.

I should say I have had a version of this working on a prototype board which had RS232 built on and used the hardward USART. This worked fine, all I've done initially is change over to the software UART.

Does anyone have any suggestions before I give up and hard-wire to the UART pins on the PIC? I could do with getting this working as a way to test these boards separate from the complete system.

Is there something about the 'K' PICs that would break the code, or is there a fundamental problem? I wonder if it has been written to work at 20MHz and no testing has been done at other speeds?

blackcattech
Posts: 113
Joined: Mon Jan 11, 2010 10:39 pm
Location: Chesterfield

Post by blackcattech » Thu Mar 08, 2012 3:29 pm

Finally got it working - I needed to change the mode to 'umOpenTrue'

I think the major problem with the SUART module is that the documentation is, frankly, pathetic. Nothing is explained. Even a brief summary of the modes would be useful - you would assume that as a UART is most commonly used to talk to a PC that the 'default' mode would do that, or there would at least be a comment in the help file somewhere telling you which mode to use.

The calculation of the baud rate values is still way out though, I'll have to look in to rewriting this at some point as it is daft having to work it out manually.

Jerry Messina
Swordfish Developer
Posts: 1471
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Thu Mar 08, 2012 4:01 pm

I tried calculating my own delay value and got a value of 813. The code viewer suggests a value of 51 based on a 20MHz oscillator. That is quite a difference - heaven known what baud rate 51 would end up giving at 20MHz but it wouldn't be 1200 baud!
I'm not seeing the same thing here. At 20MHz, I see 'sbr1200 = 829', not 51.

Also, if I add a 'clock=4' statement to the file so it shows the baudrate values values for 4MHz, I see 'sbr1200 = 813', so it doesn't seem that there's a need to change any of the calculations or manually compute them.

Open, true, etc would depend on how your hardware's connected to the PC's serial port (via MAX232, etc)

blackcattech
Posts: 113
Joined: Mon Jan 11, 2010 10:39 pm
Location: Chesterfield

Post by blackcattech » Thu Mar 08, 2012 4:28 pm

The modes are probably obvious to those who are familiar with serial comms, to those who aren't then a basic explanation wouldn't go amiss, even if it is just 'use this mode to do this'.

As for the sbr values, if I have the 'SUART' module open in Swordfish, I get:

CycleCost = 20
FROSC = 20000000
tcy1200 = 4166.666667
sbr1200 = 51

If I open my code which has Clock = 4 at the start, I get

sbr1200 = 50
(it doesn't show FROSC or tcyxxxx, presumably as they are internal only)

No idea what is going on but something is badly wrong. This is the SE version of Swordfish. I can't see anything else that needs setting that would affect this. I've not modified the library at all. I'll do some cross-checking when I have a little more time, but I've seen this on two different PCs now so it must be either the SE compiler or the library that comes with it.

Jerry Messina
Swordfish Developer
Posts: 1471
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Thu Mar 08, 2012 6:14 pm

Interesting.

As I said, that's not what I see even with the SE version (and the SUART modules are the same).

Can't really disagree about the umMode settings. I can see where it would be confusing.

blackcattech
Posts: 113
Joined: Mon Jan 11, 2010 10:39 pm
Location: Chesterfield

Post by blackcattech » Fri Mar 09, 2012 8:22 am

The code in the version of SUART I have to determine the sbr value (for 1200 baud but the rest are the same just with the appropriate baud rate) is:

Code: Select all

CycleCost = 20,                           // TX and RX cycle cost

FROSC = _clock * 1000000,                 // clock (MHz)

tcy1200 = (2 * FROSC) / (4 * 1200) / 2   // 1200 baud Tcy

sbr1200 As Word = (tcy1200 - CycleCost) / _clock / 4
Based on a 20MHz clock that works out to:

tcy1200 = 40000000 / 4800 / 2 = 4166.6666667

sbr1200 = 4146.67 / 20 / 4 = 51.8

Miles away from the 829 it should be!

My workings:
One bit time is 1/1200 = 833.33usec
One instruction = 4 / clock = 0.2usec
Therefore, 20 instructions = 4usec
833 - 4 = 829.

The sbr value is just the delay in usec so that is all you need to do.

The maths in the version of the library I have seems overly complicated, unless that is to get around some limitation of the precompiler.

I'd suggest (with appropriate commenting to explain)

CycleCost = (20 * 4) / _clock
tcy = 1000000/baud
sbr = tcy - CycleCost

For 1200 baud at 4MHz that would give:

CycleCost = 80 / 4 = 20
tcy = 1000000/1200 = 833.33
sbr = 833 - 20 = 813

Which is correct.
I'm not sure why the code is so complex to be honest, it would be easier to document how the baud rate is being worked out and do the simpler way above?

Jerry Messina
Swordfish Developer
Posts: 1471
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Fri Mar 09, 2012 10:17 am

The code in the version I have is slightly different...

Code: Select all

sbr1200 As Word = (tcy1200 - CycleCost) / (_clock / 4)

blackcattech
Posts: 113
Joined: Mon Jan 11, 2010 10:39 pm
Location: Chesterfield

Post by blackcattech » Fri Mar 09, 2012 10:39 am

Makes sense and corrects the error.

Which version do you have? (Of the SUART library) Mine is 1.3 from May 2006. I can't remember when I installed it on here, but much more recently than that.

Jerry Messina
Swordfish Developer
Posts: 1471
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Fri Mar 09, 2012 10:52 am

Mine says the same thing, although the actual date on the file is June 2008.

From what I remember, it's from the latest SF SE download (v2213).

blackcattech
Posts: 113
Joined: Mon Jan 11, 2010 10:39 pm
Location: Chesterfield

Post by blackcattech » Fri Mar 09, 2012 12:22 pm

Just realised I was only on V2.2.0.3 so I've updated to the latest version and the file is now correct.

The lesson of the day is always make sure you are on the most recent version, although this bug must have been there for a long time as the SE version seemed to be on 2.2.0.3 for quite a while.

Post Reply