Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
07/20/10 16:25
Read: times


 
#177396 - Which register bank are you using?
Responding to: ???'s previous message
I use the same part (DS89C450) and have both UARTS working using interrupts, but in order to do it, I used the "using" keyword. This keyword switches the register banks used when the interrupt is services so that interrupts don't trample over each other or have to use the stack.

Here is my initialization code:
void sbufs_init(void) {

	// General Serial Mode Setup
	PCON &= 0xBF; // No Frame Error Mode for SBUF0 and SBUF1

	// Serial 0 Mode Setup
	SM0 = 0; // SBUF0 Mode 0
	SM1 = 1;	// SBUF0 Mode 0
	SM2 = 0; // No multiprocessor communication mode
	REN = 1; // Recieve enable
	RI = 0; // RI must be clear to recieve
	PCON &= 0x7F; // Single Speed for sbuf0
	RXD0 = 1; // Latch port high for serial functions to work correctly

	// Serial 1 Mode Setup
	SM01 = 0; // SBUF1 Mode 0
	SM11 = 1;	// SBUF1 Mode 0
	SM21 = 0; // No multiprocessor communication mode
	REN1 = 0; // Recieve only enabled when expecting an incomming message
	WDCON = WDCON & 0x7F; //01111111B Single Speed for sbuf1
	RXD1 = 1; // Latch port high for serial functions to work correctly

	TEN = 0; // Disable transmit for RS485 until needed

	// Interrupt Settings
	ET1 = 0; // Disable T1 interrupts since using T1 for baud generation
	ET2 = 0; // Disable T2 interrupts since using T2 for baud generation

	// SBUF1 Baud clock
	TMOD = TMOD & 0x0F; // reset timer1 mode bits
	TMOD = TMOD | 0x20; // t1 8bit auto reload timer using system clk 
	TCON = TCON & 0x33; // reset t1 control bits and INT1 control bits
	TH1 = 0xFD; // 9600 for serial port 1
	TR1 = 1; // Start the Baud clock

	// SBUF0 Baud clock	
	T2MOD &= 0xFC;  // Not driving external pin with T2 and T2 counts up
	T2CON = 0x30; // timer 2 is baud for sbuf0 TX and RX
	RCAP2H = 0xFF; // Setup 9600 baud
	RCAP2L = 0xDC; // Communication for S0
	TR2 = 1; // Start the Baud clock
	
	// Initialize ptrs
	RX_IN_PTR_0 = 0;
	RX_OUT_PTR_0 = 0;
	RX_EMPTY_0 = 1;

	RX_IN_PTR_1 = 0;
	RX_OUT_PTR_1 = 0;
	RX_EMPTY_1 = 1;

	TX_IN_PTR_0 = 0;
	TX_OUT_PTR_0 = 0;
	TX_EMPTY_0 = 1;

	TX_IN_PTR_1 = 0;
	TX_OUT_PTR_1 = 0;
	TX_EMPTY_1 = 1;

}

 


And the ISR code:
void serial0_ISR(void) interrupt 4 using 2{
	if(RI) {
		RI = 0;	// Always acknowledge the interrupt
		if(RX_EMPTY_0 || (((RX_IN_PTR_0 + 1) % RX_BUF_SIZE_0) != RX_OUT_PTR_0)) { // buffer full if in+1 == out

			RX_BUF_0[RX_IN_PTR_0]=SBUF0;

			RX_IN_PTR_0 = (RX_IN_PTR_0 + 1) % RX_BUF_SIZE_0;

			RX_EMPTY_0 = 0; // not empty any more
		}
	}
	else {
		TI = 0; // always acknowledge interrupt

		// put_char routine must not fill the buffer such that in ptr catches out ptr
		if(TX_OUT_PTR_0 != TX_IN_PTR_0) {

			SBUF0 = TX_BUF_0[TX_OUT_PTR_0];

			TX_OUT_PTR_0 = (TX_OUT_PTR_0 + 1) % TX_BUF_SIZE_0;
		}
		else TX_EMPTY_0 = 1; // we are done when out ptr catches in ptr
	}
}

void serial1_ISR(void) interrupt 7 using 2{

	if(RI1) {
		RI1 = 0;	// Always acknowledge the interrupt
		if(RX_EMPTY_1 || (((RX_IN_PTR_1 + 1) % RX_BUF_SIZE_1) != RX_OUT_PTR_1)) { // buffer full if in+1 == out

			RX_BUF_1[RX_IN_PTR_1]=SBUF1;

			RX_IN_PTR_1 = (RX_IN_PTR_1 + 1) % RX_BUF_SIZE_1;

			RX_EMPTY_1 = 0; // not empty any more
		}
	}
	else {
		TI1 = 0;

		// put_char routine must not fill the buffer such that in ptr catches out ptr
		if(TX_OUT_PTR_1 != TX_IN_PTR_1) {
			REN1 = 0; // can't send and recieve at the same time
			TEN = 1;
			SBUF1 = TX_BUF_1[TX_OUT_PTR_1];
			TX_OUT_PTR_1 = ++TX_OUT_PTR_1 % TX_BUF_SIZE_1;
		}
		else {
			TX_EMPTY_1 = 1; // we are done when out ptr catches in ptr
			TEN = 0;
			REN1 = 1; // finished talking, now we listen
		}
	}
}

 


Note that UART1 is setup for half duplex communication.

Please don't copy the style of this code as it is old and I would have chosen to do things differently these days, but it does work.

Take a look at Mark A. Odell's code in the code section here at 8052.com for a better structured library.

http://www.8052.com/codelib/files/efdUartDriver.zip

--David

List of 38 messages in thread
TopicAuthorDate
Trouble with interrupt driven comms on 80C320 serial port 1            01/01/70 00:00      
   CLR ES1?            01/01/70 00:00      
      Good idea but not the solution            01/01/70 00:00      
         As Erik posted, may be the etc. part            01/01/70 00:00      
   I cant' tell if there is a problem in ...            01/01/70 00:00      
      Which ... are you worrying about?            01/01/70 00:00      
         How about commenting "etc"            01/01/70 00:00      
         please post as is, not all the ...            01/01/70 00:00      
            Again without the conditionals            01/01/70 00:00      
               this is NOT an ISR            01/01/70 00:00      
                  Why will jnb RI,$ screw up?            01/01/70 00:00      
                     stick a state machine in the ISR            01/01/70 00:00      
                        To interrupt or not...            01/01/70 00:00      
                           an example            01/01/70 00:00      
                              Avoid infinite loops like the plague            01/01/70 00:00      
                                 Back to the subject - why won't it interrupt?            01/01/70 00:00      
                                    Serial Port Interrupts            01/01/70 00:00      
                                       Yes, I think I've done this correctly            01/01/70 00:00      
                                          Vector Address...            01/01/70 00:00      
                                             I think I've done this correctly...            01/01/70 00:00      
                                                you had me there            01/01/70 00:00      
                                                   Serial port, not port            01/01/70 00:00      
                                          maybe not            01/01/70 00:00      
                                             ES1 is non-standard            01/01/70 00:00      
                                                probably the most common misumderstanding            01/01/70 00:00      
                                                   Thanks for clarification...            01/01/70 00:00      
                                             It works without interrupts...            01/01/70 00:00      
                                                then ...            01/01/70 00:00      
                                                   Even Better ...            01/01/70 00:00      
                                    maybe it does            01/01/70 00:00      
                                       Two things argue against this...            01/01/70 00:00      
   Dunno, but that's a very useful instruction            01/01/70 00:00      
   Dunno..            01/01/70 00:00      
      I have problem with serial port 1 on ds89c450 (www.maxim-ic            01/01/70 00:00      
         MUCH better description needed            01/01/70 00:00      
            not it is not language            01/01/70 00:00      
               Which register bank are you using?            01/01/70 00:00      
                  yes it works now            01/01/70 00:00      

Back to Subject List