Bill, one good workaround for zero error baudrate is to use zero error
usart crystals You will always have zero error baud rate. 7.3728MHz,
14.7456MHz etc.

On Sat 22 Oct 2022, 5:14 PM Bill Beek <[email protected] wrote:

> Hi Rob,
> I applied the function unchanged to 3 types: 16F876A, 18F2520 and
> 18F25K22.
> On the first 2 the function worked fine. So very useful for me.
> The function is used as a library "usart_dynamic" with the following 2
> lines added:
>  if (defined(usart_hw_serial) == FALSE) then
> const bit usart_hw_serial = TRUE   ; default is async mode (not sync)
> end if
> In the library "serial_hardware" I have changed the call to the correct
> library and the new function.
> I have change the name of this lib of coarse. It worked right away.
> The 18F25K22 does not want to generate the correct Baud rate, the relevant
> registers do have the correct values.
> I will look with the oscilloscope to see what kind of Baud rate is really
> generated.
>
> Thanks again for your help,
> Kind regards Bill.
>
> On Friday, October 21, 2022 at 7:23:33 PM UTC+2 [email protected] wrote:
>
>> Hi Bill,
>>
>> Thanks and good to hear that you might becomd a fan of JAL.
>>
>> I saw that your PIC had an 8-bit baudrate generator so you would only
>> need this part of the code:
>>
>>          -- use classic (8 bit) baudrate register
>>          -- <SPBRG> = ( Fosc / ( 4 * Baudrate ) ) -1
>>          -- first try high baudrate, will generate highest accuarcy
>>          -- to get the right rounding (5 + 10*f(x)) /10
>>          usart_calculation =((5 + ((10 * clock) / (16 * baudrate))) / 10)
>> - 1
>>          usart_div = word(usart_calculation)
>>          -- special case if divider is 0, test if deviation is not too
>> much
>>          if usart_div == 0 then
>>             if (100 * (baudrate - (clock / 16))) / baudrate >=
>> max_deviation then
>>                -- Asynchronous baudrate is too high
>>                succes = FALSE
>>             end if
>>          end if
>>          -- if divider small enough calculate divider and set high-speed
>>          real_baud = clock / 16 / (usart_div + 1)
>>          if usart_div <= 255 then
>>             if (real_baud > baudrate) then
>>                if (100 * (real_baud - baudrate) / baudrate >=
>> max_deviation) then
>>                   -- Asynchronous baudrate deviation is too large
>>                   succes = FALSE
>>                end if
>>             else
>>                if (100 * (baudrate - real_baud) / baudrate >=
>> max_deviation) then
>>                   -- Asynchronous baudrate deviation is too large
>>                   succes = FALSE
>>                end if
>>             end if
>>             SPBRGL = byte(usart_div)
>>             TXSTA_BRGH = TRUE
>>             -- try the low-speed mode
>>          else
>>             usart_div_low = ((((10 * clock) / (64 * baudrate)) + 5) / 10)
>> - 1
>>             -- here divider will never be 0
>>             -- but special case to consider,
>>             -- if baudrate is just a little too low
>>             if (usart_div_low > 255) & (100 * ((clock / (64 * 256 )) -
>> baudrate)) /
>>                   baudrate < max_deviation then
>>                SPBRGL = 255
>>                TXSTA_BRGH = FALSE
>>                -- now calculate divider and set high-speed / low-speed
>> bit
>>             elsif usart_div_low <= 255 then
>>                SPBRGL = byte(usart_div_low)
>>                TXSTA_BRGH = FALSE
>>             else
>>                -- Asynchronous baudrate is too low
>>                succes = FALSE
>>             end if
>>          end if
>>       end if
>>
>> Good luck testing.
>>
>> Kind regards,
>>
>> Rob
>>
>> ------------------------------
>> *Van:* [email protected] <[email protected]> namens Bill
>> Beek <[email protected]>
>> *Verzonden:* donderdag 20 oktober 2022 19:15
>>
>> *Aan:* jallib <[email protected]>
>> *Onderwerp:* Re: [jallib] Baudrate control
>> Hi Rob,
>> I am going to try out the function you have sent, I see that it is
>> suitable for various PIC's and also test whetherthe chosen X-tal frequency
>> is good enough for the desired baudates. I myself use an 18.432 MHz x-tal
>> that I still found in my junkbox. in that casemy code can
>> be more simple because of the very small spread, but obviously not for
>> general use.
>>  I'll let you know if it worked out. B.T.W. this is very instructive for
>> me. and I'm going to appreciate JAL more and more.
>> Thank you for your effort,
>> Kind regards Bill.
>>
>> On Tuesday, October 18, 2022 at 7:23:04 PM UTC+2 [email protected]
>> wrote:
>>
>> Hi Bill,
>>
>> I understand what you try to do but it does not work because the hardware
>> baudrate setting is calculated at compile time not at runtime.
>>
>> In the library usart_common.jal you find the procedure that calculates
>> the baudrate settings.
>>
>> I once changed this code to be dynamic and created the following code but
>> I do not remember if I ever tested it (it compiled as far as I know 🙂).
>>
>> I did not use it because it is a lot of code for only calculating and
>> setting the baudrate. That's why I suggested the other code.
>>
>> You could leave out the part which calculates it for synchronous mode and
>> based on the PIC you are using you could leave out the 8-bit or 16-bit
>> baudrate generator since your PIC has only one of them. In that case the
>> code size is much smaller.
>>
>> You could give it a try and if it works let me know.
>>
>> Kind regards,
>>
>> Rob
>>
>>
>> --
>> ------------------------------------------------------------------------------
>> -- Title:     Calculate and set baudrate dynamically for USART 1
>> -- Arguments: baudrate
>> -- Returns:   TRUE when succesful, otherwise FALSE
>> -- Notes:     Uses bit-constant 'usart_hw_serial' to determine mode of
>> operation:
>> --              * TRUE:  Asynchronous communications (default)
>> --              * FALSE: Synchronous communications
>> --
>> ------------------------------------------------------------------------------
>> function _calculate_and_set_baudrate_dynamic(dword in baudrate) return
>> bit is
>>
>>    const max_deviation = 5 -- maximum % deviation of the desired baudrate
>>    var dword usart_calculation, real_baud, usart_div_low,
>> usart_div_sync, clock
>>    var word  usart_div
>>    var bit   succes = TRUE
>>
>>    clock = dword(target_clock)
>>
>>    if (usart_hw_serial == TRUE) then           -- USART in asynchronous
>> mode
>>       if (defined(BAUDCON_BRG16) == TRUE) then -- use 16 bit baudrate
>> register
>>          BAUDCON_BRG16 = TRUE
>>          TXSTA_BRGH = TRUE
>>          usart_calculation = ((5 + ((10 * clock) / (4 * baudrate))) / 10)
>> - 1
>>          usart_div = word(usart_calculation)
>>          real_baud = clock / 4 / ((usart_div & 0xffff) + 1)
>>          if (real_baud > baudrate) then
>>             if (100 * (real_baud - baudrate) / baudrate >=
>> max_deviation) then
>>                -- Asynchronous baudrate deviation is too large
>>                succes = FALSE
>>             end if
>>          else
>>             if (100 * (baudrate - real_baud) / baudrate >=
>> max_deviation) then
>>                -- Asynchronous baudrate deviation is too large
>>                succes = FALSE
>>             end if
>>          end if
>>          SPBRGL = byte(usart_div)                  -- MSB
>>          SPBRGH = byte(usart_div >> 8)             -- LSB
>>       else
>>          -- use classic (8 bit) baudrate register
>>          -- <SPBRG> = ( Fosc / ( 4 * Baudrate ) ) -1
>>          -- first try high baudrate, will generate highest accuarcy
>>          -- to get the right rounding (5 + 10*f(x)) /10
>>          usart_calculation =((5 + ((10 * clock) / (16 * baudrate))) / 10)
>> - 1
>>          usart_div = word(usart_calculation)
>>          -- special case if divider is 0, test if deviation is not too
>> much
>>          if usart_div == 0 then
>>             if (100 * (baudrate - (clock / 16))) / baudrate >=
>> max_deviation then
>>                -- Asynchronous baudrate is too high
>>                succes = FALSE
>>             end if
>>          end if
>>          -- if divider small enough calculate divider and set high-speed
>>          real_baud = clock / 16 / (usart_div + 1)
>>          if usart_div <= 255 then
>>             if (real_baud > baudrate) then
>>                if (100 * (real_baud - baudrate) / baudrate >=
>> max_deviation) then
>>                   -- Asynchronous baudrate deviation is too large
>>                   succes = FALSE
>>                end if
>>             else
>>                if (100 * (baudrate - real_baud) / baudrate >=
>> max_deviation) then
>>                   -- Asynchronous baudrate deviation is too large
>>                   succes = FALSE
>>                end if
>>             end if
>>             SPBRGL = byte(usart_div)
>>             TXSTA_BRGH = TRUE
>>             -- try the low-speed mode
>>          else
>>             usart_div_low = ((((10 * clock) / (64 * baudrate)) + 5) / 10)
>> - 1
>>             -- here divider will never be 0
>>             -- but special case to consider,
>>             -- if baudrate is just a little too low
>>             if (usart_div_low > 255) & (100 * ((clock / (64 * 256 )) -
>> baudrate)) /
>>                   baudrate < max_deviation then
>>                SPBRGL = 255
>>                TXSTA_BRGH = FALSE
>>                -- now calculate divider and set high-speed / low-speed
>> bit
>>             elsif usart_div_low <= 255 then
>>                SPBRGL = byte(usart_div_low)
>>                TXSTA_BRGH = FALSE
>>             else
>>                -- Asynchronous baudrate is too low
>>                succes = FALSE
>>             end if
>>          end if
>>       end if
>>    else -- USART in synchronous mode
>>       usart_div_sync = ( clock / ( 4 * baudrate )) - 1
>>       -- special case if divider is 0 or negative
>>       -- test if baudrate is a little bit too high
>>       if usart_div_sync <= 0 then
>>          if (100 * (baudrate - (clock / 4))) / baudrate >= max_deviation
>> then
>>             -- Synchronous baudrate is too high
>>             succes = FALSE
>>          end if
>>       end if
>>       -- special case to consider, if baudrate is just a little too high
>>       if (usart_div_sync > 255) & (100 * ((clock / (4 * 256)) -
>> baudrate)) /
>>             baudrate < max_deviation then
>>          SPBRGL = 255
>>       elsif (usart_div_sync <= 255) then
>>          SPBRGL = byte(usart_div_sync)
>>       else
>>          -- Synchronous baudrate is too low
>>          succes = FALSE
>>       end if
>>    end if
>>
>>    return succes
>>
>> end function
>>
>>
>>
>>
>> ------------------------------
>> *Van:* [email protected] <[email protected]> namens Bill
>> Beek <[email protected]>
>> *Verzonden:* dinsdag 18 oktober 2022 11:34
>>
>> *Aan:* jallib <[email protected]>
>> *Onderwerp:* Re: [jallib] Baudrate control
>> Hello Rob,
>> Thank you for your cooperation, yesterday I had already seen the code.
>> Now let's figure out how I can fit it into my program.
>> Maybe my question was not entirely clear so I send a piece of the code to
>> show how I imagined it.
>>
>> Kind regards, Bill.
>>
>> MCU = 16F876A  20 MHz The problem here is that var "set" must be a
>> constant.
>> Short vars for testing only.
>>
>> var byte c1,c2,c3
>> var byte  set     -- Baud indicator
>> const serial[8]={1200,2400,4800,9600,19200,38400,57600,115200}
>> ;var dword serial[8]={1200,2400,4800,9600,19200,38400,57600,115200}
>>
>> pin_c1_direction = INPUT
>> pin_c2_direction = INPUT
>> pin_c3_direction = INPUT
>>
>> include serial_hardware
>>
>> if pin_c1 then
>>  c1 = 1
>>   else
>>   c1 = 0
>> end if
>>
>> if pin_c2 then
>>  c2 = 2
>>   else
>>   c2 = 0
>> end if
>>
>> if pin_c3 then
>>  c3 = 4
>>   else
>>   c3 = 0
>> end if
>>
>> set = c1 + c2 + c3 + 1
>>
>> const serial_hw_baudrate = serial[set]
>> ;var dword serial_hw_baudrate = serial[set]
>> serial_hw_init()
>>
>>
>>
>>
>> On Tuesday, October 18, 2022 at 7:14:34 AM UTC+2 [email protected]
>> wrote:
>>
>> Hello Bill,
>>
>> I posted an example but never received it my self so this is a retry.
>>
>> Kind regards,
>>
>> Rob
>>
>>
>> Op maandag 17 oktober 2022 om 19:52:25 UTC+2 schreef [email protected]:
>>
>> Hi Bill,
>>
>> I applied the suggestion of Kiste in one of my programs. Here is a part
>> of that program. This is for a PIC running at 48  MHz target clock.
>>
>> I had to look up a specific baudrate to see if it was valid. If so I set
>> the new baudrate.
>>
>> You see 4 parts (not all needed)
>>
>>    1. Define valid bauddrates.  You could skip this
>>    2. Check if a given baudrate is valid. You could skip this too.
>>    3. The baudrate calculation based on the given baudrate + initialize
>>    the USART. You need this. Note: baudrate calculation is of type dword.
>>    4. The intiallization routine of the USART with the calculation. You
>>    need this.
>>
>>
>> ; List of baudrates supported. See page 262 of the datasheet.
>> ; Formula for baudrate calclation for 8 byte asynchronous mode
>> ; with for sync = FALSE and brg16 = TRUE and brgh = FALSE:
>> ; brg = target_clock/(baudrate * 16) - 1
>> const dword SUPPORTED_BAUDRATES[] = {
>>    110, 300, 600, 1200, 2400, 4800, 9600, 14400,
>>    19200, 28800, 38400, 57600, 115200, 230400
>> }
>>
>> ; Check if the given baudrate is supported and return TRUE if so.
>> function supported_baudrate(dword in baudrate) return bit is
>>
>>    var byte index
>>    var bit found = FALSE
>>
>>    for count(SUPPORTED_BAUDRATES) using index loop
>>       if (SUPPORTED_BAUDRATES[index] == baudrate) then
>>          found = TRUE
>>       end if
>>    end loop
>>
>>    return found
>>
>> end function
>>
>>            baudrate_calculation = (target_clock/(current_baudrate * 16))
>> - 1
>>            usart_init(word(baudrate_calculation))
>>
>> ; Initialize the USART with the given baudrate value. The USART is
>> enabled.
>> procedure usart_init(word in baudrate_value) Is
>>
>>    usart_disable()
>>    ; Use 16 bit baudrate generator and set baudrate
>>    BAUDCON = 0b0000_1000
>>    SPBRG = baudrate_value
>>    ;Initialise transmitter, 8 bits, asynchronous mode, low speed.
>>    TXSTA = 0b0000_0000
>>    ; Initialise receiver and serial port, 8 bits
>>    RCSTA = 0b1000_0000
>>    usart_enable()
>>
>> end procedure
>>
>>
>> Hope this helps.
>>
>> Kind regards,
>>
>> Rob
>> ------------------------------
>> *Van:* [email protected] <[email protected]> namens Bill
>> Beek <[email protected]>
>> *Verzonden:* maandag 17 oktober 2022 19:40
>> *Aan:* jallib <[email protected]>
>> *Onderwerp:* Re: [jallib] Baudrate control
>>
>> Thanks Kiste for your reply. My teacher said more than 50 years ago that
>> poking in memory was not a good way of programming,
>> but I did think that this was also a possibility. If this turns out to be
>> the only possibility,
>>  I'm not sure how to go about it I don't see anything in the
>> documentation about writing directly in the PIC memory
>> except that you can use assembler instructions. Unfortunately I am not
>> well informed about the PIC asm code.
>> A long time ago I programmed various micro processors.
>>  I would like to hear if you want to share a piece of code what i can
>> alter for my needs.
>>
>>  Thanks in advance, Bill.
>>
>>
>> On Monday, October 17, 2022 at 4:47:20 PM UTC+2 Kiste wrote:
>>
>> Hi Bill,
>>
>> I've used different baud rates, but I did not modify the serial libraries
>> for that. I just calculated the register values by hand and poked the
>> different values to the different registers. The baud rate calculation in
>> the libraries is not a thing which is good to be done at runtime. For
>> certain baud rates, the lib will refuse to compile and inform you, that
>> your desired baud rate cannot be set due to a deviation from the desired
>> value which is to large to reliably work. That can't be done at runtime for
>> a start.
>>
>> Greets,
>> Kiste
>>
>> Am Montag, 17. Oktober 2022, 15:39:54 MESZ hat Bill Beek <
>> [email protected]> Folgendes geschrieben:
>>
>>
>> Hello everyone, Is there anyone who has a solution to my problem. I am
>> working on a serial LCD now that I have this working, I want to select the
>> baud rate before running the program. Unfortunately, the "const
>> serial_hw_baudate" do not easily change. In the library "usart_common" I
>> changed all the constants in a variable "var dword" but I keep getting
>> error messages from this lib. Maybe I'm overlooking something, or is there
>> a simple method to set the Baud rate under software control.
>>  Kind regards, Bill
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "jallib" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected].
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/jallib/2b1be8c6-547c-4f0c-97bb-43fc851e4bf4n%40googlegroups.com
>> <https://groups.google.com/d/msgid/jallib/2b1be8c6-547c-4f0c-97bb-43fc851e4bf4n%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "jallib" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [email protected].
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/jallib/81855104-44d2-4941-b199-807927d341dan%40googlegroups.com
>> <https://groups.google.com/d/msgid/jallib/81855104-44d2-4941-b199-807927d341dan%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>> --
>> You received this message because you are subscribed to a topic in the
>> Google Groups "jallib" group.
>> To unsubscribe from this topic, visit
>> https://groups.google.com/d/topic/jallib/vc1s65yXPkQ/unsubscribe.
>> To unsubscribe from this group and all its topics, send an email to
>> [email protected].
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/jallib/8852c568-89d0-4224-95fa-ecd30b6cdc3an%40googlegroups.com
>> <https://groups.google.com/d/msgid/jallib/8852c568-89d0-4224-95fa-ecd30b6cdc3an%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>> --
>> You received this message because you are subscribed to a topic in the
>> Google Groups "jallib" group.
>> To unsubscribe from this topic, visit
>> https://groups.google.com/d/topic/jallib/vc1s65yXPkQ/unsubscribe.
>> To unsubscribe from this group and all its topics, send an email to
>> [email protected].
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/jallib/5d0d8e28-8738-4449-a2f0-270cae592709n%40googlegroups.com
>> <https://groups.google.com/d/msgid/jallib/5d0d8e28-8738-4449-a2f0-270cae592709n%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
> --
> You received this message because you are subscribed to the Google Groups
> "jallib" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/jallib/d50afd69-5b72-4559-b107-3cc12ed76cb3n%40googlegroups.com
> <https://groups.google.com/d/msgid/jallib/d50afd69-5b72-4559-b107-3cc12ed76cb3n%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"jallib" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jallib/CAM%2Bj4qsYVcvgDEC25%3Dax9qNQmUoQcH_GBmmFg9Nj1Z66_U%2B5Qw%40mail.gmail.com.

Reply via email to