|
|
View previous topic :: View next topic |
Author |
Message |
starfire151
Joined: 01 Apr 2007 Posts: 195
|
Async comm with PIC12F675 at 32.768KHz? |
Posted: Mon Sep 01, 2008 7:06 pm |
|
|
Is it possible to get a reliable asynchronous, bi-directional communications link using a PIC12F675 running at 32.768KHz?
I have done some basic tests with a rate of 300 baud (3.333ms/bit) with no success. The clock running at 32.768KHz should mean the instruction cycle is roughly 122us. This should be around 27 instruction cycles per bit. I used the following code to check for output and input:
Code: |
#include <12F675.h>
#device adc=8
#fuses NOWDT, LP, NOPROTECT, NOMCLR, PUT, NOBROWNOUT
#use delay(clock=32768)
#use rs232(baud=300, parity=N, xmit=PIN_A2, rcv=PIN_A3, bits=8)
void main()
{
char ch;
setup_counters(RTCC_INTERNAL, RTCC_DIV_1);
set_tris_a(0x08); // a0, a1, and a2 : outs; a3 : in
port_a_pullups(0x07); // pullups on a0 through a2 (no pullup on a3)
set_rtcc(0);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_8 | RTCC_8_BIT);
ch = 'x'; // default char
while(TRUE)
{
if(kbhit())
{
ch = getc(); // get char
printf("%c ", ch); // print char
}
}
} |
Is there an easier way to get a slow data communications link working between two processors? I only need to communicate one or two characters each way. Is there a way to do this with one wire?
Thanks for any insight...
Dave |
|
|
Ttelmah Guest
|
|
Posted: Tue Sep 02, 2008 2:25 am |
|
|
The problem is that 'simple' async, needs quite a lot of work. For transmit, you need to rotate a bit from the source word, and output it for the required time. Probably 'do-able'. However for receive, you need to sample in the 'middle' of the bit time, receive a bit, and rotate this into the required location. I posted on a thread some time ago, the instruction counts involved, and the total is surprisingly large. I'd say you could probably happily do 50bps both ways. Probably handle the transmit OK at perhaps 200bps, but have problems with the receive.
Unless you 'need' 300bps, go down to something like 50bps, or switch to a chip that has a hardware UART.
The alternative is to go 'custom', and write your own routines. If (for instance), you just sample the bits into a byte array, then perform the assembly of the byte after the receive, this would probably work. Even with assembler, getting the timings to work really well at 300bps, will be quite difficult. However for 'comparison', I wrote an assembler transmit and receive, that handled _full duplex_ at 75bps at a similar clock rate, but on a '16' chip, with the advantage of more hardware timers.
Best Wishes |
|
|
Guest
|
|
Posted: Tue Sep 02, 2008 2:40 am |
|
|
Quote: | Is there a way to do this with one wire? | How about the 'One wire' protocol? Developed by Dallas Semiconductor, now owned by Maxim.
You will have to make some changes to the protocol timings as your clock is too slow, but because you are implementing both the master and slave devices this shouldn't be a problem.
An example driver is provided in the the CCS examples directory. Several more implementations can be found in this forum (search for 'DS1822', a one-wire temperature sensor). |
|
|
starfire151
Joined: 01 Apr 2007 Posts: 195
|
|
Posted: Tue Sep 02, 2008 7:17 am |
|
|
Thanks for the replies...
I suspected the software receive routine would be fairly complicated and take a lot of instruction cycles. Thanks for confirming that. Ultimately I need this communication link between two processors. The first is running in a very low power mode (thus the 32.768KHz clock). It controls the power to a second processor running at about 20MHz. At the conclusion of the second processor's program, it needs to send a sequence back to the first processor to tell it to power down the second processor for a period of time. The second processor also has to sometimes communicate a command to tell the first processor to change the power down period.
I had been accomplishing this with a single wire sending a series of pulses from the second processor to the first. The count of pulses received by the first processor would determine the needed action. I had the pulses set to 10ms low and 20ms high with up to 10 pulses being sent (300ms max). The first processor looked for an input high-to-low interrupt and, when seen, would start a 1-second timer. The interrupt would count the number of pulses and the total number would be reported to the background routine at the end of the 1-second period. The count would determine the action. This was a blind output from the second processor, though, with no way for the second processor to confirm the first processor received the command correctly. There have been cases in the field where the command was received incorrectly. I'm trying to add some reliability and confirmation to the interface.
I have checked the 1-wire Maxim protocol a bit but the same problem with data rate will exist. I thought a simple 10-bit baud packet at a slow data rate might be a little more reliable. I could use specific ASCII characters with bit patterns to minimize confusion with invalid commands.
I will check into using 50 baud as this would still only take around 200ms to send a character. Unfortunately Hyperterminal only goes down to 110 baud. Is there a freeware terminal emulator that will go down to 50 baud?
Thanks, again.
Dave |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Tue Sep 02, 2008 9:23 am |
|
|
Two bit lines between the processors also would allow a reduced speed I2C protocol, possibly more easy than 1-wire cause it doesn't rely on a specific timing, except for leaving enough time for the slave to recognize the bus level changes. |
|
|
Guest
|
low baud rate |
Posted: Tue Sep 02, 2008 3:16 pm |
|
|
I've used a simple 24 Baud( yes, 24 bits per second, yawn...) single wire 3 state protocol communications network for the past 25+ years.Originally a 6800 series processor,later a 68HC11,currently upgrading to a PIC.
It is dead simple but very,very reliable going about 25 miles(yes MILES) over plain old telephone hard copper cables.
Jay |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Sep 02, 2008 4:00 pm |
|
|
I2C is a nice protocol using only two wires but slave implementation is very difficult to do in software.
A better alternative would be SPI. Default SPI is full-duplex and uses 3 wires but some non-standard versions exist using two wires at the trade off of being half duplex.
Just curious: The low power processor's only purpose is to wake up the main processor at specified time intervals? If yes, then why not use a standard Real Time Clock chip? These are designed for that exact purpose including 1 or more alarm registers with outputs that will trigger your High Performance CPU.
Using one of these chips will save you the time of designing the low power CPU software, the chips are tested, optimized for low power and don't require to be flash programmed during production. |
|
|
John P
Joined: 17 Sep 2003 Posts: 331
|
|
Posted: Wed Sep 03, 2008 3:54 pm |
|
|
I'm certain that you can do this for 300 baud. The only requirement is that the processor mustn't need to be doing anything else at the same time.
Don't use interrupts. Just have the processor sit in a loop polling the incoming data line:
Code: |
while(bit_test(SERIAL_IN))
; // Do nothing till line goes low
|
When you get a low-going edge, have the processor run through a series of NOP statements arranged to take 1.5 bit times altogether. Then store the first data bit.
Code: |
NOP // 1.5 bit times worth of NOPs
NOP
#ENDASM
if (bit_test(SERIAL_IN))
bit_set(new_byte, 0);
else
{
bit_clear(new_byte, 0);
bit_clear(new_byte, 0); // This wastes time so 1/0 are equal length
}
#ASM
NOP // Now 1 bit times worth of NOPs
NOP // then look for the next bit
|
Then repeat for bit 1, bit 2 etc. This scheme should work for 600 baud, but I don't think it will do 1200.
Compared with receiving, transmitting is so easy that I won't bother with it. |
|
|
|
|
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
|