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

18F26K22 uart

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



Joined: 05 Apr 2011
Posts: 303

View user's profile Send private message

18F26K22 uart
PostPosted: Fri Mar 02, 2012 2:56 pm     Reply with quote

The 18F26K22 has an errata on the UART that requires BRG16 = 1 and BRGH = 1. Is there a way to force the set_uart_speed to use this? I can set all of the registers manually but would like to be able to use the built in functions if possible.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Mar 02, 2012 9:13 pm     Reply with quote

I don't think there is a way to do it with the built-in function. I think you
need to write your own function (with a new name) that uses the equation
given in the errata. Use #byte and #bit statements to define the
baudrate registers and the BRG16 and BRGH bits. Then write to the
registers and bits in your new function.
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Sat Mar 03, 2012 4:58 pm     Reply with quote

OOPS - I found it in version D of the erratum.
I did not know there were SO many problems with the silicon in this part !!!!!

I had been considering the 46k22 for its DUAL EUSARTS but now ???

Second and third thoughts come to mind and
this takes me back to the crazy B.S. surrounding 16C74 and 16c6xx UART speed limit plagues of many years ago - only this is WORSE by far.....

A 1 in 256 chance of mis-interpreting or losing characters ??
Totally unacceptable IMB.

OH - right I can work around it -- great
Confused Sad Sad
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

a fix for the problem
PostPosted: Sun Mar 04, 2012 7:39 pm     Reply with quote

Code:

//  void Set_baudfix( int1 uartnum, unsigned int32 masterfreq, unsigned int32 baudrate){
void Set_baudfix( unsigned int32 masterfreq, unsigned int32 baudrate){

    unsigned int16 baudiv;
// UART 1
#byte SPBRG =0xFAF
#byte SPBRGH=0xFB0
#byte TXSTA =0xFAC
#byte BAUDCON=0xFB8
#BIT  BRG16 =0xFB8.3

// UART 2
#byte SPBRG2 =0xF75
#byte SPBRGH2=0xF76
#byte TXSTA2 =0xF72
#byte BAUDCON2=0xF70
#BIT  BRG16_2 =0xF70.3

    baudiv= (unsigned int16) (( masterfreq / (4*baudrate))-1);

    BRG16=1;
    SPBRG =make8(baudiv,0);
    spbrgh=make8(baudiv,1);
    txsta=0xA6;  // std 8 bit see txsta bit mapping and BRGH=1


}


Sorry if it looks like Hi-Tech code but it does the trick per the UART Error issue. I used #use RS-232 as usual - and then call this function in MAIN after I intialize all the PIC I/O and onboard hardware features I will be using but before any RS-232 of course - typically JUST before I start my RS-232 interrupt receive services and have done no transmit yet .

masterfreq is the SAME value you put into your #use delay() setup.

I put the defines and a prototype header there for the SECOND UART port but am too lazy this evening to finish it off.

Very Happy Idea
dyeatman



Joined: 06 Sep 2003
Posts: 1933
Location: Norman, OK

View user's profile Send private message

PostPosted: Sun Mar 04, 2012 8:03 pm     Reply with quote

Using version 4.114 I just finished two projects that use both UARTS
on the 18F46K22 and had no problems running standard baud rates
from 9600 up to 115K. Mine are A4 revs from Mouser..
_________________
Google and Forum Search are some of your best tools!!!!
gaugeguy



Joined: 05 Apr 2011
Posts: 303

View user's profile Send private message

Thanks
PostPosted: Tue Mar 06, 2012 8:03 am     Reply with quote

I had figured that I would need to set the registers directly and I do have everything working correctly with that. I was hoping there was a simple way to use the built in functions. This is a nice chip and costs less but I have A2 rev chips I am using for development and testing.
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Tue Mar 06, 2012 8:32 am     Reply with quote

As a quick saving, why not take advantage of #word....
Code:

//  void Set_baudfix( int1 uartnum, unsigned int32 masterfreq, unsigned int32 baudrate){
void Set_baudfix( unsigned int32 masterfreq, unsigned int32 baudrate, int1 uart){
    //uart = 0/1 for UART 1/2
    unsigned int16 baudiv;
// UART 1
#word SPBRG =0xFAF
#byte TXSTA =0xFAC
#byte BAUDCON=0xFB8
#BIT  BRG16 =0xFB8.3

// UART 2
#word SPBRG2 =0xF75
#byte TXSTA2 =0xF72
#byte BAUDCON2=0xF70
#BIT  BRG16_2 =0xF70.3

    bauddiv= (unsigned int16) (( masterfreq / (4*baudrate))-1);
    if (uart) {
        BRG16_2=1;
        SPBRG2=bauddiv;
        txsta2=0xa6;
    }
    else {
       BRG16=1;
       SPBRG =bauddiv;
       txsta=0xA6;  // std 8 bit see txsta bit mapping and BRGH=1
   }
}

Modified to handle both UART's (0/1 for final variable).
No point in using int8 registers when the compiler can treat it as an int16.
You could generate a 'smaller' visually routine, by just using the UART address, and offsets, but the actual code would be larger and slower.

Best Wishes
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