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

Interfacing Technique

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







Interfacing Technique
PostPosted: Thu Aug 04, 2005 12:28 am     Reply with quote

Hi,

Most of the time, when i want to interface the PIC with another IC, such as LCD IC, I send the clk pulse each time aft i set all other PINs in proper condition (high or low).

output_high(PIN_D1);
output_low(PIN_D2);
.
.
.
output_high(LCD_CLK);
output_low(LCD_CLK);

This technique is for those ICs take CLK signal from PIC.
However, for IC that required its own XTAL or shares XTAL with PIC,
what is the interfacing technique required?

Do we have to calculate the delay all the time between PIC and IC?
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Aug 04, 2005 1:40 am     Reply with quote

The kind of communications that uses a clock signal is known in literature as 'synchronous communications' the other type without a seperate clock signal is called 'asynchronous communications'.

Examples of synchronous communications are SPI and I2C.
Asynchronous examples are most wireless protocols (ethernet, wifi, bluetooth) and the RS232 as used in PC's (there exists also a synchronous RS232 but this is rarely used).

Asynchronous communication (without the extra clock wire) can be implemented in several ways:
1) Sample the databits in the middle of the bittime. This requires the clock in both systems to be stable and synchronized. For example RS232 uses a fixed start- and stopbit for every byte to keep the receiver synchronized and only a 4% error in sampling frequency is allowed.
2) A clock signal is hidden in the data stream. For example Manchester encoded data gives a clock pulse for every data bit at the cost of half the bandwidth.
Kit
Guest







PostPosted: Thu Aug 04, 2005 2:26 am     Reply with quote

Thanks.

I am dealing with a Async Transmission now.
Normally when I need RS232 connection, I use the built-in #use RS232 function, so I have no idea what's happening at the background.

Where can i obtain a RS232 function written in PIC-C ( not using the built-in #use rs232)? I want to study the flow of the function.


Thanks
Kit
Guest







PostPosted: Thu Aug 04, 2005 2:27 am     Reply with quote

Thanks.

I am dealing with a Async Transmission now.
Normally when I need RS232 connection, I use the built-in #use RS232 function, so I have no idea what's happening at the background.

Where can i obtain a RS232 function written in PIC-C ( not using the built-in #use rs232)? I want to study the flow of the function.


Thanks
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Aug 04, 2005 2:03 pm     Reply with quote

If you do not want to use a hardware UART then you need a piece of software that is often reffered to as bit-banging. These routines are often written in assembly because of the tight timing requirements which are more difficult to control from C.

Can you be a bit more specific with your questions? Do you want to learn about asynchronous communications methods in general or do you have a specific project in mind?
Kit
Guest







PostPosted: Thu Aug 04, 2005 7:59 pm     Reply with quote

Thanks for your reply.

Actually I am trying to interface with smart card using one io pin. the transmission protocol is using Asynchronous.

I guess if i learn to code rs232, it might help me to code for the smart card protocol.

I try not to use "#use rs232" because it is for rs232 communication, i don't know how it works. Or perhaps I can use it, by changing the parameter?

for the moment, software uart is prefered, because i can port the code to other PIC model. But i wish to use C language, because, to be honest, I am not that good in Assembly.

If there is no way to write software uart in C, then i will use hardware uart. but still, the only example that i came across is also using "#use rs232" statement.
Ttelmah
Guest







PostPosted: Fri Aug 05, 2005 2:21 am     Reply with quote

#use RS232, uses the hardware UART(s), if you use it with the pins with this hardware, or automatically generates the software UART, if you use another pin.
At heart, asynchronous comms, are relatively 'simple'. The default behaviour, is that the output line 'idles' high. Then when a character is to be sent, the 'start' is signalled by dropping the line for one bit time (this time is the 'bps' setting). This is the 'start' bit. This is then followed by the bits from the data character, with one 'bit time' for each bit. The LSB is sent first. A '1' is sent as a logic 'high' on the output line, and a '0', as a logic low. This is repeated for the number of bits in the character. If parity is enabled, an extra bit is then inserted to make the total number of bits either even or odd. The line is then raised, and held for the 'stop bit'. The controls in the use RS232 instruction, allow you to specify the number of bits to send 'BITS=', the rate the bits are sent 'BAUD=' & whether a parity bit is generated 'PARITY='. There is also a control to reverse the logic (line then idles low, and the data bits are all inverted) 'INVERT', and to not actually 'drive' the line high, but assume there is a pull-up resistor driving the line 'FLOAT_HIGH'. this allows multiple chips to drive a single line (something that RS232 does not itself support).
The #use RS232 nomenclature is really somwhat confusing. The command produces a standard serial stream, which can then be sent using RS232 (RS232 is really a _signaling_ voltage standard, which the chip cannot develop - this is why a MAX232 or simlar transceiver is needed for 'RS232'). The same serial stream, can equally well be sent using RS485, or direct logic connections for short distances. It would really be more logical if the instruction was called 'use asynch', or something similar.
The software RS232 then is very simple, just involving moving the line to the levels required for each bit, and then holding the line at that level for the required time. The timings are done using the 'use delay' instruction, so are affected if any interrupt occurs during the character.
On reception, the standard is to wait for the falling edge, then delay for 1.5 bit times (so you are in the 'middle' of the bit), and then sample at bit time intervals to regenerate the character. More sophisticated algorithms will sample at multiple 'points' in the bit, to improve data recovery. In terms of timing then, the [spam] accuracy at each end, must be 'close enough', that the sample point all fall inside the correct bit, even at the end of the character. If things were perfect (logic switched instantly etc.), and the sample point was in the dead centre of the character, then with 10 bit times (start, 8data bits, parity), an error of 5% (half a character time/10), would cause problems. Normally given the different sampling algorithms, 4% is used as the maximum that is probably 'safe'.

Best Wishes
Guest








PostPosted: Fri Aug 05, 2005 3:27 am     Reply with quote

Hi,

I need help to code Asynchronous Transmission Protocol in CCS-C.

I am using one IO pin. So I cann't use "#use rs232" (which use one XMIT and one RCV pin).

Someone told me ppl usually use ASM to code Async protocol, instead of C, because of tight timing.

1. How to code it using C? I know it's possible, but I dont know how to calculate the delay and timing.

for example, the bit delay is 104 us.
However, besides the 104 us, the for loop it self creates delay, shift_left creates delay, and every instruction also cause delay.

Calculate those delay could take up some efford.
Code:

#define  BIT_DELAY   104;

void RS232_xmit(BYTE data)
{
   int i;

   output_low(RS232_XMIT);
   delay_us(BIT_DELAY);
   for (i = 8; i != 0; i--)
   {
      output_bit(RS232_XMIT, shift_left(&data, 1, 0));
      delay_us(BIT_DELAY);
   }
   output_high(RS232_XMIT);
      delay_us(BIT_DELAY);
}


2. If i have to use ASM, i will tend to use #ASM which mix with C code. The problem is, It might mess up my code, because C and ASM may use the same memory location, and I don't know in advance where C will use to store data.

I only take RS232 as a way of learning Async. At the end of day i have to code Async for one pin IO for another smart card device.
Thanks for solving my problem.
Konrad



Joined: 15 Sep 2003
Posts: 34

View user's profile Send private message

bit bang using timers
PostPosted: Sat Aug 06, 2005 5:21 am     Reply with quote

The simplest way to bit bang (or bit capture) with specific timing is to use the timer interrupts.


Code:


//timer 2 is used to time recieve
#int_timer2
timer2_isr()
{
   if(--interrupt2_count==0) //no of timer interrupts for bit period
   {
      interrupt2_count=INTS_PER_BIT_PERIOD;

      //sample routine, samples pin B1 every xxmS
      shift_left(data, MESSAGE_LENGTH, input(PIN_B1));
      data_count++;
      //disable interrupt
      if(data_count == MESSAGE_LENGTH_BITS)
      {
         disable_interrupts(INT_TIMER2);
         interrupt_flag=1;
      }
   }

}

data_count=0;
interrupt2_count=INTS_PER_BIT_PERIOD;
set_timer2(0x00);
enable_interrupts(INT_TIMER2);
interrupt_flag=0;
while(interrupt_flag==0)
{
   //nop
}


If you can set the timer interrupt rate exactly then you do not need to clear the timer or count the interrupts.
There is a time difference between the timer rolling over and resetting the timer, but this timing will be consistent.
Kit
Guest







PostPosted: Sat Aug 06, 2005 8:41 am     Reply with quote

Thanks Mark,

Now I will take some time to learn about the timer interrupt Smile

Another question, how to calculate the for each instruction?

Code:
57:                      delay_us(90);
00002F    303B     MOVLW 0x3b
000030     0F7     MOVWF 0x77
000031     BF7     DECFSZ 0x77, F
000032    2831     GOTO 0x31
000033     000     NOP
000034     000     NOP


The above listing is taken from the MPLAB (compiled with CCS compiler).
I am using 8Mhz resonator.

Code:
so Each instruction clock takes 4 clock cycles = 1 /(8 MHz / 4 ) = 0.5 us
GOTO takes 2 instructions clock
DECFSZ + GOTO loop for 119 times (0x77 = 119) = (1 + 2) x 119 x 0.5 us = 178.5 us
MOVLW + MOVWF + NOP + NOP = 4 x 0.5us = 2 us
The total time spent = 178.5us + 2us = 180.5 us


Why does the total time spent is 180.5 us, instead of 90 us?
Kit
Guest







PostPosted: Sat Aug 06, 2005 8:43 am     Reply with quote

my compiler is pcm 3.180
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Sat Aug 06, 2005 10:02 am     Reply with quote

0x77 is a variable address. The value loaded is 0x3b = 59.

Do the math and you will find that the delay is 90us.
Ttelmah
Guest







PostPosted: Sat Aug 06, 2005 3:54 pm     Reply with quote

Be aware, that you don't have to use two pins for the use RS232 instruction to work. If (for instance), you code a use RS232 instruction using a transmit, and receive pin, and then never use the receive pin, no code is generated for the receive (for the software UART), and the second pin can still be used for other things. You can also code two streams, and use the same pin for a transmit in one, and a receive in the other, and send data out using the first stream, and then receive data on the same pin using the second. The instruction is much more flexible than it may appear.

Best Wishes
Kit
Guest







PostPosted: Sat Aug 06, 2005 8:58 pm     Reply with quote

When we want to code one-pin IO Async Transmission, what we need to do is use 2 #use rs232 with stream referring to same pin, one is for Xmit, another one for Rcv. Is that what u mean?


Finally there is hope for coding Async in simple way. Very Happy
Ttelmah
Guest







PostPosted: Sun Aug 07, 2005 2:24 am     Reply with quote

I think I'd do the following:
Use two use RS232 statements. One setting up a pin as the receive, and another setting the same pin up for transmit. On the latter, use the 'float high' option. Add an external pull up resistor on the line.
The reasons are that unless you use the 'float high' line, the line will be driven high by the transmit code when it finishes. Since the line needs to be available as an input, for the other device to use it, the float option allows this to work.
I'd use the two seperate streams, both to keep it clear in my mind (if you call one something like 'output', and the other 'input', it helps to keep things clear about what is being done). Also though this avoids the compiler getting itself possibly confused by using one pin.

Best Wishes
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