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]<mailto:[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/GVXP195MB1637937903C9474BC32CBD8FE6289%40GVXP195MB1637.EURP195.PROD.OUTLOOK.COM.

Reply via email to