PDA

View Full Version : Serin and Serout problem



rubisharmax
- 31st May 2012, 09:28
Hi,

I'm just trying the communication between two PICs (both 12F675) using Serin and Serout with the codes written below:

For the transmitter:


Include "modedefs.bas" ' Include serial modes
define osc 4


output GPIO.1
SO var GPIO.1 ' Define serial out pin
B0 Var byte


B0=50
pause 3000
mainloop:
Serout SO,N9600,[B0] ' Send character
Goto mainloop ' Forever

End

And for the receiver:


Include "modedefs.bas" ' Include serial modes


define osc 4


input GPIO.1
SI var GPIO.1 ' Define serial in pin
B0 Var byte
output GPIO.2
LED VAR GPIO.2


main:
LED=0
pause 1000
LED=1
pause 1000
LED=0

mainloop:
Serin SI,N9600,[B0] ' Receive character
if B0=50 then LED=1
Goto mainloop ' Forever

End

I connected GPIO.1 pins of the transmitter and receiver PICs to each other. When I check the voltage on the GPIO.1 pin of the transmitter PIC it shows around 2.95V after 3 seconds since the program started which I interpret as the PIC is sending some data. However, the receiver PIC is supposed to turn the LED on if it gets a byte with the value 50 but nothing happens. Could you help me please?

Thanks in advance.

timmers
- 31st May 2012, 10:12
At first glance,
Check you have turned off the comparators on the GPIO port. (CMCON = 7), and the analog input (ANSEL = 0) to enable digital IO.
Also use a holdup resistor on the data line when using SEROUT (tristates the pin when idle) or use SEROUT2 (leaves the pin high when idle).
Also in your receiver code, instead of turning the LED on (LED = 1) toggle it (TOGGLE LED). You will then see a change upon every packet received.

rubisharmax
- 31st May 2012, 11:32
Thanks timmers, I did what you said but still not working :(

rubisharmax
- 31st May 2012, 12:43
I was using internal oscillator of 12F675 but when I changed to external XT, it seems to work better now. So, can I conclude that we shouldn't rely on the internal oscillator when we use Serin and Serout?

AvionicsMaster1
- 31st May 2012, 14:13
I was shown some time ago that if you do the math of a 4Mhz oscillator, internal for a 12f675, the possible timing errors preclude oscillators that slow. Since you went to an external oscillator, assuming greater than 4Mhz, the problem was reduced.

I have always been told the slowest you can run a PIC transferring serial data is 20Mhz. If you move to that speed I'm thinking your problems would be reduced.

rubisharmax
- 31st May 2012, 14:17
Thanks AvionicsMaster1, I currently use 4MHz but I'll also try 20MHz to see if it'll make better.

longpole001
- 31st May 2012, 16:54
assuming it async , why did this not work correctly on internal clock

rsocor01
- 31st May 2012, 19:05
Were you able to see the LED flashing once?

main:
LED=0
pause 1000
LED=1
pause 1000
LED=0

Maybe, the internal oscillator wasn't set correctly.

rubisharmax
- 1st June 2012, 07:52
@longpole001 and rsocor01:

I don't know why it didn't work correctly, I could see the LED flashing properly though.

Even now it works instable so I'll try to use debug and debugin to see if it'll make a difference...

rubisharmax
- 1st June 2012, 09:10
Hi again,

Debug and debugin seems to work properly with external cyrstal. However, if I operate the transmitter at 4MHz and the receiver at 8MHz, the receiver doesn't pick the data. I also verified this in Proteus. Do both tr and rec PICs need to be operated at the same frequency?

Thanks.

vaporized
- 1st June 2012, 21:56
Hello

Transmitter and receiver do not need to operate at the same speed. They only have to use same baud rate. For instance, PIC and PC work at very different speeds yet they can communicate.

As regards need for 20MHz oscillator for serial communication, I don't think that's correct. 4MHz is perfectly enough as long as you utilize adequate baud rates. Since it is a software serial communication, I would recommend not to exceed 2400 baud.

Send some garbage first to "clear" comm-line and then transmit real data.

It is good practice to apply pulling resistors, pull-downs in your case since you're using inverted mode.
Also make sure that data line is not too long.

rubisharmax
- 2nd June 2012, 17:58
Thanks grinder, I can now use an 18f2550 at 48MHz to receive the data sent by 12F675 at 4MHz and 9600 baud. I'll try to send the received data from 18F2550 to PC over USB using USBOUT command and write here if successful or not.

Archangel
- 3rd June 2012, 08:14
OKkkkkkkkkkkkay,
DEFINE OSC 4, should always be all capital letters. In fact all defines should be, I understand the PB assembler is less fussy, but MPASM must be.
Get used to using MPASM as your choice of assembler as PBP3 requires it, as does almost all of Darrel's tricks.
The define does not actually set the oscillator speed, what it does do is adjust PBP timings so when you specify something like Pause 100 it actually generates the correct number of assembly nops to give you that 100 ms. Since I am not looking at the data sheet for the 12F675 understand I am winging it here, but as I remember the option Reg does set the OSC speed. As for can you use intrc or xt or HS with serout the answer is yes but with this caveat, the slower the OSC vs The BAUD rate the more likely the error will exceed the " I just can't understand what you're saying" level of the other chip. Obviously a crystal is closer to being on frequency followed by a resonator, and then internal / external R/C oscillator. Debug seems to work better than serin / out in R/C due to lower overhead going on in the background.
Finally, if you are using a resonator of any frequency you should use the HS_OSC in your config. What this does is allow more power to run the OSC than the XT_OSC allows.

HTH
JS

rubisharmax
- 4th June 2012, 11:57
Thanks Archangel, I changed the definitions as you said.

On the other hand, there's a weird problem again: I send a serial bytes of "50" and "55" from 12F675 to 18F2550. 18F2550 is supposed to take the serial data input and send it to PC via USB.

The transmitter code is as follows:


Include "modedefs.bas" ' Include serial modes

DEFINE OSC 4

CMCON = 7
ANSEL = 0

output GPIO.1
SO var GPIO.1 ' Define serial out pin
B0 Var byte

mainloop:
pause 1
B0=50
Serout SO,N9600,[B0] ' Send character
pause 1
B0=55
Serout SO,N9600,[B0] ' Send character
Goto mainloop ' Forever

End

And on the 18F2550, just trying to read serial input and then send it via USBOUT command:


DEFINE OSC 48Include "modedefs.bas"
Buffer VAR BYTE[1]
Cnt VAR BYTE
counter VAR WORD
B0 VAR BYTE


ADCON1 = 15 ' Set all I/Os to Digital
CMCON = 7 ' Disable Comparators
Cnt = 1


input PORTA.0
SI var PORTA.0


USBInit ' Initialize USART

Loop2:
Serin SI,N9600,B0
Buffer(0)=B0

Loop1:
USBService
USBOut 3, Buffer, Cnt, loop1
goto Loop2 ' Go and read serial input data again


end

The problem is: when I load the above code into 18F2550, PC doesn't see the virtual COM port. But when I change the code as follows, it works fine:


DEFINE OSC 48Include "modedefs.bas"
Buffer VAR BYTE[1]
Cnt VAR BYTE
counter VAR WORD
B0 VAR BYTE

ADCON1 = 15 ' Set all I/Os to Digital
CMCON = 7 ' Disable Comparators
Cnt = 1

input PORTA.0
SI var PORTA.0

USBInit ' Initialize USART

Loop2:
Serin SI,N9600,B0
Buffer(0)=B0

Loop1:
USBService
USBOut 3, Buffer, Cnt, loop1
goto Loop1 ' Send the same received serial data again and again to the PC

end

The problem is: I need to read each serial input data and send it to PC via USB on 18F2550. Tried loads of combinations but nothing worked except the latter code above, which sends the data received only once at the start of the program.

Any opinion to overcome this problem?

vaporized
- 10th June 2012, 13:20
Hello.
You have to service USB regularly (about 5ms max. between servicing) which the first 18F2550 program fails to do due to "goto Loop2" directing program to Serin. With Serin PIC just sits there waiting for serial data and can't do anything else (*1), like service USB, until the data arrives. And there are numeruos reasons for PICs not to get the data therefore just hanging on Serin.

*1 - o.k., not entirely true, PICs can run comparators, timers, send/receive serial data, etc. in background, depending on device's features.


You can try with Timeout parameter for Serin but I don't think it'll work as desired with such a short period as 5ms.
I would rather suggest you to employ 18F2550's UART for serial data reception. That way you can service USB while receiving data in background.
But keep in mind that UART size is 2 bytes so either make larger pause between data transmission so you have time to collect data from UART, send it to PC, and service USB; or use interrupts (mr. Darrel Taylor's Instant Interrupts are really great) in combination with (circular) buffer.
Another thing of importance when dealing with UART is that you have to switch to true mode (T9600 instead of N9600; pull-ups instead of pull-downs; data-line idles high)


Oh, one more thing - I see you're not using DEFINE OSCCAL in your 12F675 programs. I don't know if PBP3 (presuming that's your version) handles that differently than previous versions (PBP2.5 here) but please make sure and see about it in maual.