I have a 89C5131 talking to a RS-232 device, 50 cm from the chip. Using Max232 in standard configuration and RX/TX/GND cable.
The task is to send assincronous commands to the device and read its response and ping pong the configuration.(the device timeout is 3 seconds).
Problem: For some reason (what I am asking you for help), the micro repeats - sometimes - whatever have been received at its input. Like, the micro repeats to the device the string just received. Of course the device them does not recognize it as a valid string and timeout or halts.
I use the INTSIO2 example from Keil and the following program to write and read the commands.
the code - it is sio.c with the mods below:
void com_baudrate () { /*------------------------------------------------ Clear transmit interrupt and buffer. ------------------------------------------------*/ TI = 0; /* clear transmit interrupt */ t_in = 0; /* empty transmit buffer */ t_out = 0; /*------------------------------------------------ Set timer 2 up as a baud rate generator. ------------------------------------------------*/ Set_timer2_x1_mode(); 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 16MHz */ RCAP2L=0xCC; /* reload value, 9600 Bds at 16MHz */ ES = 1; /* Enable serial interrupt */ EA = 1; /* Enable global interrupt */ TR2 = 1; /* Timer 2 run */ }
The above is for 9600, 8, 1, even.
------------------------------------------------------------------------------*/ static void com_isr (void) interrupt 4 { /*------------------------------------------------ Received data interrupt. ------------------------------------------------*/ if (RI != 0) { RI = 0; if (((r_in - r_out) & ~(RBUF_SIZE-1)) == 0) { rbuf [r_in & (RBUF_SIZE-1)] = SBUF; r_in++; } } /*------------------------------------------------ Transmitted data interrupt. ------------------------------------------------*/ if (TI != 0) { TI = 0; if (t_in != t_out) { ACC = (tbuf [t_out & (TBUF_SIZE-1)]); TB8 = P; SBUF = (tbuf [t_out & (TBUF_SIZE-1)]); t_out++; ti_restart = 0; } else { ti_restart = 1; } } }
This is for transmission with the even bit.
void get_serial_cmd() { unsigned char buff; int counter; while ((buff !=0xFC) && (buff !=0)) { buff = getchar(); } if (buff==0xFC) { serial_read[0] = 0xFC; serial_read[1] = getchar(); for (counter = 2; counter < (serial_read[1]); counter++) { serial_read[counter] = getchar(); } } } int send_serial_cmd(unsigned char serial_cmd[16]) { int counter; print_to_lcd = 0; //Diverts putchar to UART for (counter = 0; counter<serial_cmd[1]; counter++) { putchar(serial_cmd[counter]); } print_to_lcd = 0; //Diverts putchar to LCD return (0); }
The above receives and sends the strings from the device.
The program calls this function as:
void action_bill_accepted() { if (serial_read[2] == 0x15) { send_serial_cmd(ACKNOWLEDGE); get_serial_cmd(); } if (serial_read[2] == 0x16) { send_serial_cmd(STATUS_REQUEST); get_serial_cmd(); } }
_getkey and putchar are below:
char _getkey (void) { int k; do { k = com_getchar(); } while (k == -1); return ((unsigned char) k); } char putchar (char c) { volatile unsigned int i; if (print_to_lcd == 1) { lcd_putchar(c); } if (print_to_lcd == 0) { while (com_putchar (c) != 0) { for (i=0; i<1000; i++) { //*** DO NOTHING ** } } } return(c); }
Any suggestion is welcome.
Ed