CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Please help: printf

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Einly



Joined: 10 Sep 2003
Posts: 60

View user's profile Send private message Send e-mail Yahoo Messenger MSN Messenger ICQ Number

Please help: printf
PostPosted: Sun Oct 26, 2003 8:56 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Oct 27, 2003 5:47 am     Reply with quote

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
PostPosted: Mon Oct 27, 2003 6:58 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Oct 27, 2003 8:51 pm     Reply with quote

With a 3.686MHz crystal you can achieve up to 230.4Kbaud with 0% error (BRGH=1,SPBRG=0). That should be enough!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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