|
|
View previous topic :: View next topic |
Author |
Message |
Einly
Joined: 10 Sep 2003 Posts: 60
|
Please help: printf |
Posted: Sun Oct 26, 2003 8:56 pm |
|
|
Dear all,
I wish to send data from PIC16f876 to a PC using serial communication.
Below is my code:
#include <16f876.h>
#fuses hs,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use RS232(baud=9600, x_mit=PIN_C6, rcv=PIN_C7)
#byte PORTA=5
#byte PORTB=6
#byte PORTC=7
void main()
{
int i;
int buffer[64];
for(i=0;i<64;i++)
{
printf("%u\n\r",buffer[i]);
//Assume that I got my buffer from the adc
}
}
1)
Now, I would like to send long data to the PC, which is 16 bit, consists of both positive & negative number (in 2's complement format). May I know how should I do that? Is it:
#include <16f876.h>
#fuses hs,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use RS232(baud=9600, x_mit=PIN_C6, rcv=PIN_C7)
#byte PORTA=5
#byte PORTB=6
#byte PORTC=7
void main()
{
int i;
long int buffer[64];
for(i=0;i<64;i++)
{
printf("%ld\n\r",buffer[i]);
//Assume that I got my buffer from the adc
}
}
2)
At the computer, is it possible for me to receive 16 bit data? Or is it onle possible to receive data in bytes (8 bits)?
3)
If it is possible, may I know can anyone give me an example of program (either written in C or Visual C or Visual Basic) how to achieve this?
4) What is the difference between hardware UART & software UART? Any examples?
5) baud=9600 depends on what? What is the maximum that I can achieve?
Thanks a lot
Yours truly,
Einly _________________ Einly |
|
|
TSchultz
Joined: 08 Sep 2003 Posts: 66 Location: Toronto, Canada
|
|
Posted: Mon Oct 27, 2003 5:47 am |
|
|
It is possible to send your data between the PIC and a PC. Having said that you have a few choices; send data as ASCII charcter representation of number, send data as straight binary, send data as converted binary. If you choose to use binary you must remember that the internal byte ordering of the Intel PC and the PIC are different (little endian vs big endian).
To make things the most efficient I normally choose to send data as a straight binary packed string and do the conversions on the PC side using Visual Basic or C. C is the most straight forward as it can handle unsigned vars and has bit manipulation, and has variable type casting, VB is a bit more involved but with the help of a simple API call you can acheive a similiar result to type casting.
Assuming you have the following;
long Readings[12];
Just send all the bytes to the PC unformatted using putc for each byte. Then on the PC side (in VB);
Dim Readings(12) as long
Receive your data stream either as a string(has good string handling cmds) or byte array (no unicode issues) and copy the bytes directly to the Readings array using either CopyMemoryFromString or CopyMemory depending on if you used a string for the data buffer. You can then correct the byte alignments for each array element as follows;
for i = 0 to 11
Readings(i) = SwapInteger(i)
next i
You now have the array of longs from the PIC in VB all ready for use.
This is one way, but it is the most efficient way to handle things. I normally use a structure with mixed variable types this way. If you choose to do this you must keep in mind how the PC will store the structure in memory. 32 bit VB will keep everything on 4 byte boundaries and this will determine the optimum byte organization for the PIC.
This is a start for you. I have not given you everything but this is a very good start. If you have problems fell free to ask away, I have to go now and get some work done.
Here are the VB6 helper routines I use (I think they are the most recent version);
<pre>
'***********************************************************************
' Description: Helper routines for binary data passing Intel PC to PIC
' Author: Troy Schultz
' Date: January 2000
' Language: Visual Basic 6
'***********************************************************************
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal BytesToCopy As Long)
Public Declare Sub CopyFromString Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, ByVal lpSource As String, ByVal BytesToCopy As Long)
Public Declare Sub CopyToString Lib "kernel32" Alias "RtlMoveMemory" (ByVal lpDest As String, lpSource As Any, ByVal BytesToCopy As Long)
Public Function CheckBit(word As Long, bit As Integer) As Boolean
CheckBit = (word And (2 ^ bit)) >= (2 ^ bit)
End Function
Public Function BitSet(word As Long, bit As Integer) As Long
BitSet = word Or (2 ^ bit)
End Function
Public Function BitClr(word As Long, bit As Integer) As Long
If CheckBit(word, bit) Then
BitClr = word - (2 ^ bit)
Else
BitClr = word
End If
End Function
Public Function SwapInteger(num As Integer) As Integer
'Integer is 16 bit signed variable
Dim b(2) As Byte
Dim I As Byte
Dim n As Integer
CopyMemory b(0), num, 2
I = b(0): b(0) = b(1): b(1) = I
CopyMemory n, b(0), 2
SwapInteger = n
End Function
Public Function SwapLong(num As Long) As Long
'Long is 32 bit signed variable
Dim b(4) As Byte
Dim I As Byte
Dim n As Long
CopyMemory b(0), num, 4
I = b(0): b(0) = b(4): b(4) = I
I = b(1): b(1) = b(2): b(2) = I
CopyMemory n, b(0), 4
SwapLong = n
End Function
Public Function FloatIntelIEEEtoPIC(num As Single) As Single
'IEEE to PIC floating point conversion
' RLF MSB ;move most significant bit to carry
' RLF EXP ;put bit at top of EXP and get sign bit in carry
' RRF MSB ;move sign bit into MSB
'
'Note: Intel has bytes in reverse order compared to PIC, bits in each byte are
' correctly ordered.
Dim b(4) As Byte
Dim sign As Byte
Dim carry As Byte
Dim I As Byte
Dim n As Single
'Get each byte of the floating point number
CopyMemory b(0), num, LenB(num)
'Reverse byte order for EXP, MSB, ..., LSB (Intel is oposite PIC)
I = b(0): b(0) = b(3): b(3) = I
I = b(1): b(1) = b(2): b(2) = I
sign = Abs((b(0) And 128) >= 128) 'get sign bit
carry = Abs((b(1) And 128) >= 128) 'get highest bit from MSB
b(0) = ((b(0) And 127) * 2) + carry 'rotate EXP left and add carry bit
b(1) = (b(1) And 127) + (128 * sign) 'sign bit if highest bit of MSB
'Put each byte in a floating point variable
CopyMemory n, b(0), LenB(num)
'Return the variable
FloatIntelIEEEtoPIC = n
End Function
Public Function FloatPICtoIntelIEEE(num As Single) As Single
'IEEE to PIC floating point conversion
' RLF MSB ;move sign bit to carry
' RRF EXP ;put sign at top of EXP and get most significant bit in carry
' RRF MSB ;move most significant bit into MSB
'
'Note: Intel has bytes in reverse order compared to PIC, bits in each byte are
' correctly ordered.
Dim b(4) As Byte
Dim sign As Byte
Dim carry As Byte
Dim I As Byte
Dim n As Single
'Get each byte of the floating point number
CopyMemory b(0), num, LenB(num)
sign = Abs((b(1) And 128) >= 128) 'get sign bit
carry = b(0) And 1 'get lowest bit from EXP
b(0) = ((b(0) And 254) \ 2) + (sign * 128) 'rotate EXP right and add sign bit
b(1) = ((b(1) And 127)) + (carry * 128) 'put highest bit of MSB
'Reverse byte order for LSB, ..., MSB, EXP (Intel is oposite PIC)
I = b(0): b(0) = b(3): b(3) = I
I = b(1): b(1) = b(2): b(2) = I
'Put each byte in a floating point variable
CopyMemory n, b(0), LenB(num)
'Return the variable
FloatPICtoIntelIEEE = n
End Function
</pre> |
|
|
david smith Guest
|
Re: Please help: printf |
Posted: Mon Oct 27, 2003 6:58 pm |
|
|
4) What is the difference between hardware UART & software UART?
5) baud=9600 depends on what?
A HW UART is circuitry in the chip to pass the bytes supplied to the serial port, with all the serializing of bits handled without the processor doing anything. Conversely, a SW UART is a subroutine that receives the byte, and sends 1 bit at a time to an I/O pin with the requisite timing, parity, etc.
SW UART: disadvantages: much slower, doesn't work well for receiving in some cases. advantage, any pins can be assigned to Rx Tx, inverted-True is available.
HW UART, disadvantage: dedicated pins ONLY (see device) No invert. Advantage: works. higher rates possible. Recommended. (Learned on this forum!)
Someone else may be able to comment on maximum speed; it does depend on xtal.
I've used 9600 for both at 4MHz and 20MHz. |
|
|
Haplo
Joined: 06 Sep 2003 Posts: 659 Location: Sydney, Australia
|
|
Posted: Mon Oct 27, 2003 8:51 pm |
|
|
With a 3.686MHz crystal you can achieve up to 230.4Kbaud with 0% error (BRGH=1,SPBRG=0). That should be enough! |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|