Page 1 of 1

Serialstring on one pin of the 16F84

Posted: Sun Dec 31, 2006 2:16 pm
by Urfalo
I am trying to comunicate with the 16F84 thru a MAX232 on one one pin of the 16F84. How can I send and recive serial strings on one pin?
This is my project, but I dont understand the C language: http://www.blitzlogic.com/temp.htm :?:
How can I decide what comunicationspeed I want to use?

Posted: Tue Jan 02, 2007 10:40 am
by Benj
Hi Urfalo

To achieve this you need to adopt a bit banging approach. Since you are using the 16F84 there is no serial UART port so all of the serial communication must be achieved through software. The communication speed or baud rate of the serial data must be compatible with your max232 device. This will probably be found in the device datasheet. The baud rate can be calulated as throughput per second. eg bytes with start and stop bits per second.

Posted: Tue Jan 02, 2007 9:34 pm
by Urfalo
This MAX232 is just a stupid device thath transform the RS232 +- 10 to 0 to 5v, so the speed is defined by the prosessor. I see they have used a C example, but can the pins on the prosessor be defined like this? I have tryed to copy paste the examples and put them in a C module in Flowcart, but I get several error messages.

#include <16F84.H>

#use delay(clock=4000000)

#use rs232(baud=9600, xmit=PIN_A3, rcv=PIN_A2)

#include

main() {
byte value;

init_temp();

do {
value = read_temp();
printf("%u\r\n",value);
delay_ms(1000);
}while (TRUE);
}

Posted: Wed Jan 03, 2007 10:57 am
by Benj
I can see why your compiler is throwing up errors. This C code you are using is obviously from some kind of smart compiler which uses code to drive the PICmicros UART device.

Since the PICmicro your using (16F84) has no UART device the only way you will be able to send or recieve the serial data is to clock the data in or out one bit at a time. The easiest way to do this is to set up a loop of 10 cycles.

1st cycle outputs a logic 0 - start bit
2nd - 9th cycle outputs the data going LSB / MSB first not sure which
10th cycle outputs a logic 1 - stop bit

Between each cycle you will need a delay. If you times this delay by 10 (no of cycles) and then devide 1 by this number (1 / total time) you will get the baud rate of your system. By varying the delay you vary the baud rate. Therefore if you wanted a baud rate of 9600, each bit delay would equal.

((1 / 9600) / 10) seconds

Reading a value in would follow the same process of

waiting for a logic 0 - start bit
delaying the correct amount of time
reading in the 1st bit of data
delaying the correct amount of time
etc....

Time

Posted: Sat Jan 06, 2007 8:11 pm
by Urfalo
I have read in the RS232 protocol that i have to use 104uS for every byte in 9600bps, but in flowcart the shortest amount of time I can choose is 1mS.

Posted: Sun Jan 07, 2007 12:26 am
by Mikat
There is change to use 10Βµs delay,with writing in c-code block "delay_10us"(delay you needed");..
It should work..

T:Mika

Posted: Sun Jan 07, 2007 10:26 pm
by Urfalo
I have no experience in C code. When I compile "delay_104us" into chip, i get an error: test.c(68): error: missing semicolon

Posted: Mon Jan 08, 2007 10:15 am
by Benj
In the C Code block you need to use delay_10us(10); this will create a delay of 100us. The other 4us can be taken up by the control logic that controls the serial data flow. If the delay is not long enough then the 4us can be created by using assembler embedded into a C code block eg

Code: Select all

asm
{
nop   ;nop = no operation
nop
nop
nop
}

Posted: Mon Jan 08, 2007 8:39 pm
by Urfalo
Thanks.
This seams to work in one block, but when I copy paste this block I get several error messages:

C:\Documents and Settings\Rudi Skanvik\My Documents\RS232.c(59:2): error: unknown identifier 'txsta'
C:\Documents and Settings\Rudi Skanvik\My Documents\RS232.c(59:2): error: invalid operand 'txsta'
C:\Documents and Settings\Rudi Skanvik\My Documents\RS232.c(59:8): error: failed to generate expression
C:\Documents and Settings\Rudi Skanvik\My Documents\RS232.c(60:2): error: unknown identifier 'spbrg'
C:\Documents and Settings\Rudi Skanvik\My Documents\RS232.c(60:2): error: invalid operand 'spbrg'
C:\Documents and Settings\Rudi Skanvik\My Documents\RS232.c(60:8): error: failed to generate expression
C:\Documents and Settings\Rudi Skanvik\My Documents\RS232.c(61:2): error: unknown identifier 'rcsta'
C:\Documents and Settings\Rudi Skanvik\My Documents\RS232.c(61:2): error: invalid operand 'rcsta'
C:\Documents and Settings\Rudi Skanvik\My Documents\RS232.c(61:8): error: failed to generate expression
C:\Documents and Settings\Rudi Skanvik\My Documents\RS232.c(62:4): error: unknown identifier 'rcsta'
C:\Documents and Settings\Rudi Skanvik\My Documents\RS232.c(62:4): error: invalid operand 'rcsta'
C:\Documents and Settings\Rudi Skanvik\My Documents\RS232.c(62:11): error: failed to generate expression
C:\Documents and Settings\Rudi Skanvik\My Documents\RS232.c(64:4): error: unknown identifier 'trisc'
C:\Documents and Settings\Rudi Skanvik\My Documents\RS232.c(64:4): error: invalid operand 'trisc'
C:\Documents and Settings\Rudi Skanvik\My Documents\RS232.c(64:11): error: failed to generate expression

Posted: Mon Jan 08, 2007 8:55 pm
by Urfalo
Sorry if I'm asking stupid questions now, but wont a NOP wary in time depending on the speed of the local oscillator :shock:

Posted: Tue Jan 09, 2007 11:34 am
by Benj
wont a NOP wary in time depending on the speed of the local oscillator
Yes a single NOP just takes up 4 clock cycles this would have to be translated into a time equivalent to 4us. Also keep in mind that your control logic will take up clock cycles also.
error: unknown identifier 'txsta'
Secondly the error messages you are receiving are due to the fact that the 16F84 doesn't have these registers. You either have to use a PICmicro with a hardware UART or use a totally software approach. (bit banging)

Psudo code for the bit banging output approach would look similar to this

for (byte i = 0; i < 10; i++)
{
delay (1 bit delay / 1 10th byte delay)
switch (i)
case 0:
Output_Bit = 0; //Start Bit
Break;

case 9:
Output_Bit = 1; //Stop Bit
Break;

case default:
Output_Bit = Data_Var & 0x01; //Output Data 1 Bit at a time
Data_Var = Data_Var >> 1; //Rotate Data Variable
Break;
}