??? 02/16/06 07:59 Read: times |
#110127 - about code Responding to: ???'s previous message |
hi,
Although the code seems workable nevertheless I have some suggestions and questions about it. Some ones are pedant, others are more serious. INIT_UART: mov tmod,#20H ;timer MODE 1, 8 BIT auto reload mov th1,#0FDH ;timer preset for 38400 BAUD mov scon,#01011010B ;SM0=0 SM1=1 REN=1 TB8=1 RB8=1 TI=1 mov pcon,#10000000B ;double BR_BIT=1 => @ 38400 BAUD setb tr1 ;set timer RUN BIT setb es ;enable serial interrupt setb ea ;enable global interrupt clr char_rcv_flag ;clear character received Flag ret ;Do clear character received flag before enable interrupts. In fact, this piece of code does not cause problems only because according "Atmel hardware datasheet" all interrupts are delayed for one instruction after IE register has been changed. But I have no idea about derivatives of other vendors. Just for test: insert one NOP between interrupts enable and clear instructions and you will get undefined characters transmitted via UART as echo after power-up time to time. It is because memory content is not defined at power-up and char_rcv_flag may be set then. SER_INT: push psw ;save psw push acc ;save acc push dpl ;save dpl push dph ;save dph jb ri,receive ;receiver interrupt ? jnb char_rcv_flag,ser_exit ;transmitter ready & no new char. mov sbuf,buffer ;send byte clr ti ;clear transmitter interrupt clr char_rcv_flag ;clr character received Flag sjmp ser_exit ;exit ISR RECEIVE: mov buffer,sbuf ;received byte into buffer clr ri ;clear receiver interrupt setb char_rcv_flag ;set Flag SER_EXIT: pop dph ;get dph pop dpl ;get dpl pop acc ;get acc pop psw ;get psw reti ;return from interrupt 1) There is no reason to save/restore DPTR, ACC and even PSW during the serial ISR because you have no commands which alter their content. 2) AT89S8252 has SPI interrupt vector shared with UART one (0x0023). Even worse: they both are enabled by the same ES bit. Fortunately Atmel added SPIE bit to disable SPI interrupt individually. What I say about: if this piece of code will be used together with SPI interrupt then you should check both RI and TI bits. I would do this way even here for good programming style. 3) A question: could you explain the idea? Assume I send one byte from PC to MCU. The byte has been received, processed by display part and sent back (echo). After that, TI flag is set at the end of echo transmission and serial ISR is executed. The ISR checks for char_rcv_flag. As you commented "transmitter ready & no new char" so ISR ends with RETI and MCU goes to main loop where it executes one instruction and jumps to serial ISR once again and again and again due TI flag is still set. Is this defined behaviour of your code? It might not be a problem for main loop. But such situation may happen anywhere, for example, during WAIT subroutines and all their timings come very wrong. And about timings. You printed "Zero waitstates @ 38400 BAUD - (Transmit Delay 0 ms)." Here I do not be pedant saying that nothing may be zero long :) but in fact some control bytes break this timing absolutely. I mean cursor_home and clear_display. These subroutines take above 4ms to be executed while UART takes only about 0.3ms to receive a byte. As result some bytes may be lost if this fact is not took in consideration. Regards, Oleg |