|
// yz_INT_RDA.c by C-H Wu 2004/05/09
//
// 參閱 CCS 範例 EX_SISR.C Shows how to do RS232 serial interrupts
// EX_STISR.C Shows how to do RS232 transmit buffering w/ ISR
//
#ifdef __PCM__
#include <16F877A.H>
#byte RCSTA = 0x18
#else
#include <18F458.H>
#byte RCSTA = 0xFAB
#endif
#use delay(clock= 20000000)
#use rs232(baud = 115200, xmit= PIN_C6, rcv= PIN_C7)
//se rs232(baud = 115200, xmit= PIN_C6, rcv= PIN_C7, errors)
// 注意:本程式中 #use RS232 裡不能用 errors,會當機!請用這個解決問題
//
#bit OERR = RCSTA.1 // overrun
#bit CREN = RCSTA.4 // enable
void check_and_reset_HW_RS232(void)
{
if ( OERR ) // RS232 receiver buffer full !
{
CREN=0; delay_us(2); // 清除 RS232 receive error
CREN=1; // restart RS232, clear buffer!
}
}
#define my_RS232_buf_size 32
struct serial_buff {
int8 ptr;
int8 data [ my_RS232_buf_size ];
int1 got_cr;
int1 buf_full;
int8 errors : 3; // 3 bits
} my_rs232;
#int_RDA
void RDA_isr(void)
{
putc( my_rs232.data [ my_rs232.ptr ] = getc() );// echo back
if ( my_rs232.data [ my_rs232.ptr ] == '\r' ) my_rs232.got_cr = 1;
if (++my_rs232.ptr == my_RS232_buf_size ) my_rs232.buf_full = 1;
if ( my_rs232.got_cr||my_rs232.buf_full )
{ my_rs232.data [--my_rs232.ptr] = 0; // 字串結束碼
disable_interrupts ( INT_RDA ); // 關閉中斷
}
}
void main()
{
int8 i; my_rs232.ptr = 0;
enable_interrupts ( INT_RDA );
enable_interrupts ( GLOBAL );
printf("\n\r\n\n ex_int_RDA.c, 鍵入字串後請按 CR: ");
while(1)
{
if(my_rs232.got_cr || my_rs232.buf_full )
{ my_rs232.got_cr = my_rs232.buf_full = 0;
printf("\n\r\n Got: %s, length= %u", my_rs232.data, my_rs232.ptr );
my_rs232.ptr = 0; // reset data pointer
// --- 測試把 RS232 硬件 buffer (兩個 byte) 灌爆的效果 -----
//
// 在 delay_ms() 的 十秒鐘內敲四五次鍵盤試試看吧
//
printf("\r\n ISR disabled for 10 sec now, wait ");
for(i=0;i<10;i++) { putc('.'); delay_ms(1000); };
printf("\r\n ISR re-enabled, you may use keyboard now. ");
check_and_reset_HW_RS232(); // 灌爆後要重置才行!
//
// --- 測試 --- 結束 ---------------------------------------
enable_interrupts ( INT_RDA );
}
output_toggle ( PIN_A4 ); delay_ms( 200 ); // 閃閃 LED
}
} |
|