|
|
View previous topic :: View next topic |
Author |
Message |
Bob Sorenson Guest
|
printf/putc problem with 16f873 |
Posted: Thu May 15, 2003 2:37 pm |
|
|
I solved the problems I was having using printf and the RS-485
chip. A while back we wanted to use the Receive Enable (RE) pin
on the MAX-487 and control it with C1 from the PIC. The idea
was to monitor the signal that appeared on the bus and compare
it to what was sent. If the two strings did not match then a
collision had occurred and the packet needed to be re-sent. This
was a thought for the future and was never implemented. If any-
one knows how to do this, please let me know. (We have several
PICs that need to talk with a host control computer and need the
RS-485 bus capabilities.)
The code that caused it to work is below. However, another problem has cropped up, and it may be related to the "fix" I used.
The code in the section THIS_WORKS does, but the code in the
#else section does not; nothing is printed on the terminal,
except as noted. I seem to remember seeing this way of printing
in another post, but perhaps the fact that it does not work for
me is related to what I am doing with the C1 output and the
delay needed for the MAX-487 chip.
Another oddity: Instead of printing 1.234 for the voltage, it
prints 1.233999.
I am using version 3.154 of the compiler and have not seen any
printf-related changes in newer versions.
______________________________________________________________
#include <16F873.H>
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, NOLVP, PUT
#use delay(clock = 14745600)
#use rs232(baud = 115200, xmit = PIN_C6, rcv = PIN_C7, enable = PIN_C2, PARITY = N, BITS = 8, ERRORS)
#define C1_DELAY_MS 1 // mS after toggling pin C1 for transmit.
#define MAX_BUFFER_SIZE 32
#define THIS_WORKS
#ifdef THIS_WORKS
void send_buffer(char *buffer)
{
int idx;
output_high(PIN_C1);
delay_ms(C1_DELAY_MS);
for (idx = 0; buffer[idx]; idx++) {
putc(buffer[idx]);
}
output_low(PIN_C1);
}
#else // This does NOT work!!!
void send_buffer(char *buffer)
{
output_high(PIN_C1);
delay_ms(C1_DELAY_MS);
printf(buffer);
//printf("\%s", buffer); // Does NOT work either!
//printf("String: \%s", buffer); // Just prints "String: "!
output_low(PIN_C1);
}
#endif
void main()
{
char buffer[MAX_BUFFER_SIZE];
enable_interrupts(GLOBAL);
set_tris_c(0x86);
sprintf(buffer, "\%s\r", "Program started...");
send_buffer(buffer);
sprintf(buffer, "\%s: \%f\r", "Voltage", 1.234);
send_buffer(buffer);
sprintf(buffer, "\%s\r", "Program ended...");
send_buffer(buffer);
while(TRUE); // Keep PIC from entering SLEEP mode.
}
___________________________
This message was ported from CCS's old forum
Original Post ID: 144514496 |
|
|
Pete Smith Guest
|
Re: printf/putc problem with 16f873 |
Posted: Fri May 16, 2003 8:08 am |
|
|
:=I solved the problems I was having using printf and the RS-485
:=chip. A while back we wanted to use the Receive Enable (RE) pin
:=on the MAX-487 and control it with C1 from the PIC. The idea
:=was to monitor the signal that appeared on the bus and compare
:=it to what was sent. If the two strings did not match then a
:=collision had occurred and the packet needed to be re-sent. This
:=was a thought for the future and was never implemented. If any-
:=one knows how to do this, please let me know. (We have several
:=PICs that need to talk with a host control computer and need the
:=RS-485 bus capabilities.)
:=
:=The code that caused it to work is below. However, another problem has cropped up, and it may be related to the "fix" I used.
:=
:=The code in the section THIS_WORKS does, but the code in the
:=#else section does not; nothing is printed on the terminal,
:=except as noted. I seem to remember seeing this way of printing
:=in another post, but perhaps the fact that it does not work for
:=me is related to what I am doing with the C1 output and the
:=delay needed for the MAX-487 chip.
:=
:=Another oddity: Instead of printing 1.234 for the voltage, it
:=prints 1.233999.
This is a common problem, to do with the way that the numbers are stored, and will happen with most/all systems. 1.234 can't be stored exactly as 1.234, so corners are cut (so to speak)
As to your other problem : I've never got \%s to work under CCS C, so I normally (if I'm using strings like that) just use puts() (this may not work for you, because it puts a LF or CR at the end).
HTH
Pete.
___________________________
This message was ported from CCS's old forum
Original Post ID: 144514507 |
|
|
R.J.Hamlett Guest
|
Re: printf/putc problem with 16f873 |
Posted: Sun May 18, 2003 6:56 am |
|
|
:=I solved the problems I was having using printf and the RS-485
:=chip. A while back we wanted to use the Receive Enable (RE) pin
:=on the MAX-487 and control it with C1 from the PIC. The idea
:=was to monitor the signal that appeared on the bus and compare
:=it to what was sent. If the two strings did not match then a
:=collision had occurred and the packet needed to be re-sent. This
:=was a thought for the future and was never implemented. If any-
:=one knows how to do this, please let me know. (We have several
:=PICs that need to talk with a host control computer and need the
:=RS-485 bus capabilities.)
:=
:=The code that caused it to work is below. However, another problem has cropped up, and it may be related to the "fix" I used.
:=
:=The code in the section THIS_WORKS does, but the code in the
:=#else section does not; nothing is printed on the terminal,
:=except as noted. I seem to remember seeing this way of printing
:=in another post, but perhaps the fact that it does not work for
:=me is related to what I am doing with the C1 output and the
:=delay needed for the MAX-487 chip.
:=
:=Another oddity: Instead of printing 1.234 for the voltage, it
:=prints 1.233999.
This will happen, even on a PC!...
The problem is that the normal 'floating point' format, is _not_ an accurate way to store numbers. The format used on the PIC, has 23bits of accuracy (just over 6 1/2 digits), and to this level of accuracy, 1.233999 = 1.234. This is the reason why people needing absolute guarantees that a particular number will not display this type of error, use other numberic formats (for instance in VB, there is a 'currency' type, which uses a scaled integer). Now you can limit the result to just three digits, by using a 'width' limiter on the \%f printout (perhaps something like \%5.3f). The individual bits in the mantissa of the number, correspond to '1', then '0.5', then '0.25', then '0.125' etc., Hence the nearest value that can be acheived, is 1+0.125+0.0625+0.03125 etc.. With some numbers, the result will be perfect (for instance, 1.125), but numbers that are not conventiently constructed from binary multipliers, will end up with errors...
If you want accuracy over a particular range, use a scaled integer instead (which is also generally faster), but otherwise you must bear in mind the limits of standard floating point encoding.
Best Wishes
:=I am using version 3.154 of the compiler and have not seen any
:=printf-related changes in newer versions.
:=______________________________________________________________
:=
:=#include <16F873.H>
:=
:=#fuses HS, NOWDT, NOPROTECT, BROWNOUT, NOLVP, PUT
:=
:=#use delay(clock = 14745600)
:=#use rs232(baud = 115200, xmit = PIN_C6, rcv = PIN_C7, enable = PIN_C2, PARITY = N, BITS = 8, ERRORS)
:=
:=#define C1_DELAY_MS 1 // mS after toggling pin C1 for transmit.
:=
:=#define MAX_BUFFER_SIZE 32
:=
:=#define THIS_WORKS
:=
:=#ifdef THIS_WORKS
:=void send_buffer(char *buffer)
:={
:= int idx;
:=
:= output_high(PIN_C1);
:= delay_ms(C1_DELAY_MS);
:= for (idx = 0; buffer[idx]; idx++) {
:= putc(buffer[idx]);
:= }
:= output_low(PIN_C1);
:=}
:=#else // This does NOT work!!!
:=void send_buffer(char *buffer)
:={
:= output_high(PIN_C1);
:= delay_ms(C1_DELAY_MS);
:= printf(buffer);
:= //printf("\%s", buffer); // Does NOT work either!
:= //printf("String: \%s", buffer); // Just prints "String: "!
:= output_low(PIN_C1);
:=}
:=#endif
:=
:=void main()
:={
:= char buffer[MAX_BUFFER_SIZE];
:=
:= enable_interrupts(GLOBAL);
:= set_tris_c(0x86);
:=
:= sprintf(buffer, "\%s\r", "Program started...");
:= send_buffer(buffer);
:=
:= sprintf(buffer, "\%s: \%f\r", "Voltage", 1.234);
:= send_buffer(buffer);
:=
:= sprintf(buffer, "\%s\r", "Program ended...");
:= send_buffer(buffer);
:=
:= while(TRUE); // Keep PIC from entering SLEEP mode.
:=}
___________________________
This message was ported from CCS's old forum
Original Post ID: 144514529 |
|
|
|
|
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
|