Modules, libraries etc.

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

Modules, libraries etc.

#1 Post by dangerous » 24 Feb 2006 12:48

This link: [/url]http://www.mikroe.com/forum/viewtopic.php?t=4101[url] shows a useful usart routine.

It suggests that the MCL file can be used with MikroBasic, so I downloaded MikroPascal, and compiled the test program.

Amongst the files was the irq_usart.MCL file. I copied this to MB and re-wrote the test routine for MB:

Code: Select all

program Uart_test
include "irq_usart"
dim var,tmp As byte

main:
  irq_usart_init    '// intialises the interrupt
  usart_init(4800)  '// redefines the baudrate
  while true do

    while lines_read  < 3 do nop  '// read into buffer until 3 CR's received
          while lines_read > 0  do       '// then send's back these 3 line's

               tmp = readkey
              write(tmp)
              wend
    wend
  wend
end.
Attempt to compile it with the MCL file in the same project folder - nothing!
6:3 3 Identifier 'irq_usart_init' was not declared Uart_test.pbas comes up in the error zone.

Back in MP, I tried only loading the test file and the MCL. Same result it will not compile, unless the unit irq_usart is present.

How do we use an MCL file? Can it be compiled on its own?

Help!

jpc
Posts: 1986
Joined: 22 Apr 2005 17:40
Location: France 87

#2 Post by jpc » 24 Feb 2006 13:03

Bonjour dangerous ,

the include should be just include irq_usart , as the sourcefile is not present. Next you should create the .mcl ( in Pascal) for the right PIC-type , i think you should have at least different .mcl's for P16 and P18 family's , and they should be placed in the appropriate uses/pxx folder . Then it should work without problem. ( you can adjust the size of the buffers , P16 has limited resources )
I do hope this exchange of mcl will be possible between all compilers with the upcoming release . I have not been able to test that yet.

jpc
Posts: 1986
Joined: 22 Apr 2005 17:40
Location: France 87

#3 Post by jpc » 24 Feb 2006 13:15

with respect to compilation , you cannot compile a unit on its own , you need a program that 'uses' the unit to compile. Then a .mcl for the unit ( and the program) is generated. Aside from terminology this should be identical in Basic. As i already sayd , the .mcl has to be created for the PIC you are using. If you compile the example in Pascal , this will automatically be ok as there the source is available and if you select another PIC the unit will be recompiled with the program.

dangerous
Posts: 748
Joined: 08 Mar 2005 16:06
Location: Nottinghamshire, UK

#4 Post by dangerous » 24 Feb 2006 14:03

Thanks for that jpc.
the include should be just include irq_usart ,
without quotation marks?

so {include irq_usart }

not {include "irq_usart "}

I am only copying the irq_usart.MCL file to MB.

I did a compile for 16F877A at 8MHz in both cases. The MCL file is present in the project directory for the MB version. Clicking on it in IDE just gives "MCL" at the top of page. File is about 59Kb. Looking at file with notepad means very little but there is data present.

I have just tried with {include irq_usart } as include statement. Same thing. Failure at {init_irq_usart} line with message: "6:3 3 Identifier 'irq_usart_init' was not declared Uart_test.pbas"

If irq_usart.MCL file is not present I get message "file not found", so MB must be finding something.

I cannot insert a screen print to show it, but the same thing happens in mikro pascal if there is only the MCL file present. Perhaps I have a set up problem somewhere.

I will try to modify the irq_usart.ppas file for MB and see if that works as a MCL file, (if I can translate it properly to basic from pascal!)

I always seem to have trouble with this sort of thing, and wonder what I am doing wrong. :oops: The manuals are a bit indefinite about modules and libraries, or I am too stupid to follow them!

jpc
Posts: 1986
Joined: 22 Apr 2005 17:40
Location: France 87

#5 Post by jpc » 24 Feb 2006 14:11

actually i am checking this right now , i never use Basic but did the test after writing that unit. One thing i am not sure about now is wether the .mcl conatins all code or only those elements that were used at time of compilation. In that case we would need dummy-calls to include everything in the mcl but again, i am not sure . Will keep you informed .

xor
Posts: 5465
Joined: 18 May 2005 00:59
Location: NYC
Contact:

#6 Post by xor » 24 Feb 2006 14:24

You might need to place a "cold" (without *.pbas) *.mcl file in your USES folder. I can get custom units/modules to work if I open the *.pbas file in my project folder, open with my open project and main source code, and then compile.
[color=darkred][b]xor[/b][/color]
[url=http://circuit-ed.com]CircuitED -[/url]

dangerous
Posts: 748
Joined: 08 Mar 2005 16:06
Location: Nottinghamshire, UK

#7 Post by dangerous » 24 Feb 2006 14:24

Merci, jpc.

I look forward to your replies. I am out of the office from about now until Monday, so I hope to hear from you then.

It could be me who can not drive the IDE properly.

xor
Posts: 5465
Joined: 18 May 2005 00:59
Location: NYC
Contact:

#8 Post by xor » 24 Feb 2006 14:36

jpc,

A while back I started to convert your pascal to basic for this module but I got a little confused in one part with the If-Then statements at some point. I wasn't familiar enough with Pascal syntax to be sure I was doing it correctly but maybe this weekend I will take a shot at it again.
[color=darkred][b]xor[/b][/color]
[url=http://circuit-ed.com]CircuitED -[/url]

jpc
Posts: 1986
Joined: 22 Apr 2005 17:40
Location: France 87

#9 Post by jpc » 24 Feb 2006 14:43

hi xor , nice if you convert it to mB , just succeded to use it in mB by include irq_usart , found some problems however regarding scope , possibly irrelevant with the incoming compiler , anyway it is always better to have access to the source for the same compiler.
If you have questions regarding how the code works , let me know

jpc
Posts: 1986
Joined: 22 Apr 2005 17:40
Location: France 87

#10 Post by jpc » 24 Feb 2006 14:43

hi xor , nice if you convert it to mB , just succeeded to use it in mB by include irq_usart , found some problems however regarding scope of functions and variable's , possibly irrelevant with the incoming compiler , anyway it is always better to have access to the source for the same compiler.
If you have questions regarding how the code works , let me know

lsv
Posts: 74
Joined: 03 Feb 2006 14:08
Location: Russia

#11 Post by lsv » 26 Feb 2006 08:27

hi, jpc!
I try to convert your mcl to mB too, but not test yet
Check, pls, sub interrupt and readkey

Code: Select all

 module irq_usart
 const rxbufsize as byte = 40
 const txbufsize as byte = 40
 const baudrate  as word = 19200

dim ik as byte ' // private to interrupt !
    k as byte
    rxstatus as byte


    dim RXhead, RXtail  as  byte
    Dim Rxbuf  as byte[rxbufsize]
    Dim RXbufempty, RXbfull as  boolean

    Dim txbuf as byte[txbufsize]
    Dim txhead, txtail as byte
    Dim crflag as byte
    Dim TXbuffull, TXbufempty  as boolean

 implements
 sub procedure interrupt
 if PIR1.RCIF = 1 then
   rxstatus = RCSTA ' error-handling
    if rxstatus and %00000110 = 0 then
      ik = RCREG
      RXbuf[RXtail] = ik
      inc(RXtail)
      if rxtail > rxbufsize then rxtail = 0 end if
      RXbufempty = false
      if RXtail = RXhead then RXbfull = true end if
      if ik = 13 then inc(crflag) end if
    else
      ' error in reception
      SetBit(RCSTA,CREN)
    end if
    ClearBit(PIR1,RCIF)
 end if
 if PIR1.TXIF = 1 then
    if TXbufempty = false then
      ' transmit everything in buffer
      TXREG = txbuf[txhead]
      inc(txhead)
      TXbuffull = false
      if txhead > txbufsize then txhead = 0 end if
       if txhead=txtail then
        TXbufempty = true
       else
        ClearBit(PIR1,TXIF) ' allow next byte to be sent
       end if
     else
      ClearBit(PIE1,TXIE)
     end if
  end if
 end sub
 
sub function readkey as byte  ' read a byte from the input-FIFO
dim k as byte
  k = 0
  if RXbufempty = false then
    k = RXbuf[RXhead]
    if k = 13 then dec(crflag) end if
    RXbuf[RXhead] = 0 ' destructive read
    inc(RXhead)
    if RXhead >  RXbufsize then RXhead = 0 end if
    if RXhead = RXtail then RXbufempty = true else RXbfull = false end if
  end if
  result = k
end sub

sub function lines_read as byte  ' function return nr cr's in FIFO
  result = crflag
end sub

sub procedure _write(dim k as byte) ' write a byte to the TX-FIFO
  while txbuffull
   nop ' if necessary wait until buffer not full
  wend
  TXbuf[TXtail] = k
  inc(TXtail)
  if txtail > txbufsize then txtail = 0 end if
  if TXtail=TXhead then txbuffull = true end if  ' notify buffer full
  SetBit(PIE1,TXIE)   ' Allow UsartTX-interrupt'
  txbufempty = false
end sub

sub function keypressed as boolean ' returns false if no byte available in RX-FIFO
  if rxbufempty then result = false else result = true end if
end sub

sub procedure writeln(dim s as string[20])
dim i as byte
  i = 0
  while s[i] <> 0
      _write(s[i])
       inc(i)
  wend
  _write(13)
  _write(10)
end sub

 sub procedure irq_usart_init
  memset(@RXbuf,0,rxbufsize)
  memset(@TXbuf,0,txbufsize)
  RXhead = 0
  RXtail = 0
  TXtail = 0
  TXhead = 0
  RXbfull = false
  RXbufempty = true
  TXbuffull = false
  TXbufempty = true
  crflag = 0
  Usart_Init(baudrate)
  SetBit(RCSTA,CREN)
  SetBit(PIE1,RCIE)   ' Allow UsartRX-interrupt's
  SetBit(TXSTA,TXEN)  ' enable Usart transmission maybe done by usart_init()
  SetBit(INTCON,PEIE) ' Allow peripheral interrupts
  SetBit(INTCON,GIE)  ' Allow general Interrupt's
  Delay_Ms(50)

 end sub

 end.
You do very important thing - post sources of mcl!

jpc
Posts: 1986
Joined: 22 Apr 2005 17:40
Location: France 87

#12 Post by jpc » 26 Feb 2006 09:12

Bonjour lsv,

the first important difference i see is that you have all var-declarations in the interface-section , i think you should put them in the implementation part. Aside from that it looks ok , why not just test it .

I did try to use the .mcl generated by mP3.2 after dangerous asked , it works but i did face some problems with visibility. I could not call the function lines_read for some unknown reason , however could test the var crflag which should be invisible outside the unit. Anyway , i could successfully run this test :

Code: Select all

While true
'if lines_read > 3 'this did not work but should
 if crflag > 3 then 'this should not be possible
  while keypressed
    xx = readkey
    usart_write(xx)
  wend
end if

Wend

I tested yor code and it seems to work fine.


My feeling is that mE should build compilers , users can contribute to the project by publishing library's , together we will have better products.
Once the sources are published we can discuss problems with them and improve the library's.
Last edited by jpc on 26 Feb 2006 14:22, edited 1 time in total.

jpc
Posts: 1986
Joined: 22 Apr 2005 17:40
Location: France 87

#13 Post by jpc » 26 Feb 2006 10:01

now it looks like this :

Code: Select all

module irq_usart

implements
 
 const rxbufsize as byte = 40
 const txbufsize as byte = 40
 const baudrate  as word = 9600

dim ik as byte ' // private to interrupt !
    k as byte
    rxstatus as byte


    dim RXhead, RXtail  as  byte
    Dim Rxbuf  as byte[rxbufsize]
    Dim RXbufempty, RXbfull as  boolean

    Dim txbuf as byte[txbufsize]
    Dim txhead, txtail as byte
    Dim crflag as byte
    Dim TXbuffull, TXbufempty  as boolean

 sub procedure interrupt
 if PIR1.RCIF = 1 then
   rxstatus = RCSTA ' error-handling
    if rxstatus and %00000110 = 0 then
      ik = RCREG
      RXbuf[RXtail] = ik
      inc(RXtail)
      if rxtail = rxbufsize then rxtail = 0 end if
      RXbufempty = false
      if RXtail = RXhead then RXbfull = true end if
      if ik = 13 then inc(crflag) end if
    else
      ' error in reception
      SetBit(RCSTA,CREN)
    end if
    ClearBit(PIR1,RCIF)
 end if
 if PIR1.TXIF = 1 then
    if TXbufempty = false then
      ' transmit everything in buffer
      TXREG = txbuf[txhead]
      inc(txhead)
      TXbuffull = false
      if txhead = txbufsize then txhead = 0 end if
       if txhead=txtail then
        TXbufempty = true
       else
        ClearBit(PIR1,TXIF) ' allow next byte to be sent
       end if
     else
      ClearBit(PIE1,TXIE)
     end if
  end if
 end sub

sub function readkey as byte  ' read a byte from the input-FIFO
dim k as byte
  k = 0
  if RXbufempty = false then
    k = RXbuf[RXhead]
    if k = 13 then dec(crflag) end if
    RXbuf[RXhead] = 0 ' destructive read
    inc(RXhead)
    if RXhead >  RXbufsize then RXhead = 0 end if
    if RXhead = RXtail then RXbufempty = true else RXbfull = false end if
  end if
  result = k
end sub

sub function lines_read as byte  ' function return nr cr's in FIFO
  result = crflag
end sub

sub procedure _write(dim k as byte) ' write a byte to the TX-FIFO
  while txbuffull
   nop ' if necessary wait until buffer not full
  wend
  TXbuf[TXtail] = k
  inc(TXtail)
  if txtail > txbufsize then txtail = 0 end if
  if TXtail=TXhead then txbuffull = true end if  ' notify buffer full
  SetBit(PIE1,TXIE)   ' Allow UsartTX-interrupt'
  txbufempty = false
end sub

sub function keypressed as boolean ' returns false if no byte available in RX-FIFO
  if rxbufempty then result = false else result = true end if
end sub

sub procedure writeln(dim byref s as string[20])
dim i as byte
  i = 0
  while s[i] <> 0
      _write(s[i])
       inc(i)
  wend
  _write(13)
  _write(10)
end sub

 sub procedure irq_usart_init
  memset(@RXbuf,0,rxbufsize)
  memset(@TXbuf,0,txbufsize)
  RXhead = 0
  RXtail = 0
  TXtail = 0
  TXhead = 0
  RXbfull = false
  RXbufempty = true
  TXbuffull = false
  TXbufempty = true
  crflag = 0
  Usart_Init(baudrate)
  SetBit(RCSTA,CREN)
  SetBit(PIE1,RCIE)   ' Allow UsartRX-interrupt's
  SetBit(TXSTA,TXEN)  ' enable Usart transmission maybe done by usart_init()
  SetBit(INTCON,PEIE) ' Allow peripheral interrupts
  SetBit(INTCON,GIE)  ' Allow general Interrupt's
  Delay_Ms(50)

 end sub

 end.
and it can be tested with

Code: Select all

program irq_usart_test
include "irq_usart"
dim xx as byte
main:
irq_usart_init

USART_INIT(9600)
usart_write_text("basic-version")
usart_write(10)
usart_write(13)


While true
 if lines_read > 3 then
  while keypressed
    xx = readkey
    usart_write(xx)
  wend
  end if
wend
'
end.
for running this test we connect Hyperterminal , 9600-8-N-1 .
The tesprogram store's received characters in the buffer until the 4th return is received , then replies all received characters . The buffer is only 40 characters in this example , can be overrun if we send too much characters. If needed you can expand the buffersize up to 255.
Last edited by jpc on 26 Apr 2007 17:53, edited 2 times in total.

lsv
Posts: 74
Joined: 03 Feb 2006 14:08
Location: Russia

#14 Post by lsv » 26 Feb 2006 11:09

jpc!
Sorry, i forgot some lines in code:

Code: Select all

module irq_usart
'*************************************************
'* @JPC 2005 from mPascal version 3.2.0.0 
'*************************************************
...

jpc
Posts: 1986
Joined: 22 Apr 2005 17:40
Location: France 87

#15 Post by jpc » 26 Feb 2006 11:41

very kind , but was no code !

Post Reply

Return to “mikroBasic General”