Welcome, Guest
Username: Password: Secret Key Remember me
  • Page:
  • 1
  • 2

TOPIC: 18f46j50 usart2 help

18f46j50 usart2 help 4 years 10 months ago #16929

  • kamlaa
  • kamlaa's Avatar
  • Offline
  • Fresh Boarder
  • Posts: 5
i am trying to use usart2 on 18f46j50 but unable to get it work. I am able to receive data through interrupt but when I try to transmit nothing is sent. I have also remapped the pins using the following code:

PPSCON = 0
RPINR16 = 23
RPOR24 = 5
PPSCON = 1

to transmit data I am using USART2.Write("data",13,10)
I have also modified usart2 library:
Module USART2

Include "system.bas"

// calculate clock...
Const FOSC = _clock * 1000000

// low speed or high speed (BRGH)...
#if IsOption(USART2_BRGH) And Not (USART2_BRGH in (true, false))
   #error USART2_BRGH, "Invalid option. BRGH must be TRUE or FALSE."
#endif
#option USART2_BRGH = true   
#if USART2_BRGH = true   
Const USART_MODE = $24
#else
Const USART_MODE = $20
#endif   

// 8 bit or 16 bit (BRG16 only supported with EUSART modules)...
#if IsOption(USART2_BRG16) And Not (USART2_BRG16 in (true, false))
   #error USART2_BRG16, "Invalid option. BRG16 must be TRUE or FALSE."
#endif
#option USART2_BRG16 = false
#if Not USART2_BRG16 And Not USART2_BRGH     // BRG16 = 0, BRGH = 0
Const FMULT = 64
#elseif USART2_BRG16 And Not USART2_BRGH     // BRG16 = 1, BRGH = 0
Const FMULT = 16
#elseif Not USART2_BRG16 And USART2_BRGH     // BRG16 = 0, BRGH = 1
Const FMULT = 16
#else                                      // BRG16 = 1, BRGH = 1
Const FMULT = 4
#endif  

// map registers to USART(x)
#if _usart < 2
   #error _device + " does not support second USART"
  
// MCU has more than one USART...
#else 
Public Dim                         // -> USART2
   #if USART2_BRG16
   SPBRGRegister As SPBRG2.AsWord,
   BRG16 As BAUDCON2.3,
   #else
   SPBRGRegister As SPBRG2,
   #endif
   RCRegister As RCREG2,           //    as RCREG2
   TXRegister As TXREG2,           //    as TXREG2
   RCStatus As RCSTA2,             //    as TXSTA2
   TXStatus As TXSTA2,             //    as TXSTA2
   RCInput As TRISD.Booleans(6),   //    as TRISG (2)
   TXInput As TRISD.Booleans(7)    //    as TRISG (1)
#endif
can anyone help me please.

18f46j50 usart2 help 4 years 10 months ago #16930

  • jmessina
  • jmessina's Avatar
  • Offline
  • Senior Boarder
  • Posts: 44
  • Thanks received: 189
The J50 family has a few twists that make it different from some of the other devices.

The PPS remapping code
PPSCON = 0
RPINR16 = 23	// UART2 RXD assigned to pin PORTD.6
RPOR24 = 5	// UART2 TXD assigned to pin PORTD.7
PPSCON = 1

Won't work as shown. To set or clear the PPSCON.IOLOCK, a specific command sequence must be executed:
1. Write 55h to EECON2<7:0>.
2. Write AAh to EECON2<7:0>.
3. Clear (or set) IOLOCK as a single operation.

IOLOCK is 0 by default, so unless you've set it somewhere you shouldn't even need to mess with it.

Are you using the full Swordfish version or the free SwordfishSE? The reason I ask is that the free version only allows a single bank of ram, and the J50 needs a trick to allow access to the PPS registers since they're located outside the access bank.


The UART libraries need a little modification. For some chips (like the J50 series) the BRGH/BRGL registers aren't contiguous,
so the definitions and SetBaudrate() need to change to accomodate this.
Module USART2

Include "system.bas"

// calculate clock...
Const FOSC = _clock * 1000000

// low speed or high speed (BRGH)...
#if IsOption(USART2_BRGH) And Not (USART2_BRGH in (true, false))
   #error USART2_BRGH, "Invalid option. BRGH must be TRUE or FALSE."
#endif
#option USART2_BRGH = true   
#if USART2_BRGH = true   
Const USART_MODE = $24
#else
Const USART_MODE = $20
#endif   

// 8 bit or 16 bit (BRG16 only supported with EUSART modules)...
#if IsOption(USART2_BRG16) And Not (USART2_BRG16 in (true, false))
   #error USART2_BRG16, "Invalid option. BRG16 must be TRUE or FALSE."
#endif
#option USART2_BRG16 = false
#if Not USART2_BRG16 And Not USART2_BRGH     // BRG16 = 0, BRGH = 0
Const FMULT = 64
#elseif USART2_BRG16 And Not USART2_BRGH     // BRG16 = 1, BRGH = 0
Const FMULT = 16
#elseif Not USART2_BRG16 And USART2_BRGH     // BRG16 = 0, BRGH = 1
Const FMULT = 16
#else                                      // BRG16 = 1, BRGH = 1
Const FMULT = 4
#endif  

// map registers to USART(x)
#if _usart < 2
   #error _device + " does not support second USART"
  
// MCU has more than one USART...
#else 
Public Dim                         // -> USART2
   SPBRG_LO as SPBRG2,  	// <<**** MOD for non-contiguous BRG regs
   SPBRG_HI as SPBRGH2,  	// <<**** MOD for non-contiguous BRG regs
   #if USART2_BRG16
   BRG16 As BAUDCON2.3,
   #endif
   RCRegister As RCREG2,           //    as RCREG2
   TXRegister As TXREG2,           //    as TXREG2
   RCStatus As RCSTA2,             //    as TXSTA2
   TXStatus As TXSTA2,             //    as TXSTA2
   RCInput As TRISD.Booleans(6),   //    as TRISG (2)
   TXInput As TRISD.Booleans(7)    //    as TRISG (1)
#endif


{
****************************************************************************
* Name    : SetBaudrate                                                    *
* Purpose : Sets the hardware USART baudrate                               *
*         : Pass SPBRG constant, as defined above. For example, br115200   *
// <<****** MODIFIED for non-contiguous BRG registers 
****************************************************************************
}
Public Sub SetBaudrate(pSPBRG As word = br19200)

   SPBRG_LO = pSPBRG.byte0  // <<****** MOD
   SPBRG_HI = pSPBRG.byte1  // <<****** MOD

   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

There may be more needed, but see it that helps.

Jerry

18f46j50 usart2 help 4 years 10 months ago #16931

  • kamlaa
  • kamlaa's Avatar
  • Offline
  • Fresh Boarder
  • Posts: 5
Hi Jerry,
Thank you for your reply. I did the changes as advised by you but still pic is not sending anything. I am using full version.
for PPS remapping I did the following:
EECON2 = $55
EECON2 = $AA
PPSCON.0 = 0
RPINR16  = 23
RPOR24    = 5
EECON2 = $55
EECON2 = $AA
PPSCON.0 = 1
as advised I have also modified usart module as below:
Module USART2

Include "system.bas"

// calculate clock...
Const FOSC = _clock * 1000000

// low speed or high speed (BRGH)...
#if IsOption(USART2_BRGH) And Not (USART2_BRGH in (true, false))
   #error USART2_BRGH, "Invalid option. BRGH must be TRUE or FALSE."
#endif
#option USART2_BRGH = true   
#if USART2_BRGH = true   
Const USART_MODE = $24
#else
Const USART_MODE = $20
#endif   

// 8 bit or 16 bit (BRG16 only supported with EUSART modules)...
#if IsOption(USART2_BRG16) And Not (USART2_BRG16 in (true, false))
   #error USART2_BRG16, "Invalid option. BRG16 must be TRUE or FALSE."
#endif
#option USART2_BRG16 = false
#if Not USART2_BRG16 And Not USART2_BRGH     // BRG16 = 0, BRGH = 0
Const FMULT = 64
#elseif USART2_BRG16 And Not USART2_BRGH     // BRG16 = 1, BRGH = 0
Const FMULT = 16
#elseif Not USART2_BRG16 And USART2_BRGH     // BRG16 = 0, BRGH = 1
Const FMULT = 16
#else                                      // BRG16 = 1, BRGH = 1
Const FMULT = 4
#endif  

// map registers to USART(x)
#if _usart < 2
   #error _device + " does not support second USART"
  
// MCU has more than one USART...
#else 
Public Dim                         // -> USART2
   SPBRG_LO As SPBRG2,  	// <<**** MOD for non-contiguous BRG regs
   SPBRG_HI As SPBRGH2,  	// <<**** MOD for non-contiguous BRG regs
   #if USART2_BRG16
   BRG16 As BAUDCON2.3,
   #endif

   {#if USART2_BRG16
   SPBRGRegister As SPBRG2.AsWord,
   BRG16 As BAUDCON2.3,
   #else
   SPBRGRegister As SPBRG2,
   #endif}

   RCRegister As RCREG2,           //    as RCREG2
   TXRegister As TXREG2,           //    as TXREG2
   RCStatus As RCSTA2,             //    as TXSTA2
   TXStatus As TXSTA2,             //    as TXSTA2
   RCInput As TRISD.Booleans(6),//TRISD.Booleans(2),   //    as TRISG (2)
   TXInput As TRISD.Booleans(7)//TRISD.Booleans(1),    //    as TRISG (1)
#endif
 
Dim                                // -> USART2
   PIR As PIR3,                    //    as PIR3 
   PIE As PIE3,                    //    as PIE3
   IPR As IPR3                     //    as IPR3

// public baudrate constants...
#if USART2_BRG16
Public Const
   br300 As Word   = FOSC / (FMULT * (300 + 1)) - 1 + 0.5,
   br600 As Word   = FOSC / (FMULT * (600 + 1)) - 1 + 0.5,
   br1200 As Word  = FOSC / (FMULT * (1200 + 1)) - 1 + 0.5,
   br2400 As Word  = FOSC / (FMULT * (2400 + 1)) - 1 + 0.5,
   br4800 As Word  = FOSC / (FMULT * (4800 + 1)) - 1 + 0.5,
   br9600 As Word  = FOSC / (FMULT * (9600 + 1)) - 1 + 0.5,
   br19200 As Word = FOSC / (FMULT * (19200 + 1)) - 1 + 0.5,
   br38400 As Word = FOSC / (FMULT * (38400 + 1)) - 1 + 0.5,
   br57600 As Word = FOSC / (FMULT * (57600 + 1)) - 1 + 0.5,
   br115200 As Word = FOSC / (FMULT * (115200 + 1)) - 1 + 0.5
#else
Public Const
   br300 As Byte   = FOSC / (FMULT * (300 + 1)) - 1 + 0.5,
   br600 As Byte   = FOSC / (FMULT * (600 + 1)) - 1 + 0.5,
   br1200 As Byte  = FOSC / (FMULT * (1200 + 1)) - 1 + 0.5,
   br2400 As Byte  = FOSC / (FMULT * (2400 + 1)) - 1 + 0.5,
   br4800 As Byte  = FOSC / (FMULT * (4800 + 1)) - 1 + 0.5,
   br9600 As Byte  = FOSC / (FMULT * (9600 + 1)) - 1 + 0.5,
   br19200 As Byte = FOSC / (FMULT * (19200 + 1)) - 1 + 0.5,
   br38400 As Byte = FOSC / (FMULT * (38400 + 1)) - 1 + 0.5,
   br57600 As Byte = FOSC / (FMULT * (57600 + 1)) - 1 + 0.5,
   br115200 As Byte = FOSC / (FMULT * (115200 + 1)) - 1 + 0.5
#endif
  
// alias public bitnames to TXSTA(x)...
Public Dim
   CSRC As TXStatus.7,
   TX9 As TXStatus.6,
   TXEN As TXStatus.5,
   SYNC As TXStatus.4,
   BRGH As TXStatus.2,
   TRMT As TXStatus.1,
   TX9D As TXStatus.0

// alias public bitnames to RCSTA(x)...
Public Dim
   SPEN As RCStatus.7,
   RX9 As RCStatus.6,
   SREN As RCStatus.5,
   CREN As RCStatus.4,
   ADDEN As RCStatus.3,
   FERR As RCStatus.2,
   OERR As RCStatus.1,
   RX9D As RCStatus.0
   
// alias public interrupt flags...
Public Dim
   RCIF As PIR.5,  // receive buffer full 
   TXIF As PIR.4,  // transmit buffer empty 
   RCIE As PIE.5,  // receive interrupt enable
   TXIE As PIE.4,  // transmit interrupt enable
   RCIP As IPR.5,  // receive interrupt priority
   TXIP As IPR.4   // transmit interrupt priority
   
// public boolean flags...
Public Dim  
   DataAvailable As PIR.Booleans(5),         // RCIF
   ReadyToSend As PIR.Booleans(4),           // TXIF
   ContinousReceive As RCStatus.Booleans(4), // CREN
   Overrun As RCStatus.Booleans(1),          // OERR
   FrameError As RCStatus.Booleans(2),       // FERR
   RCIEnable As PIE.Booleans(5),             // RCIE
   TXIEnable As PIE.Booleans(4),             // TXIE
   RCIPHigh As IPR.Booleans(5),              // RCIP
   TXIPHigh As IPR.Booleans(4)               // TXIP

Public Dim
   ReadTerminator As Char                    // read string terminator
{
****************************************************************************
* Name    : SetBaudrate                                                    *
* Purpose : Sets the hardware USART baudrate                               *
*         : Pass SPBRG constant, as defined above. For example, br115200   *
****************************************************************************
}
'Public Sub SetBaudrate(pSPBRG As SPBRGRegister = br19200)
Public Sub SetBaudrate(pSPBRG As Word = br19200)
   SPBRG_LO = pSPBRG.byte0  // <<****** MOD
   SPBRG_HI = pSPBRG.byte1  // <<****** MOD
   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

please advice what I am doing wrong.

18f46j50 usart2 help 4 years 10 months ago #16932

  • jmessina
  • jmessina's Avatar
  • Offline
  • Senior Boarder
  • Posts: 44
  • Thanks received: 189
I don't recall needing anything else.

Make sure IOL1WAY is off, otherwise you can only set the PPS once.
add
config IOL1WAY = OFF
to your main .bas file

How are you testing this? Can you check pin PORTD.7 with a scope/logic analyzer?

It sounds like you have everything setup properly. Could you post a short example using USART2?

18f46j50 usart2 help 4 years 10 months ago #16933

  • kamlaa
  • kamlaa's Avatar
  • Offline
  • Fresh Boarder
  • Posts: 5
Thank You for your help. Please see my test code below, i do not have access to oscilloscope :(
I am communicating with gsm module, when module is switched on it itself sends few messages like network status, etc that I can receive but when i send any command to modem it doesn't respond. I have checked rx and tx pins continuity as well as short from any neighboring pins. All connections are good.
Device = 18F46J50
Clock = 48
Config OSC = HSPLL
Config PLLDIV = 5, 'PLL division
       CPUDIV = OSC1,                     ' 48MHz cpu clock
       FCMEN = OFF,
       IESO = OFF,
       WDTEN = ON,   //watch dog timer on
       WDTPS = 32768,
       STVREN = ON,
       XINST = OFF, 
       IOL1WAY = OFF
       
#option RX2_BUFFER_SIZE = 255
#option RX2_PRIORITY = ipHigh

#option USB_SERVICE = False 
#option USB_AUTO_INITIALIZE = false
#option USB_BUS_POWER = 250
#option HID_EP_OUT_POLLING_MS = 10
#option USB_VID = $0F6E                          // VID - 6017 is Mecanique 
#option USB_PID = $0786                          // PID - 2000

'#option USART2_BRGH = false         
                          
Include "usbhid.bas"                          
Include "usart2_rp.bas"
Include "ISRRX2-modbb.bas"   
Include "Convert.bas"    

Dim LED1 As PORTA.5
Dim LED2 As PORTE.0
Dim LED3 As PORTE.1
Dim GSMControl As PORTA.3
Dim GSMStat As PORTA.2
Dim GSMReset As PORTB.1 
Dim Temp As Byte
Dim index As Byte

// TX report...
Structure TTXReport
   Message As String
End Structure

// RX report...
Structure TRXReport
   Message As String
End Structure 

Dim TXReport As TTXReport Absolute TXReportRAM,
    RXReport As TRXReport Absolute RXReportRAM    

Event OnData2()
   
End Event             

Sub SwitchOnProc()
    If GSMStat = 1 Then
        High(GSMReset)
        DelayMS(200)
        Low(GSMReset)
    EndIf
    While GSMStat = 0
        High(GSMControl)
    Wend
    Low(GSMControl)
End Sub
//======================

Sub SwitchOfProc()
    If GSMStat = 1 Then
        High(GSMControl)
        DelayMS(700)
        Low(GSMControl)
    EndIf
End Sub

index = 0

ISRRX2.Initialize(OnData2)

{
PPSCON   = 0  ' IOLOCK DISABLE
RPINR16  = 23 ' HSERIN2 remap RX2(RPINR16) to RP12(RC1)
RPOR24    = 5  ' HSEROUT2 remap TX2(05) to RP13(RC2) 
'RPINR1 = 1 'for adxl  
PPSCON   = 1  ' IOLOCK ENABLE
}

EECON2 = $55
EECON2 = $AA
PPSCON.0 = 0
RPINR16  = 23
RPOR24    = 5
EECON2 = $55
EECON2 = $AA
PPSCON.0 = 1
           
OSCTUNE.6 = 1
USART2.SetBaudrate(br19200)
Clear(HID.Buffer)
INTCON.7 = 0
OSCCON.7 = 1
ADCON1 = $07
ANCON0 = $FF                 
ANCON1 = $FF   

Low(GSMControl)
DelayMS(1000)                                       

If GSMStat = 0 Then
    SwitchOnProc()
EndIf

While true
    HID.Service
    
    ASM  //clear wdt 
        ClrWDT
    End ASM
    
    If ISRRX2.BufferOverrun Or ISRRX2.Overrun Then
	  ISRRX2.Reset
    EndIf
    
       While ISRRX2.DataAvailable
        HID.Service
        Temp = ISRRX2.ReadByte
        TXReport.Message(index) = Char(Temp)
        Inc(index)
        If Temp = Byte(Char(13)) Or index > 62 Then
            index = 0
            WriteReport
            Clear(HID.Buffer)
        EndIf
       Wend
    
    If DataAvailable Then
        ReadReport
        If RXReport.Message(0) = Char(48) Then
            HID.Service
            SwitchOfProc()
            TXReport.Message = "off" + Char(13) + Char(10)
            WriteReport
        Else
            USART2.Write(RXReport.Message,13,10)
        EndIf
        Clear(HID.Buffer)
   EndIf
    
Wend

18f46j50 usart2 help 4 years 10 months ago #16934

  • jmessina
  • jmessina's Avatar
  • Offline
  • Senior Boarder
  • Posts: 44
  • Thanks received: 189
If you don't have access to any debugging tools, I'd suggest trying something simple first to prove that you can send and receive using the UART.

Remove the GSM and all the USB code. Connect the pic TXD pin to its RXD pin so you can loopback messages to yourself using the UART alone.
Since you're using an interrupt-driven receiver, you should be able to TX characters out the uart and receive them.

Actually, as long as you just send/receive individual characters one at a time you can do this without interrupts too.
Last Edit: 4 years 10 months ago by jmessina.
  • Page:
  • 1
  • 2
Time to create page: 0.251 seconds