5-8. RS232 비동기통신예제 목표 : DSP28x 에는 2 개의비동기통신 (SCI) 이있다. EDU2812 KIT 에서 1 개의 SCI 는부트및데이터모니터링용으로사용하고, 나머지 1 개는 RS232C 형태로커넥터 (CN6) 에접속되어있다. 본예제에서는이 RS232C 통신을사용하여송수신인터럽트처리등에대해서학습해본 다. PC 에서특정문자를보내면일련의문자열로응답하는프로그램을작성해본다. 사용회로고찰 : CN6 MDXA RA2 SPICLKA 4 SPISTEA 3 2 TXD_A 1 1Kx4 1-2:Flash 2-3:Boot 2 4 6 8 10 RS232 1 3 5 7 9 3.3V R12 1K 1 2 3.3V 5 6 7 8 3 SW1 BOOT 5V RXD_A TXD_A /RESET CN8 1 2 3 4 5 6 BOOT 5V U4 5V 16 15 VCC C1+ RS232TX 14 GND V+ RS232RX 13 T1O C1-12 R1IN C2+ 11 R1O C2-10 T1I V- 9 T2I T2O R7 R2O R2I 120 TXD_B MAX232 RXD_B RealDSP 에서사용 : TTL 레벨 1 2 3 4 5 6 7 8 부트및모니터링용 C8 1uF C11 1uF C9 1uF C10 1uF RS232C 통신커넥터 RS232 통신기초 : START DATA D0 D1 D2 D3 D4 D5 D6 D7 STOP X16 클럭 데이터 일반통신비트형태 : 데이터 Sampling Point RealSYS (www.realsys.co.kr) - 152 -
START 비트 : 1 비트크기의 Low(0) 상태로데이터의시작을알린다. DATA 비트 : LSB first로실제데이터값을나타낸다. Parity 비트 : No/Even/Odd로설정이가능하고, 노이즈로 1비트가변경되었을때이의검출이가능하다. STOP 비트 : 1/1.5/2 크기로설정이가능하고, 데이터의끝을나타낸다. TTL 신호레벨 +5.0V +5.0V High(1) High(1) +2.4V 0.4V 노이즈마진 +2.0V +0.8V +0.4V +0V Low(0) 출력 Low(0) 입력 +0V RS232C 신호레벨 +15V +15V Space (Logic 0) Space (Logic 0) +5V -5V 2V 노이즈마진 +3V -3V Mark (Logic 1) Mark (Logic 1) -15V -15V 출력 입력 위의그림에서보면 TTL 신호레벨은 0.4V 정도의노이즈마진을갖는데비해 RS232C 레벨은 2V 의노이즈마진을가지므로노이즈에강하다. 특히 TTL 레벨은 Low 영역폭이 RealSYS (www.realsys.co.kr) - 153 -
0.8V 로매우좁아조그만노이즈가첨가되어도 High 로인식할수있다. 이해비해 RS232C 레벨은 Space(Logic 0) 와 Mark(Logic 1) 영역이대등하게영역을갖 고폭이넓으므로노이즈에강하다. 참조 : RS232C 의 + 전압영역은스페이스 (space) 라부르며 Logic 0 를의미하며, - 전압영 은마크 (Mark) 라부르고 Logic 1 을의미한다. DSP28x 의 SCI 살펴보기 : SCI 특징 : - 통신속도 : LSPCLK 클럭으로동작 - 2개의통신신호 : SCITXD, SCIRXD - 2개의인터럽트 : RXINT, TXINT RealSYS (www.realsys.co.kr) - 154 -
그림. SCI 전체구성도 - 16레벨송수신 FIFO - 자동통신속도검출로직 - 데이터비트수설정 : 1비트 ~ 8비트 - 스톱비트수설정 : 1비트또는 2비트 - 패리티체크 : EVEN / ODD 패리티 - 에러검출플래그패리티 (Parity) 에러, 오버런 (Overrun) 에러, 프레이밍 (Framing) 에러브레이크 (Break) 검출에러 RealSYS (www.realsys.co.kr) - 155 -
- 2 가지 Wake-up 멀티프로세서모드 Idle- 라인웨이크업 (wake up), Address 비트웨이크업 (wake up) 표. SCIA 레지스터 표. SCIB 레지스터 RealSYS (www.realsys.co.kr) - 156 -
SCI Communication Control Register (SCICCR) Address 7050h SCICCR 레지스터는문자형태, 프로토콜, 통신모드등의설정에관여한다. STOP_BITS ( 비트 7) : 스톱비트수 0 = 1 비트 1 = 2 비트 EVEN/ODD_PARITY ( 비트 6) : 패리티종류선택 ( 패리티가인에이블인경우 ) 0 = ODD 패리티 1 = EVEN 패리티 PARITY_ENABLE ( 비트 5) : 패리티인에이블 (enable) 0 = 사용안함 1 = 패리티사용함 LOOPBACK_ENA ( 비트 4) : 루프 (loop) 백 (back) 시험모드 0 = 루프백사용안함 1 = 루프백사용함 ADDR/IDLE_MODE ( 비트 3) : 멀티프로세서모드 ( 어드레스비트모드 ) 0 = 일반모드 (idle 라인모드 ) 1 = 어드레스비트모드 SCICHAR2 ~ 0 ( 비트2 ~ 0) : 데이터비트수데이터비트수설정표 : SCI Control Register 1 (SCICTL1) Address 7051h SCICTL1 레지스터는송수신인에이블제어, 슬립기능, 수신에러인터럽트, 소프트웨어 RealSYS (www.realsys.co.kr) - 157 -
리세트설정에관여한다. RX_ERR_INT_ENA ( 비트 6) : 수신에러인터럽트인에이블제어 0 = 수신에러인터럽트사용안함. 1 = 수신에러인터럽트사용, RX_ERROR 비트가세트되면, 인터럽트발생. SW_RESET ( 비트 5) : SCI 소프트웨어리세트 0 = 소프트웨어리세트걸림 1 = 리세트후에 SCI를정상적으로사용하려면 1로세트해야함. 소프트웨어후레지스터초기화값 : TXWAKE ( 비트 3) : SCI 송신 wakeup 방법선택 0 = 선택안함. 1 = 모드 ( 일반모드, 어드레스비트모드 ) 에따라다름일반모드 : TXWAKE에 1를쓰면, SCITXBUF에데이터를쓰면 1 데이터비트 idle 기간생성. 어드레스비트모드 : TXWAKE에 1를쓰면, SCITXBUF에데이터를쓰면, 그프레임의어드레스비트가 1로됨. SLEEP ( 비트 2) : SCI 슬립모드설정 0 = 슬립모드사용안함. 1 = 슬립모드사용함. TXENA ( 비트 1) : SCI 송신기능사용설정 0 = 송신기능사용안함 (disable) 1 = 송신기능사용함 (enable) RXENA ( 비트 0) : SCI 수신기능사용설정 0 = 수신기능사용안함 (disable) 1 = 수신기능사용함 (enable) RealSYS (www.realsys.co.kr) - 158 -
Baud-Select MSbyte Register (SCIHBAUD) Address 7052h Baud-Select LSbyte Register (SCILBAUD) Address 7053h SCIHBAUD & SCILBAUD 레지스터는통신속도설정에관여하며아래와같은식으로계 산됨. SCI 통신속도 = CLKOUT / ((BRR + 1)*8) BRR 값 = CLKOUT / ( 통신속도 x 8) - 1 SCI 통신속도테이블 : 통신속도 CPUCLK LSPCLK N BPS 산출 에러율 2400 150000000 37500000 1952 2400.154 0.006 4800 150000000 37500000 976 4797.851-0.045 9600 150000000 37500000 487 9605.533 0.058 19200 150000000 37500000 243 19211.066 0.058 38400 150000000 37500000 121 38422.131 0.058 57600 150000000 37500000 80 57870.370 0.469 115200 150000000 37500000 40 114329.268-0.756 SCI Control Register 2 (SCICTL2) Address 7054h TXRDY ( 비트 7) : 송신버퍼레디 (ready), 새로운송신데이터를받아들일수있음. 0 = SCITXBUF 사용중 1 = SCITXBUF가비어있어다음문자를받을수있음. TX_EMPTY ( 비트 6) : 송신 empty 플래그, SCITXBUF와 TXSHF 모두비어있음의미. 0 = 비어있지않음. 1= 모두비어있음 RX/BK_INT_ENA ( 비트 1) : 수신버퍼 / 브레이크인터럽트사용여부 0 = 사용암함 (disable) 1 = 사용 (enable) RealSYS (www.realsys.co.kr) - 159 -
TX_INT_ENA ( 비트 0) : 송신인터럽트인에이블 (enable) 0 = TXRDY 인터럽트사용안함.(enable) 1 = TXRDY 인터럽트사용함.(enable) Receiver Status Register (SCIRXST) Address 7055h SCIRXST는 SCI 의수신상태를관찰할수있는레지스터이다. RX_ERROR ( 비트 7) : 수신에러플래그 0 = No 1 = 에러플래그세트됨 RXRDY ( 비트 6) : 데이터수신완료상태 0 = 수신데이터없음. 1 = 수신완료, SCIRXBUF에서문자를읽을수있는상태. BRKDT ( 비트 5) : 브레이크검출플래그 0 = No 브레이크 1 = 브레이크조건 FE ( 비트 4) : 프레이밍에러발생 0 = No 프레이밍 1 = 프레이밍에러발생 OE ( 비트 3) : 오버런 (overrun) 에러플래그 0 = No 오버런 1 = 오버런에러발생 PE ( 비트 2) : 패리티에러발생 0 = No 패리티에러 1 = 패리티에러발생 RXWAKE ( 비트 0) : 수신 wakeup 검출플래그 0 = No 웨이크업 1 = 수신웨이크업발생 비트 5 에서비트 2 까지어느하나라도 1 이면 RX_ERROR 플래그가세트됨. RX/BK_INT_ENA = 1 이고, RXRDY 또는 BRKDT 가 1 이면인터럽트발생. RealSYS (www.realsys.co.kr) - 160 -
Emulation Data Buffer Register (SCIRXEMU) Address 7056h 에뮬레이터에서사용하는데이터수신버퍼레지스터임. Receiver Data Buffer (SCIRXBUF) Address 7057h 수신데이터버퍼 Transmit Data Buffer Register (SCITXBUF) Address 7059h 송신데이터버퍼 SCI Priority Control Register (SCIPRI) Address 705Fh SCI_SOFT( 비트 4), SCI_FREE ( 비트 3) : 에뮬레이터제어비트 SCI_SOFT SCI_FREE 에뮬레이터정지시기능 0 0 즉시정지 1 0 현재동작송수신마친후정지 X 0 에뮬레이터관계없이동작 RealSYS (www.realsys.co.kr) - 161 -
소스프로그램살펴보기 설명 1 >> SCIB 통신포트기능설정 GpioMuxRegs.GPGMUX.all=0x0030; /* GPGMUX: GPIO_G function 0=IOP,1=FUN bit5 1: SCIRXDB,PG5 ;FUN bit4 1: SCITXDB,PG4 ;FUN */ GpioMuxRegs.GPGDIR.all=0x10; // DIR: 1=output,0=input // 5(RXDB),4(TXDB),3,2,1,0 // 0 1 0 0 0 0 = 0x10 EDIS; 설명 2 >> SCIB 통신포트초기화 : sci.c 에있음 void sci_init(void){ // SCI(UART) init. // Note: Clocks were turned on to the SCIB peripheral // in the InitSysCtrl() function ScibRegs.SCIFFTX.all = 0xa000; ScibRegs.SCIFFCT.all = 0x4000; // FIFO reset // Clear ABD(Auto baud bit) ScibRegs.SCICCR.all =0x0007; ScibRegs.SCICTL1.all =0x0003; // 1 stop bit, No loopback // No parity,8 char bits, // async mode, idle-line protocol // enable TX, RX, internal SCICLK, // Disable RX ERR, SLEEP, TXWAKE ScibRegs.SCICTL2.bit.RXBKINTENA =1; // RX/BK INT ENA=1, ScibRegs.SCICTL2.bit.TXINTENA =1; // TX INT ENA=1, ScibRegs.SCIHBAUD = BRR_VAL >> 8; // High Value ScibRegs.SCILBAUD = BRR_VAL & 0xff; // Low Value RealSYS (www.realsys.co.kr) - 162 -
ScibRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset EALLOW; // This is needed to write to EALLOW protected registers PieVectTable.RXBINT = &scib_rx_isr; 수신인터럽트함수 PieVectTable.TXBINT = &scib_tx_isr; 송신인터럽트함수 EDIS; // This is needed to disable write to EALLOW protected registers // Enable CPU INT9 for SCI-B IER = M_INT9; // Enable SCI-B RX INT in the PIE: Group 9 interrupt 3 PieCtrlRegs.PIEIER9.bit.INTx3 = 1; // Enable SCI-B TX INT in the PIE: Group 9 interrupt 4 PieCtrlRegs.PIEIER9.bit.INTx4 = 1; 설명3 >> 통신관련 define #define CPUCLK 150000000L #define LSPCLK (CPUCLK/4) #define BAUDRATE 9600L 9600 bps로시험 #define BRR_VAL (LSPCLK/(8*BAUDRATE)-1) #define SCI_TX_START { ScibRegs.SCICTL2.bit.TXINTENA=1; ScibRegs.SCITXBUF = sci_tx_buf[sci_tx_pos++]; if(sci_tx_pos >= SCI_TX_BUF_SIZE) sci_tx_pos=0; #define SCI_TX_STOP ScibRegs.SCICTL2.bit.TXINTENA=0 #define SCI_TX_BUF_SIZE 100 설명4 >> 송수신인터럽트루틴 interrupt void scib_tx_isr(void){ 송신인터럽트루틴 if(sci_tx_pos!= sci_tx_end){ ScibRegs.SCITXBUF = sci_tx_buf[sci_tx_pos++]; if(sci_tx_pos >= SCI_TX_BUF_SIZE) sci_tx_pos = 0; else{ RealSYS (www.realsys.co.kr) - 163 -
SCI_TX_STOP; // Acknowledge this interrupt to recieve more interrupts from group 9 PieCtrlRegs.PIEACK.all = PIEACK_GROUP9; 송신버퍼내용이있으면데이터송신, 더이상없으면송신중지 interrupt void scib_rx_isr(void){ 수신인터럽트루틴 rxd = ScibRegs.SCIRXBUF.all; sci_puts(" n rreceived char = "); sci_hex2(rxd); SCI_TX_START; // Acknowledge this interrupt to recieve more interrupts from group 9 PieCtrlRegs.PIEACK.all = PIEACK_GROUP9; 1문자가수신되면일련의문자열을송신해본다. 설명5 >> main 루틴에서 void main(void){ // for SCI-B sci_init(); lcd_gotoxy(0,0); lcd_puts("sci test,9600bps"); lcd_gotoxy(0,1); lcd_puts(" rxd= (0x )"); AD_START; while(1){ mcnt++; ad0 = AdcRegs.ADCRESULT0>>4; EvaRegs.CMPR1 = ad0; key = IN_KEY; OUT_LED(key); lcd_gotoxy(0,1); lcd_hex4(mcnt); RealSYS (www.realsys.co.kr) - 164 -
lcd_gotoxy(9,1); lcd_putc(rxd); lcd_gotoxy(13,1); lcd_hex2(rxd); if(key_code & KEY_PRESSED) key_process(); if(key_code & KEY_CONT) cont_key_process(); delay_ms(100); 설명6 >> 송신인터럽트처리링버퍼를형성하여송신인터럽트로처리 송신버퍼처리 Tx_pos 송신버퍼 1 2 Tx_end 3 데이터송신버퍼에써넣기 :. 송신데이터를송신버퍼에쓰고 Tx_pos를증가시킨다. 송신 :. TX 인터럽트를사용하여데이터를송신한다.. Tx_end를증가한다. 송신종료 :. 만일 Tx_pos와 Tx_end가같으면송신을종료한다. 폴링송신방식 : 일렬의문자열을보낼때, 이전데이터가전송완료하기까지기다리다가 완료하면이어서다음문자를전송하는방식으로진행. 인터럽트방식 : 보내고자하는문자열을링버퍼에먼저써넣고, 송신을출발시키면 ( 첫 RealSYS (www.realsys.co.kr) - 165 -
번째문자보냄 ) 다음문자부터는송신인터럽트로처리, 링버퍼의데이터 가모두전송되면송신을중지함. 실행관찰 LCD 에수신문자표시 RS232 커넥터접속 하이퍼터미널실행 : 9600bps 1 문자를입력하면 Received char = xx 로응답. RealSYS (www.realsys.co.kr) - 166 -