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); } } /*------------------------------------------------------------------------------ ------------------------------------------------------------------------------*/