Strange behaviour of UART Library

Beta Testing discussion on mikroBasic PRO for PIC.
Post Reply
Author
Message
Tullio1248
Posts: 6
Joined: 24 Mar 2009 16:59

Strange behaviour of UART Library

#1 Post by Tullio1248 » 08 Jun 2009 18:12

there are any known bugs in the UART routines?

i'm using PIC18F2620 @ 10 mhz hs and not hsPLL with a speed of 4800 baud
in the same project i'm also using soft uart routines with a speed of 9600 baud (if this is of interest)

I have in a routine a code that is almost the same calling 2 serial boards

the first part of the routine work properly but the second does not receive anything at all.

With a sniffer on the serial line the data i'm expecting are actually coming but are not received from the UART.

this is the code, pls take a look to the comments in english

Actually i'm in bad troubles because there is a project blocked and i'm not able to deliver equipments...

Please help me....

Best regards to everibody

Tullio



sub procedure Alimentatori()
dim cc as word
dim h as word
dim K as word
dim l as byte
dim Q as byte
Dim B as byte
Dim ff as byte
dim V as byte
dim j as byte
dim po3 as byte
dim pos1 as byte
dim qas as char[3]
dim EV1 as byte
dim EV2 as byte

for Q=1 to Pk.NAL
clrwdt
clearbit(rcsta,4)
po3=0
UART1_Write (233)
po3=po3+41
clrwdt
UART1_Write (Q)
po3=po3+Q
clrwdt
UART1_Write ((pk.Voltaggio-1))
po3=po3+(pk.voltaggio-1)
clrwdt
'preparo la parola di controllo
'recupero i bit dall'array di controllo
ff=hi(PK.ArU[Fase])
Select case Q
Case 1,3,5,7
ff=ff and (8+4)
'f=f/4
Select case ff
Case 0
UART1_Write (68)'Scarica
B=B+68
Case 4
UART1_Write (78)'Positiva
B=B+78
Case 8
UART1_Write (80)'Negativa
B=B+80
Case else
Allarme=1
Alarm=20000+f+Fase
end select
Case 2,4,6,8
ff=ff and (16+32)
'f=f/8
Select case ff
Case 0
UART1_Write (68)'Scarica
B=B+68
Case 16
UART1_Write (78)'Positiva
B=B+78
Case 32
UART1_Write (80)'Negativa
B=B+80
Case else
Allarme=1
Alarm=ff
end select
end select
UART1_Write(211)
po3=po3+211
clrwdt
UART1_Write (po3)
clrwdt
delay_us(2001)
setbit(rcsta,4)
cc=0
for j=0 to 12
msg[j]=0
next j
pos1=0
Po3=0

while cc<20001
if (UART1_Data_Ready() = 1) then
po3 = UART1_Read()
msg [pos1] = po3
inc(pos1)
End If
delay_us(1)
inc(cc)
if pos1>4 then

goto jj29
end if
wend

Alarm=20000
Allarme=1
goto jj28
jj29:

po3=msg[0]
po3=po3+msg[1]
po3=po3+msg[2]
po3=po3+msg[3]
clearbit(rcsta,4)
UART1_Write(28)
UART1_Write(msg[0])
UART1_Write(msg[1])
UART1_Write(msg[2])
UART1_Write(msg[3])
UART1_Write(msg[4])
UART1_Write(100)
delay_us(2001)
setbit(rcsta,4)
'Allarme=0
if msg[2]>0 then
inc(CAAlimentatori)
if CAAlimentatori>2 then
Alarm=msg[2]+1024
Allarme=1
end if
end if

delay_ms(3)
next Q
jj28:
CAAlimentatori=0


'all the upper part works fine problems are coming from here:

clrwdt
clearbit(rcsta,4)
po3=0
UART1_Write (91)
po3=po3+91
clrwdt
UART1_Write (199)
po3=po3+199
clrwdt
if Lavaggio=0 then
EV1=88 'lo(PK.ARU[Fase]) 'just to bu shure during tests
else
EV1=88 'lo(ULavaggio[FLav])
end if
UART1_Write (EV1)
po3=po3+88 'EV1
if Lavaggio=0 then
EV2=90 '(hi(PK.ArU[Fase]) or 3) also here
else
EV2=90 'hi(Ulavaggio[Flav]) 'and here
end if
if Allarme=0 then
UART1_Write (EV2)
po3=po3+90 'EV2
else
UART1_Write(EV2+128)
po3=po3+EV2+128
end if
clrwdt
UART1_Write(po3)
clrwdt
UART1_Write (93)
clrwdt
delay_us(2001)
setbit(rcsta,4)

clrwdt
cc=0
for j=0 to 12
msg[j]=0
next j
po3=0
pos1=0
'here is the problem in receive...
while cc<60001
'i never enter this if....
if (UART1_Data_Ready() = 1) then
po3 = UART1_Read()
msg [pos1] = po3
inc(pos1)
End If
delay_us(1)
inc(cc)
if pos1>8 then
' so i never go out from here...
goto pj29
end if
wend
'so i arrive here but all msg[] is filled with "0"......
clearbit(rcsta,4)
UART1_Write(33)
UART1_Write(msg[0])
UART1_Write(msg[1])
UART1_Write(msg[2])
UART1_Write(msg[3])
UART1_Write(msg[4])
UART1_Write(msg[5])
UART1_Write(msg[6])
UART1_Write(msg[7])
UART1_Write(msg[8])
UART1_Write(33)
UART1_Write(pos1)
UART1_Write(33)
delay_us(2001)
setbit(rcsta,4)
'Alarm=11111
' Allarme=1
goto pj28
pj29:
'i never arrive here...
clearbit(rcsta,4)
UART1_Write(28)
UART1_Write(msg[0])
UART1_Write(msg[1])
UART1_Write(msg[2])
UART1_Write(msg[3])
UART1_Write(msg[4])
UART1_Write(msg[5])
UART1_Write(msg[6])
UART1_Write(msg[7])
UART1_Write(msg[8])
UART1_Write(100)
delay_us(2001)
setbit(rcsta,4)

pj28:

end sub

Corallaro
Posts: 11
Joined: 17 Sep 2009 07:54

#2 Post by Corallaro » 06 Nov 2009 10:47

news about your project?
i'm working around a similar project
Giovanni

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

#3 Post by Dany » 06 Nov 2009 11:40

Code: Select all

while cc<60001
  'i never enter this if....
  if (UART1_Data_Ready() = 1) then
    po3 = UART1_Read()
    msg [pos1] = po3
    inc(pos1)
  End If
  delay_us(1)
  inc(cc)
  if pos1>8 then
    ' so i never go out from here...
    goto pj29
  end if
wend
Hi, just some observations...

I assume you are sure that some Uart data should come in during the "while" loop? The while loop makes a timeout of 60000 * (1 us + time for 'Uart1_Data_ready') so, approx 60000 * 2 us = 120 millisecs for all 8 characters to receive. Normally this should be ok at 4800 baud, provided there are no big pauses between characters.
Perhaps you can do a test without the while loop (loop until you have 8 chars) to be sure?

I see that there is a 1 us delay in the loop. I assume that is to manage the timeout of the while loop? I do not think it will pose problems here, but it is a bad idea to put this in a uart poll loop, you could loose data, especially at high baud rates.

The best way of course is receiving uart data under interrupt. I am sure some of the mikroBasic people will know how to do that.
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)

Corallaro
Posts: 11
Joined: 17 Sep 2009 07:54

#4 Post by Corallaro » 06 Nov 2009 17:15

Hi Dany

i polling a couple of rfid receivers

and

i have this

' * Test configuration:
' MCU: PIC16F876A
' Dev.Board: HomeMade
' Oscillator: HS, 20.0000 MHz
' Ext. Modules: FT471 - FT470
' SW: mikroBasic PRO for PIC '



sub procedure interrupt()
UART1_Read_Text(ReceivedTxt,"EN",255) ' the end of rfid msg is "EN"
end sub

............................


UART1_Init(115200) ' Initialize UART module at 115200 bps
Delay_ms(100) ' Wait for UART module to stabilize
I2C1_Init(100000) ' initialize I2C ' i use it to read an RTC

.....................
while (TRUE)

ClrWdt ' clear watchdog to keep the PIC running normally

for cnt = 1 to numlettori ' in my case 2

select case cnt
case 1
UART1_Write_Text("*#010190") ' polling reader 01
case 2
UART1_Write_Text("*#020190") ' polling reader 02
'case 3
'UART1_Write_Text("*#030190") ' polling reader 03
'case 4
'UART1_Write_Text("*#040190") ' polling reader 04
end select
..........................................
bla bla bla
read answer from reader ..rfid code etc.......
..........................................


next cnt
wend



but i have some non costant resutls an some block ...so i use WDT to save me

where is the mistake???

Giovanni

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

#5 Post by Dany » 06 Nov 2009 20:37

Corallaro wrote: where is the mistake???
Hi Giovanni,

I do not know where the mistake is. I do not know the function "UART1_Read_Text(ReceivedTxt,"EN",255)", I use only mikroPascal and it does not exists in it. So, I do not know if it behaves well inside an interrupt routine.
By the way, where dou you enable the uart interrupt?
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)

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

#6 Post by Dany » 06 Nov 2009 21:28

Dany wrote:
Corallaro wrote: where is the mistake???
Hi Giovanni,

I do not know where the mistake is. I do not know the function "UART1_Read_Text(ReceivedTxt,"EN",255)", I use only mikroPascal and it does not exists in it. So, I do not know if it behaves well inside an interrupt routine.
By the way, where dou you enable the uart interrupt?
Erratum: it does exist in mP, I never used it though... :oops: :oops:
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)

Corallaro
Posts: 11
Joined: 17 Sep 2009 07:54

#7 Post by Corallaro » 09 Nov 2009 13:48

hi Dany

there is where i enable interrupts

many thanks

Giovanni


' * Test configuration:
' MCU: PIC16F876A
' Dev.Board: HomeMade
' Oscillator: HS, 20.0000 MHz
' Ext. Modules: FT471 - FT470
' SW: mikroBasic PRO for PIC '

'**************
'**************
'**************

'**********************SUB INTERRUPT********************************************
sub procedure interrupt()
UART1_Read_Text(ReceivedTxt,"EN",255) ' the end of rfid msg is "EN"
end sub

'**************
'**************
'**************

'********************** MAIN ***************************************************
main:
'********************* REGISTERS ***********************************************
TRISA =%00111111 ' designate portA.0.1.2.3.4.5 as input other output
TRISB =%00000000 ' designate portB as output
TRISC =%00000000 ' designate portC as output
ADCON1 =%01000110 ' configure VDD as Vref, and NO analog channels
PORTB =%00000000 ' clear port B
'********************* UART and I2C INIT ***************************************
UART1_Init(115200) ' Initialize UART module at 115200 bps
Delay_ms(100) ' Wait for UART module to stabilize
I2C1_Init(100000) ' initialize I2C
'******************* LCD SECTION ***********************************************
Lcd_Init() ' Lcd_Init_EP4, see autocomplete
Lcd_Cmd(_LCD_CURSOR_OFF) ' send command to LCD (cursor off)
Lcd_Cmd(_LCD_CLEAR) ' send command to LCD (clear LCD)
'********************INTERRUPTS*************************************************
RCIE_bit = 1 ' enable interrupt on UART1 receive
TXIE_bit = 0 ' disable interrupt on UART1 transmit
PEIE_bit = 1 ' enable peripheral interrupts
GIE_bit = 1 ' enable all interrupts
'*****************ENDLESS LOOP**************************************************
while (TRUE)

ClrWdt ' clear watchdog to keep the PIC running normally


for cnt = 1 to numlettori ' in my case 2

select case cnt
case 1
UART1_Write_Text("*#010190") ' polling reader 01
case 2
UART1_Write_Text("*#020190") ' polling reader 02
'case 3
'UART1_Write_Text("*#030190") ' polling reader 03
'case 4
'UART1_Write_Text("*#040190") ' polling reader 04
end select
'****************
'****************
'****************
' bla bla bla
' read answer from reader ..rfid code etc.......
'****************
'****************
'****************

next cnt
wend
end.

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

#8 Post by Dany » 10 Nov 2009 15:25

Corallaro wrote:there is where i enable interrupts


Hi Giovanni, thanks for your post.

I still think one can not use "UART1_Read_Text" inside a Uart interrupt routine.
The interrupt occurs for each character received, while the "UART1_Read_Text" routine obviously waits for more than 1 character.
In principle this means that "UART1_Read_Text" will be called each time a character is received. This is not what you want.

So, there is a huge mismatch here: the "UART1_Read_Text" is polling based and it is used inside an interrupt routine.

Anyway, I'm not sure: I've never used the "UART1_Read_Text". The interrupt based uart reception I use is always character based.
I think you should ask mikroElektronika people about using "UART1_Read_Text" inside the uart interrupt service routine.

Furthermore: in the interrupt routine you should set the uart receive interrupt flag to zero, otherwise the system will think the interrupt still exists (important in case you should decide to not use any longer "UART1_Read_Text" inside it to make it work), and will call "UART1_Read_Text" immediately again.

Success!
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)

Corallaro
Posts: 11
Joined: 17 Sep 2009 07:54

#9 Post by Corallaro » 10 Nov 2009 19:20

many TNX!!!
this evening i'll rewrite the code.....i hope and tell you the results....

Giovanni

Corallaro
Posts: 11
Joined: 17 Sep 2009 07:54

#10 Post by Corallaro » 16 Nov 2009 09:19

Hy Dany

i use the same structure of easyBee receiver example

and now it work perfectly withouts any freeze of code

many many TNX

Giovanni



program Reciever


' * Test configuration:
' MCU: PIC16F876A
' http://ww1.microchip.com/downloads/en/D ... f#page=123
' Oscillator: HS, 20.000 MHz
' * NOTES:
'
' *


' LCD module connections
'''''''''''''bla bla bla
' End LCD module connections


dim txt as char[50]
dim i,state,semafor,DataReady as byte
dim tmp as char


sub procedure interrupt() ' Reading the data from UART in the interuppt routine

if (PIR1.RCIF = 1)then

tmp = UART1_Read()
' We're expecting the sequence of chars "DATA ... : .... CR"
' After ":" the receiver module sends to PIC the string of characters which were sent by the transmitter module
'
' IN THIS SUBROUTINE I PUT THE SEQUENCE OF START OF RFID READERS AND THE END OF SEQUENCE

select case state

case 0
if (tmp = "D") then
state = 1
else
state = 0
end if

case 1
if (tmp = "A") then
state = 2
else
state = 0
end if

case 2
if (tmp = "T") then
state = 3
else
state = 0
end if

case 3
if (tmp = "A") then
state = 4
else
state = 0
end if

case 4
if (tmp = ":") then
state = 5
end if

case 5
semafor = 1
state = 6


case 6
if (tmp = 13) then
semafor = 0
txt = 0 ' Puting 0 at the end of the string
state = 0
DataReady = 1 ' Data is received
end if


case else state = 0

end select



if (semafor) then

txt = tmp ' Moving the data received from UART to string txt[]
inc(i)
end if
PIR1.RCIF = 0

end if
end sub


main:

state = 0 ' Init the STATE mashine variables
semafor = 0
DataReady = 0


UART1_init(115200) ' Initialize UART1 module
Delay_ms(100)

LCD_Init() ' LCD init
LCD_Cmd(_LCD_CLEAR)
LCD_Cmd(_LCD_CURSOR_OFF)

' Configure interrupts
PIE1.RCIE = 1
PIR1.RCIF = 0
INTCON.PEIE = 1

while TRUE
tmp = 0 ' Init variables
i = 0
memset(@txt, 0, 50) ' Clear array of chars

INTCON.GIE = 1 ' Interrupts allowed

while (DataReady = 0) ' Wait while the data is received
''''xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


'IN THIS POSITION INSTEAD THE ORIGINAL "NOP" I PUT THE POLLING COMMANDS AN A LITTLE DELAY


'''''xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

wend

INTCON.GIE = 0 ' Interrupts forbiden
DataReady = 0


LCD_Cmd(_LCD_CLEAR) ' Clear display
Lcd_Cmd(_LCD_FIRST_ROW)
i = 0

while (txt <> 0)
Lcd_Chr_CP(txt) ' Displaying the received text on the LCD
inc(i)
wend
wend
end.

Post Reply

Return to “mikroBasic PRO for PIC Beta Testing”