This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Setting up UART for 9600, 8, e, 1 -Works on PC but not on target

Need advice on what is going on with this program.
It partially works when connected to a PC (Windmill ComDebug) but does not work on the device. It seems that I fail to work with the parity bit, because the ComDebug can not tell the difference between even parity, no parity and odd parity. But I miserably fail to master the TB8, ACC and P to make it work.

I am struggling with an ATMEL 89C5131. I want to set it up for 9600, 8, e, 1. The Xtal is 16MHz, due to the USB needs.

The target device is a bill acceptor. Its protocol requires these settings.

The protocol is as: Synch; Lengh; data; CRC; CRC.
Synch is 0xFC; Lenght: 0x05; data is 0x40 (reset); 0x2B; 0x15. I have the following code copied from intsio2 from Keil site.
The modifications are adaptations to the required settings.

The SIO works as a charm, of course, I just can not master it to handle the parity bit.

Any help is very welcome.

Ed

/*
SIO.C:  Serial Communication Routines.

Copyright 1995-2002 KEIL Software, Inc.
------------------------------------------------------------------------------*/

#include <reg51.h>
#include <string.h>
#include "sio.h"

#define TBUF_SIZE   8           /*** Must be one of these powers of 2 (2,4,8,16,32,64,128) ***/
#define RBUF_SIZE   16           /*** Must be one of these powers of 2 (2,4,8,16,32,64,128) ***/

#define TBUF_SPACE  idata       /*** Memory space where the transmit buffer resides ***/
#define RBUF_SPACE  idata       /*** Memory space where the receive buffer resides ***/

#define CTRL_SPACE  data        /*** Memory space for the buffer indexes ***/

void com_initialize (void)
{
/*------------------------------------------------
Setup TIMER1 to generate the proper baud rate.
------------------------------------------------*/
com_baudrate (9600);

/*------------------------------------------------
Clear com buffer indexes.
------------------------------------------------*/
t_in = 0;
t_out = 0;

r_in = 0;
r_out = 0;

/*------------------------------------------------
Setup serial port registers.
------------------------------------------------*/
SM0 = 1; SM1 = 1;   /* serial port MODE 2 */
SM2 = 0;
REN = 0;            /* enable serial receiver */

RI = 1;             /* clear receiver interrupt */
TI = 1;             /* clear transmit interrupt */
ti_restart = 1;

ES = 1;             /* enable serial interrupts */
PS = 0;             /* set serial interrupts to low priority */
}

/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
#pragma disable

void com_baudrate (
  unsigned baudrate)
{

   SCON = 0xF0; /* uart in mode 3 (9 bit), REN=1 */
   T2CON &= 0xF0;               /* EXEN2=0; TR2=0; C/T2#=0; CP/RL2#=0; */
   T2CON |= 0x30;               /* RCLK = 1; TCLK=1; */
   TH2=0xFF;                    /* init value */
   TL2=0xFD;                    /* init value */
   RCAP2H=0xFF;                 /* reload value, 9600 Bds at 16.MHz */
   RCAP2L=0xCC;                 /* reload value, 9600 Bds at 16.MHz */
*/
        ES = 1;                                                      /* Enable serial interrupt */
        EA = 1;                                              /* Enable global interrupt */
   TR2 = 1;                     /* Timer 2 run */

/*------------------------------------------------
Clear transmit interrupt and buffer.
------------------------------------------------*/
TI = 0;             /* clear transmit interrupt */
t_in = 0;           /* empty transmit buffer */
t_out = 0;

/*------------------------------------------------
Set timer 1 up as a baud rate generator.
------------------------------------------------*/
//TR1 = 0;            /* stop timer 1 */
//ET1 = 0;            /* disable timer 1 interrupt */

//PCON |= 0x80;       /* 0x80=SMOD: set serial baudrate doubler */
//PCON |= 0x82;       /* 0x80=SMOD: set serial baudrate doubler */

//TMOD &= ~0xF0;      /* clear timer 1 mode bits */
//TMOD |= 0x20;       /* put timer 1 into MODE 2 */

//TH1 = (unsigned char) (256 - (16000000 / (16L * 12L * baudrate)));

//TR1 = 1;            /* start timer 1 */
}

/*------------------------------------------------------------------------------
MAIN.C:  Interrupt Driver SIO Using printf.

Copyright 1995-2002 KEIL Software, Inc.
------------------------------------------------------------------------------*/

#include <reg51.h>
#include <stdio.h>
#include "sio.h"

/*------------------------------------------------------------------------------
_getkey waits until a character is received from the serial port.  This may not
be the exact desired operation (for example if the buffer is empty, this
function hangs waiting for a character to be received).
------------------------------------------------------------------------------*/
char _getkey (void)
{
int k;

do
  {
  k = com_getchar ();
  }
while (k == -1);

return ((unsigned char) k);
}

/*------------------------------------------------------------------------------ */
bit get_parity (volatile char ch)
{
  ACC = ch;
  return (P);
  }
/*------------------------------------------------------------------------------*/
char putchar (char c)
{

volatile unsigned int i;

TB8 = get_parity(c);
while (com_putchar (c) != 0)
  {
  for (i=0; i<1000; i++)
    {
    /*** DO NOTHING ***/
    }
  }

return (c);
}

/*------------------------------------------------------------------------------
Note that the two function above, _getkey and putchar, replace the library
functions of the same name.  These functions use the interrupt-driven serial
I/O routines in SIO.C.
------------------------------------------------------------------------------*/
code char message [] =
  "This is a test to see if the interrupt driven serial I/O routines really work.";

void main (void)
{

com_initialize ();              /* initialize interrupt driven serial I/O */

EA = 1;                         /* Enable Interrupts */

//printf ("Interrupt-driver Serial I/O Example\r\n\r\n");

  putchar(0xfc);
  putchar(0x05);
  putchar(0x40);
  putchar(0x2b);
  putchar(0x15);

while (1)
  {
  unsigned char c;

//  printf ("Press a key.\r\n");
//  c = getchar ();
 // printf ("\r\n");
 // printf ("You pressed '%c'.\r\n\r\n", c);
  }
}

/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/


0