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 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/5d0d8e28-8738-4449-a2f0-270cae592709n%40googlegroups.com.

Reply via email to