Uart1 / Usart Interrupt driven receiver

General discussion on mikroBasic PRO for PIC.
Post Reply
Author
Message
dangerous
Posts: 748
Joined: 08 Mar 2005 16:06
Location: Nottinghamshire, UK

Uart1 / Usart Interrupt driven receiver

#1 Post by dangerous » 19 May 2011 22:05

In this thread: http://www.mikroe.com/app/webroot/forum ... pt#p142340 Dany of http://www.rosseeld.be/DRO/PIC/index.htm
gives a useful UART routine with interrupt driven receiver. It is MikroPascal, so for us peasants with MikroBasic, I have done a little translation and also modified it for a PIC16F877A running on a 12Mhz resonator (on an easyPic4 board if anyone wants to know).
It gives excellent results with the IDE usart tool, even at 2400 baud and a 1mS repeat rate set. Adding a 1000mS delay between the buffer read and Uart1 write command still captures all the buffer data up to the max buffer size set.

First the usage program, just calls the routines from the interrupt.

Code: Select all

program Pascal_Uart
'*******************************************************************************
include "UsartReceiver"
dim i as byte
'Could poll the bit RCIF if not using interrupts.
'In this case, do not set GIE, RCIE_bit {= PIE1.RCIE} or PEIE_bit{= INTCON.PEIE}
'Just poll for RCIF bit set on data rx
'*******************************************************************************
 sub procedure interrupt()
  if RCIF_bit = 1 then
    UsartReceiverInterrupt     'call the interrupt service routine.
  end if                       'The interrupt flag RCIF_bit is cleared within it
end sub
'*******************************************************************************
Main:
  ADCON1 = 0x07
  porta = 0
  trisa = 0xF0
  Trisb = 00
  portb = 0
   Uart1_Init(2400)             ' // Init Usart
   UsartReceiverInit            ' // <--- initialization of the unit
   GIE_bit  = 1                '// enable interrupts (needed by the uart receiver)
    while true
      if UsartCharPresent then 'main receive loop
         i = ReadUsartByte       '... // do something with it...
         Uart1_write (i)
      end if

  wend
end.
Now the module where all the work is done:

Code: Select all

module UsartReceiver
    include "Globals"
'/Based on application by D. Rosseel
'// Original: 17-08-2008
'// Latest update: 26-04-2010
'////AD version 19-05-2011 modifed from  MikroPascal to MikroBasicPro
' History:
' 26-04-2010: used "bits" out of the definitions files instead of the full definition,
'             e.g. "RCIF_bit" in stead of "PIR1.RCIF". No functionality change.
'


' Include file "Globals". The size of the receive buffer is defined there in "const UsartBuffSize = xxx":
'
' This unit receives Usart Data using the Usart hardware, interrupt based.
'
' A Usart receive buffer is implemented.
'
' It is a replacement for "Usart_Read(var error : byte) : byte;" from the "Usart Library".
' This unit provides the function "UsartCharPresent: boolean;" to find out if characters are received.
'
' It assumes the routine "Usart_Init(const baud_rate : longint)" has been called in advance.
'


'  interface:

dim UsartBufferOverflow as boolean          '(public variable)
' Indicates if a character was received while the UsartBuffer was full.
' Has to be set to "false" by the application that uses this unit.

sub function UsartCharPresent as boolean 'Returns "true" if at least one character is in the buffer (received but not yet read)
sub function ReadUsartByte as byte  'Returns the next received character in the Usart buffer
sub procedure UsartReceiverInterrupt
sub procedure UsartReceiverInit



'   For the UsartBuffer a "Queue" mechanism is used:
'
'    * The 2 pointers (WritePtr/ReadPtr) start at the same buffer address.
'
'    * A new element is placed at the current [WritePtr], and WritePtr is incremented (WritePtr++).
'      If it passes the buffer top address, it is 'folded back' to the lowest address.
'    * The buffer is "not empty" now (anymore).
'    * If WritePtr gets to be equal to ReadPtr after the WritePtr increment, the buffer is "full".
'
'    * When you want to get a element off the buffer, you read the [ReadPtr] position,
'      and the ReadPtr pointer gets incremented (ReadPtr++).
'      If it passes the top buffer address, is folded back to the lowest address.
'    * The buffer is "not full" now (anymore).
'    * If ReadPtr is equal WritePtr after the ReadPtr increment, the buffer is "empty".
'*******************************************************************************
implements

dim UsartBuffer as byte[UsartBuffSize]              'buffer array
dim UsartBuffWritePtr, UsartBuffReadPtr as word     'pointers
dim UsartBufferEmpty, UsartBufferFull, UsartError as boolean
dim UsartData as byte
'*******************************************************************************
'Set up receiver
sub procedure UsartReceiverInit
  UsartBuffWritePtr = 0
  UsartBuffReadPtr = 0
  UsartBufferEmpty = true
  UsartBufferFull = false
  UsartBufferOverflow = false
  RCIF_bit = 0  '{= PIR1.RCIF}    // clear interrupt flag
  RCIE_bit = 1 '{= PIE1.RCIE}    // enable Usart interrupts
  PEIE_bit = 1 '{= INTCON.PEIE}  // enable peripheral interrupts
end  sub
'*******************************************************************************
'detect Char(s) in buffer by testing  UsartBufferEmpty state
sub function UsartCharPresent as boolean
  Result = false
  if (UsartBufferEmpty = false)    then
       Result = true
  end if
end sub
'*******************************************************************************
'Read byte(s) from UsartBuffer
sub function ReadUsartByte  as byte
  RCIE_bit = 0                                        ' Disable Usart Interrupts
    if UsartBufferEmpty = false then
          Result = UsartBuffer[UsartBuffReadPtr]
          Inc(UsartBuffReadPtr)
          if UsartBuffReadPtr = UsartBuffSize then
              UsartBuffReadPtr = 0
          end if
          UsartBufferFull = false
          UsartBufferEmpty = (UsartBuffReadPtr = UsartBuffWritePtr)
          '   assignment "="        (operator "=") looks like: =
          'if UsartBuffReadPtr = UsartBuffWritePtr then
'              UsartBufferEmpty = true
'          end if
     end if
  RCIE_bit = 1                                  ' Enable Usart Interrupts again
end sub
'*******************************************************************************
sub procedure UsartReceiverInterrupt
  UsartError = false
  UsartData = RCREG                            ' this read action also clears the interrupt flag.
  if (RCSTA and %00000110) > 0 then             'error
    CREN_bit = 0
    CREN_bit = 1                                'Restart Usart reception
    UsartError = true
  end if
  
  if UsartError = false then
        if UsartBufferFull = false then
          UsartBuffer[UsartBuffWritePtr] = UsartData
          Inc(UsartBuffWritePtr)
              if UsartBuffWritePtr = UsartBuffSize then
                  UsartBuffWritePtr = 0
              end if
              UsartBufferEmpty = false
               UsartBufferFull = (UsartBuffWritePtr  = UsartBuffReadPtr)
               '   assignment "="         (operator "=") looks like:
              'if  (UsartBuffWritePtr  = UsartBuffReadPtr) then
'                  UsartBufferFull =   true
'              end if
        else UsartBufferOverflow = true
        end  if
   end if

end sub

end.
Finally the bit where the buffer size is defined:

Code: Select all

module Globals
 const UsartBuffSize = 30
implements

end.
It works a treat! Give it a try next time you need relaible Uart comms.

JohanB_
Posts: 3
Joined: 08 Nov 2009 16:07

Re: Uart1 / Usart Interrupt driven receiver

#2 Post by JohanB_ » 10 Nov 2011 10:33

Thanks for good code
I use this code with Pic 16F887 with 20Mhz and Eysypic 5 board and the work very well :D :D
/JohanB_

ultrabrains
Posts: 17
Joined: 08 Sep 2010 05:22

Re: Uart1 / Usart Interrupt driven receiver

#3 Post by ultrabrains » 20 Dec 2011 02:48

code not compiling!
Please help, what am I doing wrong?

I have uploaded all mikrobasic Pro file

Thanks
Attachments
UART Project.zip
(6.25 KiB) Downloaded 230 times

srnet
Posts: 163
Joined: 28 Mar 2009 17:14

Re: Uart1 / Usart Interrupt driven receiver

#4 Post by srnet » 20 Dec 2011 07:18

Can you give us a clue as to what the error is ?

ultrabrains
Posts: 17
Joined: 08 Sep 2010 05:22

Re: Uart1 / Usart Interrupt driven receiver

#5 Post by ultrabrains » 20 Dec 2011 07:42

0 : 356 : main function is not defined : main function is not defined

ultrabrains
Posts: 17
Joined: 08 Sep 2010 05:22

Re: Uart1 / Usart Interrupt driven receiver

#6 Post by ultrabrains » 20 Dec 2011 10:18

The error when you click on compile >>
Line 356: main function is not defined

Thanks

User avatar
janko.kaljevic
Posts: 3565
Joined: 16 Jun 2011 13:48

Re: Uart1 / Usart Interrupt driven receiver

#7 Post by janko.kaljevic » 20 Dec 2011 10:24

Hello,

Please check if the all source files are included in Project Manager window.

Best regards.

ultrabrains
Posts: 17
Joined: 08 Sep 2010 05:22

Re: Uart1 / Usart Interrupt driven receiver

#8 Post by ultrabrains » 21 Dec 2011 05:52

I have all libraries checked and I have uploaded the code I am trying to compile. Please download and compile it to see the error your self. I am compiling with mikroBasic Pro.

If the error is fixed, you can then re-upload here for all to enjoy.

Thanks once more

srnet
Posts: 163
Joined: 28 Mar 2009 17:14

Re: Uart1 / Usart Interrupt driven receiver

#9 Post by srnet » 21 Dec 2011 08:08

You may have all the libraries checked in the library manger, but the suggestion was to check that the source file (the .bas file with the main: label (funtion) is included in the sources listed in the project manager.

ultrabrains
Posts: 17
Joined: 08 Sep 2010 05:22

Re: Uart1 / Usart Interrupt driven receiver

#10 Post by ultrabrains » 21 Jan 2012 10:21

Thanks for your response,I have equally checked the source files.

Please Note: I uploaded the Zipped project files. so please download and run it so yo can tell me precisely what I am doing wrong.

Thanks.

Dany
Posts: 3854
Joined: 18 Jun 2008 11:43
Location: Nieuwpoort, Belgium
Contact:

Re: Uart1 / Usart Interrupt driven receiver

#11 Post by Dany » 21 Jan 2012 11:16

Hi, I see in the .mbppi (in Uart_project.zip) file that no files are present in the project:

Code: Select all

[FILES]
Count=0
I think that at least one file should be present: the main project file:

Code: Select all

[FILES]
Count=1
File0=Uart_test.mbas
So, this file should be added in the IDE's project manager...
Kind regards, Dany.
Forget your perfect offering. There is a crack in everything, that's how the light gets in... (L. Cohen)
Remember when we were young? We shone like the sun. (David Gilmour)

Post Reply

Return to “mikroBasic PRO for PIC General”