We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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); } } /*------------------------------------------------------------------------------ ------------------------------------------------------------------------------*/
"There was a thread somewhere that calls attention to manglign the contents of ACC in C language, but I was reckless."
In this case, it has nothing to do with being in 'C' - using Assembler would have exactly the same problem!
The problem is that com_putchar() does not load SBUF; it simply writes to a circular buffer - the character doesn't reach SBUF until some time later!