Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
8XC196Kx,8XC196Jx,87C196CA microcontroller family user's manual.1995.pdf
Скачиваний:
73
Добавлен:
23.08.2013
Размер:
4 Мб
Скачать
☆

8XC196Kx, Jx, CA USER’S MANUAL

CAUTION

For mode 0 receptions, the BAUD_VALUE must be 0002H or greater. Otherwise, the resulting data in the receive shift register will be incorrect.

The reason for this restriction is that the receive shift register is clocked from an internal signal rather than the signal on TXD. Although these two signals are normally synchronized, the internal signal generates one clock before the first pulse transmitted by TXD and this first clock signal is not synchronized with TXD. This clock signal causes the receive shift register to shift in whatever data is present on the RXD pin. This data is treated as the leastsignificant bit (LSB) of the reception. The reception then continues in the normal synchronous manner, but the data received is shifted left by one bit because of the false LSB. The seventh data bit transmitted is received as the most-significant bit (MSB), and the transmitted MSB is never shifted into the receive shift register.

Using XTAL1 at 16 MHz, the maximum baud rates are 2.76 Mbaud (SP_BAUD = 8002H or 0002H) for mode 0 and 1.0 Mbaud for modes 1, 2, and 3. Table 7-3 shows the SP_BAUD values for common baud rates when using a 16 MHz XTAL1 clock input. Because of rounding, the BAUD_VALUE formula is not exact and the resulting baud rate is slightly different than desired. Table 7-3 shows the percentage of error when using the sample SP_BAUD values. In most cases, a serial link will work with up to 5.0% difference in the receiving and transmitting baud rates.

Table 7-3. SP_BAUD Values When Using XTAL1 at 16 MHz

Baud Rate

SP_BAUD Register Value (Note 1)

 

% Error

 

 

 

 

Mode 0

Mode 1, 2, 3

Mode 0

Mode 1, 2, 3

 

 

 

 

 

 

9600

8340H

8067H

0.04

0.16

4800

8682H

80CFH

0.02

0.16

2400

8D04H

81A0H

0.01

0.08

1200

9A0AH

8340H

0

0.04

300

E82BH

8D04H

0

0.01

NOTE:

1.Bit 15 is always set when XTAL1 is selected as the clock source for the baud-rate generator.

7.4.4Enabling the Serial Port Interrupts

The serial port has both a transmit interrupt (TI) and a receive interrupt (RI). To enable an interrupt, set the corresponding mask bit in the interrupt mask register (see Table 7-2 on page 7-2) and execute the EI instruction to globally enable servicing of interrupts. See Chapter 5, “Standard and PTS Interrupts,” for more information about interrupts.

7-12

SERIAL I/O (SIO) PORT

7.4.5Determining Serial Port Status

You can read the SP_STATUS register (Figure 7-8) to determine the status of the serial port. Reading SP_STATUS clears all bits except TXE. For this reason, we recommend that you copy the contents of the SP_STATUS register into a shadow register and then execute bit-test instructions such as JBC and JBS on the shadow register. Otherwise, executing a bit-test instruction clears the flags, so any subsequent bit-test instructions will return false values. You can also read the interrupt pending register (see Table 7-2 on page 7-2) to determine the status of the serial port interrupts.

SP_STATUS

Address:

1FB9H

 

Reset State:

0BH

The serial port status (SP_STATUS) register contains bits that indicate the status of the serial port.

7

 

 

 

 

 

 

 

 

 

0

RPE/RB8

RI

 

TI

FE

 

TXE

 

OE

—

—

 

 

 

 

 

 

 

 

 

 

 

Bit

Bit

 

 

 

Function

 

 

Number

Mnemonic

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

7

RPE/RB8

Received Parity Error/Received Bit 8

 

 

 

 

 

 

RPE is set if parity is disabled (SP_CON.2=0) and the ninth data bit

 

 

 

received is high.

 

 

 

 

 

 

 

 

 

RB8 is set if parity is enabled (SP_CON.2=1) and a parity error occurred.

 

 

 

Reading SP_STATUS clears this bit.

 

 

 

 

 

 

 

 

 

 

 

 

6

RI

Receive Interrupt

 

 

 

 

 

 

 

 

 

This bit is set when the last data bit is sampled. Reading SP_STATUS

 

 

 

clears this bit.

 

 

 

 

 

 

 

 

 

This bit need not be clear for the serial port to receive data.

 

 

 

 

 

 

 

 

 

 

5

TI

Transmit Interrupt

 

 

 

 

 

 

 

 

 

This bit is set at the beginning of the stop bit transmission. Reading

 

 

 

SP_STATUS clears this bit.

 

 

 

 

 

 

 

 

 

 

 

 

4

FE

Framing Error

 

 

 

 

 

 

 

 

 

This bit is set if a stop bit is not found within the appropriate period of

 

 

 

time. Reading SP_STATUS clears this bit.

 

 

 

 

 

 

 

 

 

 

 

3

TXE

SBUF_TX Empty

 

 

 

 

 

 

 

 

 

This bit is set if the transmit buffer is empty and ready to accept up to two

 

 

 

bytes. It is cleared when a byte is written to SBUF_TX.

 

 

 

 

 

 

 

 

 

 

2

OE

Overrun Error

 

 

 

 

 

 

 

 

 

This bit is set if data in the receive shift register is loaded into SBUF_RX

 

 

 

before the previous bit is read. Reading SP_STATUS clears this bit.

 

 

 

 

 

 

1:0

—

Reserved. These bits are undefined.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Figure 7-8. Serial Port Status (SP_STATUS) Register

7-13

8XC196Kx, Jx, CA USER’S MANUAL

The receiver checks for a valid stop bit. Unless a stop bit is found within the appropriate time, the framing error (FE) bit in the SP_STATUS register is set. When the stop bit is detected, the data in the receive shift register is loaded into SBUF_RX and the receive interrupt (RI) flag is set. If this happens before the previous byte in SBUF_RX is read, the overrun error (OE) bit is set. SBUF_RX always contains the latest byte received; it is never a combination of the two bytes.

The receive interrupt (RI) flag indicates whether an incoming data byte has been received. The transmit interrupt (TI) flag indicates whether a data byte has finished transmitting. These flags also set the corresponding bits in the interrupt pending register. A reception or transmission sets the RI or TI flag in SP_STATUS and the corresponding interrupt pending bit. However, a software write to the RI or TI flag in SP_STATUS has no effect on the interrupt pending bits and does not cause an interrupt. Similarly, reading SP_STATUS clears the RI and TI flags, but does not clear the corresponding interrupt pending bits. The RI and TI flags in the SP_STATUS and the corresponding interrupt pending bits can be set even if the RI and TI interrupts are masked.

The transmitter empty (TXE) bit is set if SBUF_TX and its buffer are empty and ready to accept up to two bytes. TXE is cleared as soon as a byte is written to SBUF_TX. One byte may be written if TI alone is set. By definition, if TXE has just been set, a transmission has completed and TI is set.

The received parity error (RPE) flag or the received bit 8 (RB8) flag applies for parity enabled or disabled, respectively. If parity is enabled, RPE is set if a parity error is detected. If parity is disabled, RB8 is the ninth data bit received in modes 2 and 3.

7.5PROGRAMMING EXAMPLE USING AN INTERRUPT-DRIVEN ROUTINE

This programming example is an interrupt-driven “putchar” and “getchar” routine that allows you to set the size of the transmit and receive buffers, the baud rate, and the operating frequency.

#pragma model(kr)

#pragma interrupt(receive=28,transmit=27)

#ifdef EVAL_BOARD

 

/*

Reserve the 9 bytes required by eval board

*/

char

reserve[9];

 

#pragma locate(reserve=0x30)

 

#else

 

 

/*

Initialize the chip configuration bytes

*/

const unsigned int ccr[2] = {0x20FF,0x20DE}; #pragma locate (ccr = 0x2018)

#endif

7-14

SERIAL I/O (SIO) PORT

#define TRANSMIT_BUF_SIZE 20

 

#define RECEIVE_BUF_SIZE

20

 

#define WINDOW_SELECT

0x1F

 

#define

FREQUENCY (long)16000000

/* 16 MHz */

#define

BAUD_RATE_VALUE 9600

 

#define BAUD_REG ((unsigned int)(FREQUENCY/((long)BAUD_RATE_VALUE*16)-1)+0x8000)

#define

RI_BIT

0x40

 

 

#define

TI_BIT

0x20

 

 

unsigned char

status_temp;

 

 

/*

image of

SP_STATUS to preserve the RI and TI bits

on

a read. */

/*

receive and transmit buffers and their indexes

*/

 

unsigned char trans_buff[TRANSMIT_BUF_SIZE]; unsigned char receive_buff[RECEIVE_BUF_SIZE];

char begin_trans_buff,end_trans_buff; char end_rec_buff,begin_rec_buff;

/* declares and locates the special function registers */

volatile register unsigned char port2_reg, port2_dir, port2_mode; volatile register unsigned char wsr;

volatile unsigned char sbuf_tx, sbuf_rx, SP_STATUS, sp_con; volatile unsigned char int_mask1, int_pend1;

volatile unsigned int sp_baud;

#pragma locate(sbuf_tx=0xba,sbuf_rx=0xb8,SP_STATUS=0xb9h) #pragma locate(sp_con=0xbb,sp_baud=0xbc)

#pragma locate(int_mask1=0x13,int_pend1=0x12)

#pragma locate(wsr=0x14)

#pragma locate(port2_reg = 0xcd) #pragma locate(port2_dir = 0xcb) #pragma locate(port2_mode = 0xc9)

void

transmit(void)

/*

serial interrupt routine */

 

{

 

 

 

 

 

wsr = WINDOW_SELECT;

 

 

 

 

status_temp |= SP_STATUS;

/*

image SP_STATUS into status_temp

*/

/*

transmit a character if there is a character in the buffer */

 

if(begin_trans_buff!=end_trans_buff)

 

 

 

{

 

 

 

 

 

sbuf_tx=trans_buff[begin_trans_buff];

/* transmit character

*/

/*

The next statement makes the buffer circular by starting over when the

 

index reaches the end of the buffer.

*/

 

 

if(++begin_trans_buff>TRANSMIT_BUF_SIZE - 1)begin_trans_buff=0;

 

 

status_temp &= (~TI_BIT);

 

/* clear TI bit in status_temp.

*/

 

}

 

 

 

 

}

 

 

 

 

 

7-15

8XC196Kx, Jx, CA USER’S MANUAL

void

receive(void)

/*

serial interrupt routine */

{

 

 

 

 

 

wsr = WINDOW_SELECT;

 

 

 

 

status_temp |= SP_STATUS;

/*

image SP_STATUS into status_temp */

/*

If the input buffer is full, the last character will be ignored,

and the BEL character is output to the terminal. */

if(end_rec_buff+1==begin_rec_buff || (end_rec_buff==RECEIVE_BUF_SIZE-1 &&

 

!begin_rec_buff))

 

 

 

 

 

{

 

 

 

 

 

; /* input overrun code

*/

 

 

 

 

}

 

 

 

 

else

 

 

 

 

 

 

{

 

 

 

 

/*

The next statement makes the buffer circular by starting over when the

 

index reaches the end of the buffer.

 

*/

 

if(++end_rec_buff > RECEIVE_BUF_SIZE

- 1) end_rec_buff=0;

 

receive_buff[end_rec_buff]=sbuf_rx;

/*

place character in buffer */

 

}

 

 

 

 

status_temp &=

(~RI_BIT);

/*

clear RI bit in status_temp. */

int putchar(int

c)

 

 

 

{

 

 

 

 

 

/*

remain in loop while the buffer is full. This is done by checking

 

the end of

buffer index to

make sure it does not overrun the

 

beginning of buffer index.

The while instruction checks the case

 

when the end index is one less than the beginning index and at the

 

end of the

buffer when the

beginning index may be equal to 0 and

 

the end buffer index may be at the buffer end.

*/

while((end_trans_buff+1==begin_trans_buff)|| (end_trans_buff==TRANSMIT_BUF_SIZE -1 && !begin_trans_buff));

trans_buff[end_trans_buff]=c;

/*

put character in buffer */

if(++end_trans_buff>TRANSMIT_BUF_SIZE - 1)

/*

make buffer appear circular */

end_trans_buff=0;

 

 

 

if(status_temp & TI_BIT) int_pend1 |= 0x08;

/* If transmit buffer was empty,

 

 

then cause an interrupt to

 

 

start transmitting. */

}

 

 

 

unsigned char getchar()

 

 

{

 

 

 

while(begin_rec_buff==end_rec_buff);

/*

remain in loop while there is

 

 

not a character available. */

if(++begin_rec_buff>RECEIVE_BUF_SIZE - 1)

/*

make buffer appear circular */

begin_rec_buff=0;

 

 

 

return(receive_buff[begin_rec_buff]);

/* return the character in buffer */

main()

 

 

 

{

 

 

 

char c;

 

 

 

wsr=WINDOW_SELECT;

 

 

 

sp_baud = BAUD_REG;

/* set baud rate as described in Figure 7-7 on page 7-10*/

sp_con = 0x09;

/* mode 1, no parity, receive enabled, no 9th bit */

status_temp=SP_STATUS;

7-16

SERIAL I/O (SIO) PORT

port2_reg |= 0xFF; port2_dir &= 0xFE; port2_mode |= 0x03;

wsr=0; end_rec_buff=0; begin_rec_buff=0; end_trans_buff=0; begin_trans_buff=0; status_temp = TI_BIT; int_mask1=0x18;

enable();

/*

Init port2

reg */

/*

TXD output

 

*/

/*

p2.4-6 lsio

*/

/* initialize buffer

pointers

*/

/* allow for initial

transmission

*/

/*

enable

the serial

port interrupt

*/

/*

global

enable of interrupts

*/

while((c=getchar()) != 0x1b) /* stay in loop until escape key pressed */ printf("key pressed = %02X\n\r",c);

}

7-17

8

Synchronous Serial

I/O (SSIO) Port

Соседние файлы в предмете Электротехника