PDA

View Full Version : Communication between two PicChip



lerameur
- 13th November 2011, 16:13
hello,

I am trying to transfer data from one Pic16F88 to another F88 chip. is there a method better then the other one. I only have 4 ports left (one is use for adcin, one for ground between the two chips and two for serin and serout). The only alternative I know but would cost a bit more is to use an external EEPROM..
I have A master program and a Slave program, here is the code, I think it is self explanatory:
PortB.7 is hooked up to the PortB.0 (interrupt) of the other chip

Master:
SetRTCTime = 125
ViewTime = 0

I2CRead SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCY ear,RTCCtrl]
Pause 30


serout portb.7, n2400, [$55, $55, $55, $55, $aa, SetRTCTime, ViewTime, StartTimeHour ]
serout portb.7, n2400, [StopTimeHour, StartTimeMin, StopTimeMin, RTCYear, RTCMonth, RTCDay, RTCHour, RTCMin ]
Pause 100

lcdout $FE,1, "upload Time Int"
lcdout $FE,$C0, "Completed"
pause 1500

Return

Slave:
'/////////////////////////////
'/////// MyInterrupt ////////
'/////////////////////////////
DISABLE
MyInterrupt:

waitfor55:
serin portb.0 , n2400 , temp : if temp <> $55 then goto waitfor55

waitforaa:
serin portb.0 , n2400 , temp : if temp <> $aa then goto waitforaa

serin portb.0, n2400, SetRTCTime : serin portb.2, n2400, ViewRTCTime
serin portb.0, n2400, StartTimeHour : serin portb.2, n2400, StopTimeHour
serin portb.0, n2400, StartTimeMin : serin portb.2, n2400,StopTimeMin
serin portb.0, n2400, Year : serin portb.2, n2400, Month
serin portb.0, n2400, Day : serin portb.2, n2400, Hour
serin portb.0, n2400, Minute

If (SetRTCtime = 125) then
I2CWRITE SDApin,SCLpin,$D0,$00,[$00,Minute,Hour,$00,Day,Month,Year,$00] ' Write to DS1307 to initialize a new time
pause 30
Endif

If (ViewRTCTime = 55) then
I2CRead SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCY ear,RTCCtrl]
Pause 30

serout portb.7, n2400, [$55, $55, $55, $55, $aa, SetRTCTime, ViewTime ] 'if 222 then
pause 200

serout portb.7, n2400, [$55,$55,$55,$55,$55,$aa,RTCYear, RTCMonth, RTCDay, RTCHour, RTCMin, RTCSec]
serout portb.7, n2400, [StartTimeHour, StopTimeHour, StartTimeMin, StopTimeMin]
pause 100

Endif


INTCON.1 = 0 ' Enable external Interrupt
RESUME
ENABLE ' Enable Interrupt



The problem now is that the information is not transfering. And this is not a method to get a ACK and verify information transfered.

Charles Linquis
- 13th November 2011, 19:46
I think you are crazy to not use the HARDWARE serial port. That would make things almost trivial. Is there some reason why you aren't using it?

lerameur
- 13th November 2011, 21:54
Its takes three pins from my chip
: Serial Data Out (SDO) RB2/SDO/RX/DT
• Serial Data In (SDI) RB1/SDI/SDA
• Serial Clock (SCK) RB4/SCK/SCL

I am already using SDA and SCL to program and read my RTC. Unless I can use the same pin for both..

aratti
- 13th November 2011, 23:13
Why don't you use I2C also for the communication from pic to pic? Pic 16F88 can operate as slave, so you will give it an address and you will transfer all the data with I2CWRITE and I2CREAD, simpler than that! You can find a working code for I2C slave on the forum, I posted it sometime ago and I don't remember where is burried.

Cheers

Al.

PS. I found it! http://www.picbasic.co.uk/forum/showthread.php?t=10141&highlight=I2C+salve

Charles Linquis
- 14th November 2011, 01:26
When I mentioned hardware serial port, I was referring to TxD and RxD. Then you could use HSEROUT and HSERIN. Connect those two lines together on your PIC, and you can communicate at 9600 baud at least, on the internal oscillators.

lerameur
- 14th November 2011, 02:52
I just want to do a very simple communication at first, then I will work on better one. I am using the same code as i used a few ago for a project on mine. It was working fine at the time. I was using a different compiler and different software.
I am trying to re-use that code. Now I have taken THE code I used and just removed the extra stuff in the programming that is not needed ( calculation from a wireless thermometer) here is my sending code:


INCLUDE "modedefs.bas"
OSCCON = %01110000 '8 Mhz
Define OSC 8

CMCON = 7 : ANSEL = 0 : ADCON1 = 7
'/////////////////////////
'// LCD configuration //
'/////////////////////////

DEFINE LCD_DREG PORTA ' Set LCD Data port
DEFINE LCD_DBIT 0 ' Set starting Data bit (0 or 4) if 4-bit bus
DEFINE LCD_RSREG PORTB ' Set LCD Register Select port
DEFINE LCD_RSBIT 0 ' Set LCD Register Select bit
DEFINE LCD_EREG PORTB ' Set LCD Enable port
DEFINE LCD_EBIT 6 ' Set LCD Enable bit
DEFINE LCD_BITS 4 ' Set LCD bus size (4 or 8 bits)
DEFINE LCD_LINES 2 ' Set number of lines on LCD
DEFINE LCD_COMMANDUS 2500
DEFINE LCD_DATAUS 250
DEFINE CHAR_PACING 2000
pause 500

TRISB = %00000000

count_remain var byte
temperature1 var byte
temperature2 var byte

Mainloop:

temperature1 =11: temperature2 =22
count_remain =44



lcdout $FE,1, "TempC: ", dec (temperature1) , ".", dec2 temperature2," ",$DF,"C"
lcdout $FE,$C0, bin count_remain , ".","F"
pause 400

serout portb.2, n2400,[$55,$55,$55,$55,$aa,temperature1,temperature2,coun t_remain]

lcdout $FE,1 : LCDOUT "second ", dec (temperature2 / 100) , ".", dec2 temperature1," ",$DF,"r"
lcdout $FE,$C0, dec count_remain , ".","23"
pause 400

goto mainloop

end



and here is the receiving code:

INCLUDE "modedefs.bas"
OSCCON = %01110000 '8 Mhz
Define OSC 8

CMCON = 7 : ANSEL = 0 : ADCON1 = 7
'/////////////////////////
'// LCD configuration //
'/////////////////////////

DEFINE LCD_DREG PORTA ' Set LCD Data port
DEFINE LCD_DBIT 0 ' Set starting Data bit (0 or 4) if 4-bit bus
DEFINE LCD_RSREG PORTB ' Set LCD Register Select port
DEFINE LCD_RSBIT 0 ' Set LCD Register Select bit
DEFINE LCD_EREG PORTB ' Set LCD Enable port
DEFINE LCD_EBIT 6 ' Set LCD Enable bit
DEFINE LCD_BITS 4 ' Set LCD bus size (4 or 8 bits)
DEFINE LCD_LINES 2 ' Set number of lines on LCD
DEFINE LCD_COMMANDUS 2500
DEFINE LCD_DATAUS 250
DEFINE CHAR_PACING 2000
pause 500

ADCON1 = %00100010

encoded11 var word : encoded22 var word : encoded33 var word : encoded44 var word : encoded4 var byte
count_remain var byte :temp var byte


TRISA = %00000001 ' Set PORTA to all output
TRISB = %00001111


Mainloop:
'23

lcdout $FE,1 , "hello ", dec 105," ","C"
lcdout $FE,$C0, "before"
pause 300

waitfor55:
serin portb.2 , n2400 , temp : if temp <> $55 then goto waitfor55

waitforaa:
serin portb.2 , n2400 , temp : if temp <> $aa then goto waitforaa

serin portb.2, n2400, encoded11.HighBYTE : serin portb.2, n2400, encoded11.LowBYTE
serin portb.2, n2400, encoded22.HighBYTE


lcdout $FE,1, "encoded11.HighBYTE", dec encoded11.HighBYTE , ".", dec2 encoded11.LowBYTE
lcdout $FE,$C0, "TempF: ", "-", dec encoded22.HighBYTE , "After"
Pause 300


goto Mainloop

end




the sending code seems to work. but the receiving code seems to be stuck on the first LCDOUT, I guess it does not see the 55 or aa...

k

Charles Linquis
- 14th November 2011, 03:16
That is why you need to use the hardware serial port! If you use SERINx you have to sit and wait for the first transition of the start bit of the first char to come in. If you use HSERIN instead, you could simply test for PIR1.5 (at least that is what it is in the 18Fs). It gets set AFTER the whole byte is received, so in just a few instructions, you can tell if the first byte came in. If that bit isn't set, move on. If it is set, then you know there is a char in the receive buffer, so then you can issue the command HSERIN [dummy]. If Dummy = $55 then you can continue to grab chars. Virtually no overhead, and as long as you give it a
little thought, you don't even need interrupts. It will NEVER lose the first character.

Although I always advocate using interrupts, if you didn't want to mess with them, you could:

Figure out the loop time of your slave device. Then you could do the following:

Main:
GotChars = 0
If PIR1.5 then
Hserin [FirstByte] ;------------ You don't need a timeout here because you already know you have a char
if FirstByte = $55 then
HSERIN 50,NotValid, [STR receivebuffer \numbytes]
GotChars = 1
endif
endif
NotValid:
....rest of program here....

goto main

;------------------------------------------------------------------------------------
And your master -

.....

HSEROUT [$55]

pause (this should equal the length of the slave's program loop + a few mSec)

HSEROUT [whatever you want to send]

.......

lerameur
- 14th November 2011, 03:27
i know what you mean. but why did it work before and now it does not.... i can see from my scope the the same signal is going in the pic.. why the heck doesn't it read it.

K

Charles Linquis
- 14th November 2011, 03:53
Maybe you should try smaller-value pull-up resistors. Although most I2C devices can't sink much current, a PIC can sink 25mA easily. You could use 560 ohm pull-up resistors on each end if you had an extremely noisy environment or long wires.

Also, if your two devices aren't on the same PCB, could there be a difference in GND potential between the two devices?

lerameur
- 14th November 2011, 04:34
and i do have a I have the two breadboards sitting side by side, so maybe 9inch of wire between the two. I added 560ohmpull up resistors but nothing changed from before. and I do have a ground wire between them ..

lerameur
- 14th November 2011, 17:35
WHAT is the best technique to communicatebetween two Pic Chip ??
I2C ? HSEROUT ? .....

Charles Linquis
- 14th November 2011, 23:44
There are so many answers to that question. "Best" is a big word.

While there are lots of options, just quit fighting and use HSEROUT/HSERIN. Easy to use, and has full PBP and DT-INT support. It is a waste of my time to try to convince you of anything. If you choose to use that method I propose, I will give you some pointers, if you don't, you will have to look for help from others.

lerameur
- 15th November 2011, 00:27
I was heading in that direction using HSEROUT, starting reading the pic datasheet communication section and that led me to ask that question. I'll be working on HSEROUT tonight. I think it is a better practice then using serout in a free style way.

lerameur
- 15th November 2011, 01:02
working on it

lerameur
- 15th November 2011, 02:41
STILL NOT TRANSMITTING. as least I am getting any compilation errors..: here is my transmitter code:

(I just see these before word on my LCD)


INCLUDE "modedefs.bas"
OSCCON = 110000 '8 Mhz
Define OSC 8

' Set transmit register to transmitter enabled
DEFINE HSER_TXSTA 20h

' Set baud rate
DEFINE HSER_BAUD 2400

' Set SPBRG directly (normally set by HSER_BAUD)
DEFINE HSER_SPBRG 25

CMCON = 7 : ANSEL = 0 : ADCON1 = 7
'/////////////////////////
'// LCD configuration //
'/////////////////////////

DEFINE LCD_DREG PORTA ' Set LCD Data port
DEFINE LCD_DBIT 0 ' Set starting Data bit (0 or 4) if 4-bit bus
DEFINE LCD_RSREG PORTB ' Set LCD Register Select port
DEFINE LCD_RSBIT 0 ' Set LCD Register Select bit
DEFINE LCD_EREG PORTB ' Set LCD Enable port
DEFINE LCD_EBIT 6 ' Set LCD Enable bit
DEFINE LCD_BITS 4 ' Set LCD bus size (4 or 8 bits)
DEFINE LCD_LINES 2 ' Set number of lines on LCD
DEFINE LCD_COMMANDUS 2500
DEFINE LCD_DATAUS 250
DEFINE CHAR_PACING 2000
pause 500

cou var byte
temp1 var byte
temp2 var byte

Mainloop:

temp1 =18: temp2 =22
cou =44


lcdout $FE,1, "TempC: ", dec (temp1) , ".", dec2 temp2," ",$DF,"C"
lcdout $FE,$C0, bin cou , ".","F"
pause 400

Hserout [DEC temp1]
PAUSE 50

lcdout $FE,1 : LCDOUT "second ", dec (temp2 / 100) , ".", dec2 temp1," ",$DF,"r"
lcdout $FE,$C0, dec cou , ".","23"
pause 400

goto mainloop

end




and my receiver code

INCLUDE "modedefs.bas"
OSCCON = 110000 '8 Mhz
Define OSC 8

' Set receive register to receiver enabled
DEFINE HSER_RCSTA 90h

' Set baud rate
DEFINE HSER_BAUD 2400

' Set SPBRG directly (normally set by HSER_BAUD)
DEFINE HSER_SPBRG 25


CMCON = 7 : ANSEL = 0 : ADCON1 = 7
'/////////////////////////
'// LCD configuration //
'/////////////////////////

DEFINE LCD_DREG PORTA ' Set LCD Data port
DEFINE LCD_DBIT 0 ' Set starting Data bit (0 or 4) if 4-bit bus
DEFINE LCD_RSREG PORTB ' Set LCD Register Select port
DEFINE LCD_RSBIT 0 ' Set LCD Register Select bit
DEFINE LCD_EREG PORTB ' Set LCD Enable port
DEFINE LCD_EBIT 6 ' Set LCD Enable bit
DEFINE LCD_BITS 4 ' Set LCD bus size (4 or 8 bits)
DEFINE LCD_LINES 2 ' Set number of lines on LCD
DEFINE LCD_COMMANDUS 2500
DEFINE LCD_DATAUS 250
DEFINE CHAR_PACING 2000
pause 500

encoded22 var word


Mainloop:


lcdout $FE,1 , "hello "
lcdout $FE,$C0, "before"
pause 300

Hserin [DEC encoded22]
PAUSE 100

lcdout $FE,1, "after"
lcdout $FE,$C0, "AFTER: ", "-", dec encoded22 , "After"
Pause 300


goto Mainloop

end

mackrackit
- 15th November 2011, 03:10
How are the two chips connected?

chip#1 ground to chip#2 ground
chip#1 TX to chip #2 RX
???

lerameur
- 15th November 2011, 03:18
YES THE CHIPs has a common ground. RB5 is going to the receiving pic on RB2 (PIC16F88)

ken

mackrackit
- 15th November 2011, 03:55
Try these settings on both the Tx and RX chip


DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 0
DEFINE HSER_SPBRG 51 ' 2400 Baud @ 8MHz, 0.17%
DEFINE HSER_CLROERR 1 ' Clear overflow automatically

lerameur
- 15th November 2011, 05:38
just copied and paste your code and still did not work. Same as before.....

ken

Charles Linquis
- 15th November 2011, 13:19
Do you have your TX pin set for output (TRIS = 0)?

lerameur
- 15th November 2011, 13:36
i ADDed this after I sent the code yesterday.:
TRISB = %00000000
AND

the other pic:
TRISB =%11111111

could it be in the include file?
K

mackrackit
- 15th November 2011, 13:43
If you are talking about "modedefs.inc" no. You do not need that file for what you are doing so it is not doing any harm. It is for SERIN/SEROUT and a couple other commands.

Have you tried sending/receiving to a PC?

lerameur
- 15th November 2011, 15:25
nO DID NOT SEND TO pc. Actually never done that in my life....

Charles Linquis
- 15th November 2011, 19:06
If you are using the hardware serial port (as I suggest), then the polarity will be wrong for a direct connection to a PC, so that won't work.

If you issue HSEROUT [...] and the port doesn't even toggle, then you have some other problem.

lerameur
- 15th November 2011, 22:40
I can some steady activity on the HSEROUT port. Seems to me the receiving end is a problem. I used another picF88 chip in case it would be a hardwire pin problem, but still the LCD is not showing the input. I removed the First LCDOUT and juste the one after the HSERIN and the L:CD is showing blank...

Charles Linquis
- 16th November 2011, 01:47
Are you using HSERIN for the receive side?

Just do this -

LCDOUT $FE,$1

Topp:

HSERIN [X]
LCDOUT X

Goto Topp

lerameur
- 16th November 2011, 02:12
this is what I have now. the tiny rail of the breadboard seems to be defective, although I tested it with my multimeter and it seems to be conducting, but then if I put the wire from the transmitting pic directly to the receiving chip leg then I could see something on the LCD. that fixed. I am sending 5 or 22 or 85 from the TX pic and I am always receiving 49 on the RX chip....
Mainloop:

Pause 50


Hserin [encoded22]
PAUSE 100

lcdout $FE,1, "input ", bin encoded22
pause 200


goto Mainloop

end

lerameur
- 17th November 2011, 02:44
I removed the defines commands for HSERIN, ans used the serout command. It WORKS !!!. But i would like to make the HSEROUT AND HSERIN command works. I still get the number 48 or 49 showing up. sometimes after a minute or so the LCD shows some erratic behaviour, showing a lot oo???oo?? on both of the line.....
any ideas?

k

lerameur
- 18th November 2011, 23:16
i CHANGES BREADBOARD, USED BRAND NEW CHIPS, STILL i AM GETTING 49 IN THE RECEIVING PIC................ANY IDEAS ???? OUPS CAPS LOCK...

Ken