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 CCS Technical Support

problem with 16f877a and RS232

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



Joined: 16 Oct 2010
Posts: 20

View user's profile Send private message

problem with 16f877a and RS232
PostPosted: Sat Nov 27, 2010 6:14 am     Reply with quote

Hello

This is my code to convert analog voltage to digital and send it via RS232 cable

Code:

#INCLUDE <16F877A.h>
#device adc=10
#fuses HS,NOWDT,NOPROTECT,NOLVP
#USE DELAY (CLOCK=10000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
void main()
{
unsigned int16 adc_value;
setup_adc(ADC_CLOCK_DIV_16);
setup_adc_ports(ANALOG_RA3_REF);
set_adc_channel(0);
delay_us(20);
while(1)
{
adc_value=read_adc();
printf("%lu",adc_value);
delay_ms(500);
output_d(adc_value);
}
}



As you see, I output 8 bits of the converted 10 bits on PORTD to check the it converts correctly.

When I ran simulation and input was 3V I get this:



3V should be converted to 1001100110
and that's correct on Leds connected to PORTD (first 8 bits are correct)

The problem is on printf function. I don't get the expected value on the oscilloscope.
What is the problem here?!
Can someone tell me how printf works? It send extra bits or flags?
I should get 16 bits as follow: 000000 1001100110
or: 1001100110 000000

Another question, how can i make pin RA0 only analog and RA3 as VREF?
I tried setup_adc_ports(AN0_RA3_REF); but it didn't work

last question, Is there a method to send only 10 bits of adc_value and not to send all the 16 bits?

Thanks in advance
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Nov 27, 2010 6:40 am     Reply with quote

Hmm..
last question first.
Yes, you can send only the 10 bits of the ADC result , if you want.
Simply create a bit-banged (software) UART.Old school, yet I do it all the time,it's a great security feature! .Be aware that while you're bit-banging, that all else stops(except any enabled interrupts, which will kill your SW UART!)Sending 10 bits is faster than sending 16 bits ....

...However, if you're sending this data to a PC or other 'standard RS-232' device, you'll want to send both bytes.The 'other' end won't understand your 10 bit RS-232 datastream and you'll get errors.

So unless you're designing the other end, stick with the 'standard' of sending regular 8bit data.

second question second.
Consult the PIC datasheet and the PICdotH file from CCS for the different modes that the pins can be configured for Analog inputs . It varys between PICs.Both places will tell you what you need to know.

first question last.
'Normal' UART / RS-232 communication is 8 bits.The USE RS232(..) you have is set for this by default.When you try to send 10 bits, the top 2 or bottom 2 bits will be 'lost' either by the printf(...) or use rs232(...) functions.Not sure which, dump a listing to follow the code.

hope this helps.
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Sat Nov 27, 2010 7:58 am     Reply with quote

As setup, printf, is sending the value as _text_. So your ten bit value, represents a number from 0 to 1023. So for 1001100110, which is 266 in decimal, the printf will send the text character '2', followed by '6', and '6'.
Now, as explained, if is very hard to handle word lengths when talking to other 'kit', outside the range typically of 5 to 9 bits. Also remember that standard 'async serial' (which is what the UART sends), has a leading '0' bit, and a trailing '1' bit added.

You have three basic choices:
1) Define your own protocol, bit bang the data - only useable if you are also in complete control of the hardware at the other end.
2) Send just the bit patterns as two bytes with start and stop bits, without changing the data to ASCII:
Code:

printf("%c%c", make8(adc_value,1), make8(adc_value,0));

3) Best way possibly is to send the value as hex, since this then involves transmitting just three bytes, and wil not use any of the ASCII control characters, allowing you to use CR or LF to mark the 'end' of the data.
Code:

printf("%03lx", adc_value);


Best Wishes
doryme



Joined: 16 Oct 2010
Posts: 20

View user's profile Send private message

PostPosted: Sat Nov 27, 2010 10:51 am     Reply with quote

Hello
Thank you for your help.
I tried the 3rd choice and got this..I expect to get 101110000



what are CR and LF that i use to mark data? and can I make them anything I want?
I see 3 ones on oscilloscope and some zeros but still can't define my 101110000

Thanks
doryme



Joined: 16 Oct 2010
Posts: 20

View user's profile Send private message

PostPosted: Sat Nov 27, 2010 10:54 am     Reply with quote

temtronic wrote:
Hmm..
last question first.
Yes, you can send only the 10 bits of the ADC result , if you want.
Simply create a bit-banged (software) UART.Old school, yet I do it all the time,it's a great security feature! .Be aware that while you're bit-banging, that all else stops(except any enabled interrupts, which will kill your SW UART!)Sending 10 bits is faster than sending 16 bits ....

...However, if you're sending this data to a PC or other 'standard RS-232' device, you'll want to send both bytes.The 'other' end won't understand your 10 bit RS-232 datastream and you'll get errors.

So unless you're designing the other end, stick with the 'standard' of sending regular 8bit data.

second question second.
Consult the PIC datasheet and the PICdotH file from CCS for the different modes that the pins can be configured for Analog inputs . It varys between PICs.Both places will tell you what you need to know.

first question last.
'Normal' UART / RS-232 communication is 8 bits.The USE RS232(..) you have is set for this by default.When you try to send 10 bits, the top 2 or bottom 2 bits will be 'lost' either by the printf(...) or use rs232(...) functions.Not sure which, dump a listing to follow the code.

hope this helps.



Yes I will send these bits to PC so I have to send the 16 bits:S
Thanks alot for your help
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