Subject : Re: - Issue : 970527 BREAK Detect From : Milton Fabert >Message 1 : > Subject : BREAK Detect > From : "Chris Lott" > > >HELP! I'm trying to program an 8051XA to detect a BREAK signal. I >recently discovered that the hardware support provided, the break >detect interrupt, only detects the *start* of a BREAK signal. I need >to know when an entire BREAK signal has occurred - I almost would >prefer an *end* of BREAK interrupt, instead. Any ideas? > >-Chris Lott > >*********************************************************************** >R. Christopher Lott, P.E. lott@phase4.com >Phase IV Systems, Inc. alternate address: >3405 Triana Blvd, SW rclott@ro.com >Huntsville, AL 35805 >*********************************************************************** > > If you can afford to poll for the end of break you could simply check the port bits (port 1 or 3 I believe.) If the break has cleared the port bit that corresponds to the serial Rx line will be "1". If you're using an event loop you could use the start of break interrupt to set a flag that tells the event loop to check the RX status periodically. If your using a real time o.s. you could start a task that handles polling and processing of the end of break event. If you have a spare interrupt input available you could connect the rx line to said interrupt (I believe you'll need to invert the Rx signal) and enable that interrupt from within the start of break interrupt. This way you'll have an end of break interuupt. Note that you'll need code to take care of the condition that the end of break occurs while you are still processing the beginning of break interrupt. Milton Fabert Earthwatch, Inc. mfabert@ewi.com Subject : Re: Philips Microcontroller Forum Digest - Issue : 970527 at 10:57 From : Richard John Vagg On Tue, 27 May 1997, Philips Microcontroller wrote: > Philips Microcontroller Forum Digest - Issue : 970527 at 10:57 > > Message 1 : > Subject : BREAK Detect > From : "Chris Lott" > > > HELP! I'm trying to program an 8051XA to detect a BREAK signal. I > recently discovered that the hardware support provided, the break > detect interrupt, only detects the *start* of a BREAK signal. I need > to know when an entire BREAK signal has occurred - I almost would > prefer an *end* of BREAK interrupt, instead. Any ideas? > > -Chris Lott > You could set up the interrupt to be edge triggered. This would detect the start and end of the break signal. Your code would have to check whether the interrupt is from the start or the end of a break signal. rj. Subject : RE: help From : Ivan Zilic Hello ! > Subject : help > From : > I have a problem with the using serial port in Atmel 89c2051. > I programed the special function registers for the communication, > but i can send just one byte. I guess you wrote interrupt-driven program and uC locks-up after sending first byte ? If so, you must modify your serial routines, because interrupt routine (0023h) is executed also always when character is transmitted (and TI register become available for next character). A possible solution is to modify your procedures by adding a flag to look like that (and you must execute 'SETB TIReadyFlag' command during initialisation) : PutChar: JNB TIReadyFlag,PutChar CLR TIReadyFlag MOV SBUF,A RET GetChar: JB TI,SetTIReadyFlag ; this is an IRQ routine JNB RI,GetChar MOV A,SBUF CLR RI RETI SetTIReadyFlag: SETB TIReadyFlag CLR TI RETI Subject : serial port From : "Meikle, Colin" > >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> > >Message 8 : > Subject : help > From : > > >Hello! >Please HELP me! >This is my first time in the 8051 programing environment. >I have a problem with the using serial port in Atmel 89c2051. >I programed the special function registers for the communication, >but i can send just one byte. > > ><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< If you are only able to send one byte the problem is probably to do with the TI (transmit interrupt flag). TI is set when the byte is sent and must be cleared in s/w. If your are not using an interrupt driven routine you should, send a byte, wait on TI=1, then clear TI before sending the next byte. If your routine is interrupt driven you must remember to clear TI in your routine otherwise you will get continual interrupts. Subject : Re: Philips Microcontroller Forum Digest - Issue : 970602 at 10:57 From : John Dammeyer At 02:55 AM 03/06/1997 -0700, you wrote: >Message 3 : > Subject : How long must RxD be high after serial > From : skb@rainwise.com (Steve Bohrer) > > >I'm planning to receive a serial protocol (DMX-512, for theatrical dimmers) >that uses a break to signal the start of the data packet. For the break, the >transmitting system makes my RXD pin (after the proper line driver) be 0 V >for at least 2 character times; after the break the line is put in the idle >state (+5 at my RXD pin) for at least 1 bit time; and then the first byte of >data is sent. How long the UART requires a MARKING state before correctly receiving characters is usually not documented. I would assume that if One Stop bit is enabled that a one bit MARKING time - at the end of a received character - would be adequate to let the receiver synchronize and correctly receive your data. > >My concern is that a brief glitch (less than 1 bit time) during the break >will trigger a start bit detection in the 8051 serial hardware. Does the >hardware check at all for how long RXD is high before the start bit? (With >normal characters, it is at +5 for the duration of the stop bit(s).) To my knowledge many modern UART use the OVERRUN condition along with a NULL byte received to represent a BREAK detected. Older video terminals used to issue a 10ms SPACE to generate a break condition. Others just held the line in the SPACING state while a user held down the break key. As far as glitches go. The internals of a UART could use Edge detection to detect the first start bit but it would make the UART far more complicated than it needs to be. As the UART sits idle it remains in the LOOKING for START BIT state. This is checked on either the rising or falling edge of the iternal 16X clock. Once the START BIT level shows up on the Rx Line and is detected a counter is loaded with the value 8. This counter is decremented once per 16X clock until 0 at which point the logic checks the receive line again. If the line is still the same then a valid start bit has occured and the counter is now loaded with 16 and a second counter loaded with the character size. After 16 more 16X clock pulses the counter will again be 0 and produce a shift of the input line into the RX register. The counter is reloaded with 16 again and this happens until the Stop Bit time when the next received bit must be MARKING again. If not an OVERRUN condition is signaled otherwise a character received signal is produced. So your glitch could cause all sorts interesting side effects. a) UART senses high level because the glitch occurs at the instant that the UART bit detection counter is 0 and assumes break has been completed. Here it gets fuzzy. If the UART reloads it's bit detection counter with 16 (one bit time) and requires the line to be MARKING when the counter equals 0 it may see that condition as part of the data stream that suddenly appears on the bus. The next logic low in the middle of that data stream would then be considered a start bit. If the counter is loaded with 8, (1/2 bit time), the same thing may happen. b) If the UART assumes that the high level is the end of the break then on the next 16X clock it would see a low level again and assume a start bit on what is really still a break condition. Depending on when the break ends the uart will detect either a second break or find itself in the middle of a character assuming the end of a character. So what to do? Ensure a Glitch free environment. If you cannot do that then ensure that your higher level protocol is adequately protected to detect these anomilies. eg. Parity, Checksums, CRCs, inter-character timeouts where a message is discarded if the intercharacter spacing is too long. If you cannot do that be prepared accept that sometimes, perhaps only rarely, your equipment is going to do odd things and result in customer dissatisfaction. >In the old Intel "Hardware Description of the 8051, 8052, and 80C51" note it >says >" Reception is initiated by a detected 1-to-0 transition at RXD. For this >purpose RXD is sampled at a rate of 16 times whatever baud rate has been >established. " > >Does this mean that a +5 glitch of 1/16-bit-time during the break may start >a reception? If so, any solutions, beyond "make sure no glitches happen"? > What you can also do to reduce the glitches is to reduce your baudrate and filter your RS232 lines in such a way that the electrical noise is reduced below the threshold of your detectors. ie; a 1 bit time glitch at 9600 baud is 104uSec while a bit time at 2400 baud is 416uSec so filter your data line so increases the rise and fall time of your data line to >104uSec. But that can open up a different can of worms. Subject : Re: Philips Microcontroller Forum Digest - Issue : 970718 at 10:57 From : Peter Ullrich > Subject : 8051 CRCs > From : "Gerald Waugh" > > >OK, you know who you are! Please, Please send me some fast, compact 8051 >CRC code. >Thank You, Thank You! P.S. I need to do 8 and 16 bit CRCs "Gerald Waugh" > Hi Gerald! Here is a CRC16 Routine I found on the internet. I hope this solves your problem. ----------------------------------------------------------------- ; Constant definitions ; CRC_MASK_LSB EQU 001H ;CRC-16 poloynomial CRC_MASK_MSB EQU 0A0H ; ; ; Note: the CRC accumulator bytes are being stored in ; ram bytes 0DH and 0EH; these correspond to registers ; R5 and R6 in bank 1, which are not used by the ; communications interrupt ; ; CRC_ACCUM_LOW EQU 0DH ;register bank 1 R5 CRC_ACCUM_HI EQU 0EH ;register bank 1 R6 ; ACALL MSG_LENGTH ;find the message length ACALL CALC_CRC ;calculate the CRC ; ; Now, CRC_ACCUM contains the computed CRC of the message. Are ; they the same as contained in the message itself? ; ADD A,#COMBUF ;add to buffer address to from pointer ;to the first byte of the CRC MOV R1,A ;R0 will point MOV A,@R1 CJNE A,CRC_ACCUM_LOW,COMINT_03 ;abandon if not equal INC R1 MOV A,@R1 CJNE A,CRC_ACCUM_HI,COMINT_03 ;abandon if not equal ; ;--------------------------------------------------------------------------- ; CRC calculation routine -- this routine calculates ; the CRC polynomial for the contents of the communications ; buffer, based upon the desired length of computation (passed ; in the A register). R1 serves as the comm buffer pointer. ; CALC_CRC: MOV R0,A ;save the accum MOV R7,A ;save the count MOV R1,#COMBUF ;and point to the combuf CLR A MOV CRC_ACCUM_LOW,A ;clear the crc accum before we start MOV CRC_ACCUM_HI,A ; ; First we XOR the incoming byte with the contents of ; the least significant byte of the CRC accumulator ; CC10: MOV A,CRC_ACCUM_LOW ;xor the byte with the LSbyte of the CRC_accum XRL A,@R1 MOV CRC_ACCUM_LOW,A ; ; now we commence shifting the crc accumulator right ; one bit, testing the bit that pops out to see if we ; need to xor the crc accumulator with the crc mask. We ; do this eight times (once for each bit of the byte) ; MOV R4,#8 ;R4 will serve as the eight state counter CC20: MOV A,CRC_ACCUM_HI ;get the high byte CLR C ;filled with 0's RRC A ;shift it right MOV CRC_ACCUM_HI,A MOV A,CRC_ACCUM_LOW ;and the low byte RRC A ;shift it right MOV CRC_ACCUM_LOW,A ; ; if the carry is set, we must XOR the crc accumulator ; with the crc mask ; JNC CC30 MOV A,CRC_ACCUM_LOW XRL A,#CRC_MASK_LSB MOV CRC_ACCUM_LOW,A MOV A,CRC_ACCUM_HI XRL A,#CRC_MASK_MSB MOV CRC_ACCUM_HI,A ; CC30: DJNZ R4,CC20 ;do it eight times ; ; the process is repeated for each character ; in the message, according to the length passed ; when the routine was called ; ; INC R1 ;rdy for next byte in the message DJNZ R7,CC10 ;one less byte to do ; MOV A,R0 ;restore the accum RET ; ;