Can not ger 1200 baud to work

Coding and general discussion relating to the compiler

Moderators: David Barker, Jerry Messina

Post Reply
garryp4
Posts: 126
Joined: Mon May 21, 2007 7:18 am
Location: Loveland, CO USA

Can not ger 1200 baud to work

Post by garryp4 » Fri Dec 27, 2013 7:52 pm

I need to send and receive at 1200 baud on an 18F47J13. The data sheet (page 352) shows the best option at fosc=8.000mhz is for BRGH = 1, BRG_16 = 1, SYNC = 0, SPBRG = 1665d or SPBRGH = $06 and SPBRG = $81. However, when I look at the signal on the scope it is not even close to 1200 baud.

I have put #option USART2_BRGH = true and #option USART2_BRGH16 = true but when I print out USART2_BRGH16 it shows a 0.

Here is the code:

Code: Select all

Device = 18F47J13
Clock  = 8

#option USART2_BRGH = true
#option USART2_BRGH16 = true

Config IOL1WAY = OFF

// import modules...
Include "USART.bas"
Include "USART2_RP.bas"                ' Mapable pins on port D
Include "convert.bas"
Include "system.bas"
Include "PPS.bas"

Private Dim
  green        As PORTB.6,
  red          As PORTB.7

Private Dim
  b1           As Byte
      
'****************************************************************************
Private Sub LED()
  High(green)
  DelayMS(100)
  Low(green)
  High(red)
  DelayMS(100)
  Low(red)
End Sub
'****************************************************************************
Private Sub SET_SERIAL_2()
  pps.unlock()
  pps.assign_input(@IN_FN_PPS_RX2, PPS_RP19)   ' RD.2
  pps.assign_output(OUT_FN_PPS_TX2, PPS_RP20)  ' RD.3
  pps.lock()
    
'  TXSTA2.4 = 0                         ' Asynchronous
'  TXSTA2.2 = 1                         ' BRGH = high speed
'  BAUDCON2.3 = 1                       ' 16-Bit Baud Rate Register Enable
  BAUDCON2.5 = 1                       ' RCV  1=inverted
  BAUDCON2.4 = 1                       ' TX  1=inverted
'  SPBRGH = $06                         ' 1200 baud - data sheet page 352   DECIMAL 1665
'  SPBRG = $81

  USART2.SetBaudrate(br1200)           ' Baud rate
  DelayMS(2)
  
End Sub
'****************************************************************************

OSCCON  = $7F                          ' Interanl clock to 8mhz
OSCCON2 = $54
REFOCON = $00
OSCTUNE = $00                           
ADCON0  = $00                          ' Turn off A/D
ADCON1  = $FF                          ' All A/D channels digital
ANCON0  = $FF
ANCON1  = $1F
PMCONH  = $00                          ' Disable parallel port

SET_SERIAL_2
USART.SetBaudrate(br9600)              ' Baud rate
LED
      
b1 = BRGH      ' TXSTA2.2
USART.Write("BRGH = ",DecToStr(b1),10,13)
DelayMS(1)

b1 = BAUDCON2.3
USART.Write("BRGH_16 = ",DecToStr(b1),10,13)
DelayMS(1)

b1 = SPBRGH2
USART.Write("SPBRGH2 = ",DecToStr(b1),10,13)
DelayMS(1)

b1 = SPBRG2
USART.Write("SPBRG2 = ",DecToStr(b1),10,13)
DelayMS(1)

'****************************************************************************
MAIN:

  USART2.Write("8M!")
  LED
  
  DelayMS(2000)
  
  GoTo main
And I had to change two lines in USART2.BAS to allow for the mappable pins:

Code: Select all

   RCInput As TRISD.Booleans(2),   //    as TRISG (2)  *** CHANGED TO TRISD FROM TRISG
   TXInput As TRISD.Booleans(3)    //    as TRISG (1)  *** CHANGED TO TRISD FROM TRISG
Here is what prints out to the term emulator:
BRGH = 1
BRGH_16 = 0
SPBRGH2 = 0
SPBRG2 = 159

I can not understand why BRGH_16 = 0

Any help is greatly appreciated.

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Re: Can not ger 1200 baud to work

Post by Jerry Messina » Fri Dec 27, 2013 9:59 pm

I don't know about the rest of it, but if you're using the 16-bit BRG see this post http://sfcompiler.co.uk/phpBB3/viewtopic.php?f=4&t=944 for a required change to SetBaudrate() for some chips, including the J13.

The change works for all devices, and the same thing applies to USART2 and SPBRG(H)2

garryp4
Posts: 126
Joined: Mon May 21, 2007 7:18 am
Location: Loveland, CO USA

Re: Can not ger 1200 baud to work

Post by garryp4 » Sat Dec 28, 2013 12:25 am

Jerry:

Thanks for the reply. This is the change.

Code: Select all

****************************************************************************
* Name    : SetBaudrate                                                    *
* Purpose : Sets the hardware USART baudrate                               *
*         : Pass SPBRG constant, as defined above. For example, br115200   *
****************************************************************************
}
Public Sub SetBaudrate(pSPBRG As Word = br1200)
   SPBRG = pSPBRG.byte0
   SPBRGH = pSPBRG.byte1
   RCStatus = $90         // serial port enable, continuous receive
   RCInput = true         // receive pin is input
   TXInput = false        // transmit pin is output
   TXStatus = USART_MODE  // high or low speed
   #if USART2_BRG16
   BRG16 = 1
   #endif
End Sub
Now I get this sent to hterm:
BRGH = 1
BRGH_16 = 0
SPBRGH2 = 0
SPBRG2 = 0

Shouldn't

Code: Select all

Device = 18F47J13
Clock  = 8

#option USART2_BRGH = true
#option USART2_BRGH16 = true
make BRGH_16 = 1?

According to the data sheet on page 351, if I set SYNC = 0, BRGH = 0, BRG16 = 0, and SPBRG = 103 I can use 1200 baud with 8mhz fosc. When I read the register back I get 159 and the signal on the scope is still too slow a frequency. How can I force a value into SPBRG? I wanted to use the settings from page 351 with SYNC = 0, BRGH = 1, BRG16 = 1 and SPBRG=1665 as it has a lower % error, but right now will take anything that works.

Thanks

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Re: Can not ger 1200 baud to work

Post by Jerry Messina » Sat Dec 28, 2013 2:20 pm

There's a number of things going on here...
Shouldn't

Code: Select all

Device = 18F47J13
Clock  = 8

#option USART2_BRGH = true
#option USART2_BRGH16 = true
make BRGH_16 = 1?
First off, pay close attention to the #options. They should be

Code: Select all

#option USART2_BRGH = true
#option USART2_BRG16 = true
Second, just to reiterate, the fix for the SetBaudrate() routines need to be different for USART.bas and USART2.bas.
USART.BAS:

Code: Select all

Public Sub SetBaudrate(pSPBRG As Word = br1200)
   SPBRG = pSPBRG.byte0
   SPBRGH = pSPBRG.byte1

   RCStatus = $90         // serial Port Enable, continuous receive
   RCInput = True         // receive pin Is Input
   TXInput = False        // transmit pin Is Output
   TXStatus = USART_MODE  // High Or Low speed
   #if USART_BRG16
   BRG16 = 1
   #endif
End Sub
USART2.BAS:

Code: Select all

Public Sub SetBaudrate(pSPBRG As Word = br1200)
   SPBRG2 = pSPBRG.byte0
   SPBRGH2 = pSPBRG.byte1

   RCStatus = $90         // serial port enable, continuous receive
   RCInput = true         // receive pin is input
   TXInput = false        // transmit pin is output
   TXStatus = USART_MODE  // high or low speed
   #if USART2_BRG16
   BRG16 = 1
   #endif
End Sub
Note: the files have a definition for a 16-bit BRG register, but you can't use that as it doesn't work for all devices
since they split the location of the highbyte/lowbyte registers in the memory map

Code: Select all

   #if USART_BRG16
   SPBRGRegister As SPBRG.AsWord,		// doesn't work for all devices
Now the real subtle one. You're including both USART.BAS and USART2.BAS. They each have a table of
public consts for the baudrates depending on the module #options. These are the 'br1200', 'br9600' values.

Since you have the options set differently for each of the usarts, these values end up being different
in each of the modules, and the const value from one module won't work with the other module.

You need to specify WHICH 'const' to use so the compiler will know which one you're talking about. Otherwise,
it'll choose one for you (and possibly get the "wrong" one). To do this, use the module name to qualify the const

Code: Select all

usart.SetBaudrate(usart.br9600)
usart2.SetBaudrate(usart2.br1200)
See if that helps (along with your other changes for the J13 pin definitions)

garryp4
Posts: 126
Joined: Mon May 21, 2007 7:18 am
Location: Loveland, CO USA

Re: Can not ger 1200 baud to work

Post by garryp4 » Mon Dec 30, 2013 10:12 pm

Jerry:

Again, thanks so much for the help. I see on this forum that you seem to help out everyone and wish there was some way to thank you other than just saying thanks.

I did get it working. Turns out there is a type on the help file. It states:
#option USART_BRGH16

Links in code to support 16 bit baud rate generator. You should read the device datasheet to ensure that BRGH is supported. For USART2, the option is USART2_BRGH16. By default, this option is set to false.
But as you pointed out it should be USART_BRG16 (no H). It compiled fine but just did not work.

Also, the SetBaudrate sub did not seem to put any values into the SPBRGH2 and SPBRG2 registers so I just hard coded values from the data sheet into them.

Again, thanks for the help!

Post Reply