|
|
View previous topic :: View next topic |
Author |
Message |
Kit Guest
|
Interfacing Technique |
Posted: Thu Aug 04, 2005 12:28 am |
|
|
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
|
|
Posted: Thu Aug 04, 2005 1:40 am |
|
|
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
|
|
Posted: Thu Aug 04, 2005 2:26 am |
|
|
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
|
|
Posted: Thu Aug 04, 2005 2:27 am |
|
|
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
|
|
Posted: Thu Aug 04, 2005 2:03 pm |
|
|
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
|
|
Posted: Thu Aug 04, 2005 7:59 pm |
|
|
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
|
|
Posted: Fri Aug 05, 2005 2:21 am |
|
|
#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
|
|
Posted: Fri Aug 05, 2005 3:27 am |
|
|
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
|
bit bang using timers |
Posted: Sat Aug 06, 2005 5:21 am |
|
|
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
|
|
Posted: Sat Aug 06, 2005 8:41 am |
|
|
Thanks Mark,
Now I will take some time to learn about the timer interrupt
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
|
|
Posted: Sat Aug 06, 2005 8:43 am |
|
|
my compiler is pcm 3.180 |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Sat Aug 06, 2005 10:02 am |
|
|
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
|
|
Posted: Sat Aug 06, 2005 3:54 pm |
|
|
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
|
|
Posted: Sat Aug 06, 2005 8:58 pm |
|
|
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. |
|
|
Ttelmah Guest
|
|
Posted: Sun Aug 07, 2005 2:24 am |
|
|
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 |
|
|
|
|
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
|