Hi Vasile, I will use a 18.432 Mhz crystal, found in my junkbox.. On Saturday, October 22, 2022 at 5:27:11 PM UTC+2 vasile wrote:
> 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/b179035a-8ea8-45d7-a701-653dad076a3fn%40googlegroups.com.
