/********************************************************************** * File demo_int.C - Rel. 1.1 compile with uC/51 V. 1.10.7 * * GRIFO(R) via Dell'Artigiano 8/6 40016 S. Giorgio di Piano (BO) * * Cards: GPC 550 d.s. 200702 e DEB01 o TIO16 * * Tel. +39 051 892052 Fax. +39 051 893661 * * http://www.grifo.com http://www.grifo.it * * sales@grifo.it tech@grifo.it grifo@grifo.it * * by Graziano Gaiba del 09.09.03 * ********************************************************************** Questa seriale software e' stata ricavata dal codice dell'esempio RS232_C2.C (C) 2002 WWW.WICKENHAEUSER.COM nella cartella \src\rs232_c. Per adattarla alla GPC(r) 550 e' stato necessario spostare l'interrupt di di ricezione sul pin P3.2 (/Int0). Inoltre, per compatibilita' con il programma demo, il viene usato timer0. */ #include #include #include "reg552.h" #include "demo_int.h" #define TRBIT TR0 #define THREG TH0 #define TLREG TL0 #define TENA ET0 #define TXPIN P3.4 #define RXPIN P3.2 #define LF 0x0A #define CRET 0x0D // Driver in Assembler #asm ; *** Calculate: BDxyz =XTAL/12/xyz *** ; (XTAL/12) is the Timers input clock, the divider is either an 8 bit or an 16 bit number ; In the SLOW-MODE the timer is running as 16 bit timer, FAST uses the 8 bit mode. BAUD_CNT = CPU_SPEED/12/BAUDRATE SLOWMODE = BAUD_CNT > 200 ; Determine Timer Mode ; Local variables .segment _com2data, sclass dram, notext c2stat: .ds.b 1 ; Status (Steps of 2) c2byte: .ds.b 1 ; Sent/Received Byte .segment _int0, org $03 int0_irq: ljmp int0 ; jump to 'bigger' code space .segment _t0_irq, org $b ; Fix segment @ $000B t0_irq: ; no .export required! ljmp timer ; jump to 'bigger' code space .segment _com2 ; this is the 'bigger' codespace int0: mov c2stat,#24 ; Receive Byte! clr EX0 ; Disable INT0 .if SLOWMODE BD32F = - BAUD_CNT*3/2+50 mov THREG,#(BD32F)>>8 mov TLREG,#(BD32F)&255 .else mov TLREG,#256-(BAUD_CNT*3)/2+50 ; Skip Startbit and add. Cycles .endif clr TF0 ; Clear IRQ-Flag setb TRBIT ; Timer RUN setb TENA ; Enabele IRQ clr IE0 ; Clear Edge-Flag reti timer: .if SLOWMODE BD11F = -BAUD_CNT+12 mov THREG,#(BD11F)>>8 mov TLREG,#(BD11F)&255 .endif push PSW push ACC push DPL push DPH mov DPTR,#stab inc c2stat mov A,c2stat ; Get Status movc A,@A+DPTR push ACC ; Highbyte mov A,c2stat ; Get Status 2 dec A ; swap H/L inc c2stat movc A,@A+DPTR push ACC ; Lowbyte ret ; jumpto... tx_done: mov c2stat,#0 ; Ready again clr TRBIT ; Timer STOP setb EX0 ; enable INT0 sjmp t1_x tx_stopbit: setb TXPIN sjmp t1_x tx_startbit: clr TXPIN ; Ok sjmp t1_x tx_bit: mov A,c2byte rrc A mov TXPIN,C mov c2byte,A ; LSB first t1_x: pop DPH pop DPL pop ACC pop PSW reti rx_bit: mov C,RXPIN ; Get Bit mov A,c2byte rrc A mov c2byte,A ; insert Bit rx_stopbit: ; nothing to do! sjmp t1_x rx_done: mov c2stat,#128 ; Char Ready clr TRBIT ; Timer STOP clr IE0 ; Clear Edge-Flag setb EX0 ; enable INT0 sjmp t1_x ; *** Jump-Table stab: .dc.w tx_done ; 0 NIX ; * SEND .dc.w tx_startbit ; 2 .dc.w tx_bit ; 4 0 Transmit 8 Bits .dc.w tx_bit ; 6 1 .dc.w tx_bit ; 8 2 .dc.w tx_bit ; 10 3 .dc.w tx_bit ; 12 4 .dc.w tx_bit ; 14 5 .dc.w tx_bit ; 16 6 .dc.w tx_bit ; 18 7 .dc.w tx_stopbit ; 20 .dc.w tx_done ; 22 ; * RECEIVE .dc.w rx_bit ; 24 0 Receive 8 Bits .dc.w rx_bit ; 26 1 .dc.w rx_bit ; 28 2 .dc.w rx_bit ; 30 3 .dc.w rx_bit ; 32 4 .dc.w rx_bit ; 34 5 .dc.w rx_bit ; 36 6 .dc.w rx_bit ; 38 7 .dc.w rx_stopbit ; 40 .dc.w rx_done ; 42 ; * Send Byte over simulated COM2 .export _com2_putc _com2_putc: clr TENA ; Timer IRQ dis. clr EX0 ; INT0 IRQ dis. (transmitting!) mov c2byte,R7 ; Set Char mov c2stat,#2 ; Start Transmitting .if SLOWMODE mov THREG,#255 mov TLREG,#200 .endif clr TF0 ; Clear IRQ-Flag setb TRBIT ; Timer RUN setb TENA ; Enable IRQ ; * Wait polling until sent! ?c2p1: mov A,c2stat anl A,#127 ; Mask MSB jnz ?c2p1 ; wait until sent ret ; * Get Byte from simulated COM2 .export _com2_getc _com2_getc: mov A,c2stat ; Get Status cjne A,#128,_com2_getc ; 128: Byte received mov R7,c2byte ; get Byte mov R6,#0 mov c2stat,R6 ; Clear Status ret .export _com2_init ; * Got Byte from simulated COM2? .export _com2_kbhit _com2_kbhit: mov R7,#0 mov R6,#0 mov A,c2stat ; Get Status cjne A,#128,?c2k1 ; 128: Byte received inc R7 ; If Byte was 0: return 1 ?c2k1: ret ; * Init COM2 _com2_init: clr ET0 ; Timer 0 IRQ disable clr EX0 ; INT0 IRQ disable orl IP, #%00000011 setb IT0 ; INT0 Falling Edge anl TMOD,#$F0 .if SLOWMODE orl TMOD,#$01 ; Timer 0 Mode 1 (16 Bit Counter) .else orl TMOD,#$02 ; Timer 0 Mode 3 (8 Bit Reload) mov TH0,#256-BAUD_CNT ; Reload Value .endif mov c2stat,#0 ; Status Ready! clr IE0 ; Clear Edge-Flag setb EX0 ; enable INT0 ret #endasm // This definition is not to be seen by default, because it needs // So we include it manually... extern int _doprnt( void (*iofunk)(uchar) reentrant, far char* pfmt, va_list (fap)); void com2_printf(far char* pfmt, ...){ va_list(ap); va_start(ap,pfmt); _doprnt(com2_putc , pfmt, ap); // And send it to COM2... } void iniser(unsigned long baud) /* Inizializza la linea seriale hardware con: Bit x chr = 8 Stop bit = 1 Parity = None Baud rate = baud usando come baud rate generator il timer 1. */ { SCON=0x052; // Modo 1, abilita ricevitore TMOD&=0x00F; // Timer 1 in modo auto-reload TMOD|=0x020; TR1=0; // Stop al TIMER 1 TH1=256-((2*22118400)/(384*baud)); // baud a 22.1184 MHz PCON=PCON|0x080; // Setta SMOD=1 per baud rate alti TR1=1; // Start al TIMER 1 } /* Procedura che effettua un ritardo di rit millisecondi, tramite un ciclo software calibrato a 22.1184 MHz */ void ritardo (unsigned int rit) { unsigned int r; while (rit>0) { for (r=0; r<150; r++); // Valore sperimentale per ritardo di 1 msec. con 80c32 rit--; } } void clrscr(void) /* Effettua la funzione di clear screen per una generica console */ { unsigned char r; putc(CRET); for (r = 0 ; r < 25 ; r++) { putc(LF); // Trasmette 25 Line Feed } //endfor } void main(void) { unsigned char dato; ritardo(2); iniser(19200); com2_init(); TI=RI=0; ES=1; EA=1; clrscr(); // Cancello lo schermo puts(""); puts("********* Demo per l'utilizzo della seriale software su JP4 **********"); puts(""); puts("Per il corretto funzionamento del demo, collegare un dispositivo seriale RS 232"); puts("esterno su JP4 configurato con: Baud Rate = 19200, Data Bit = 8, Stop Bit = 1,"); puts("Nessuna Parita'"); puts(""); puts("Premere un tasto per continuare..."); while(! kbhit()) // Attende la pressione di un tasto ; getc(); // Rimuove il tasto dal buffer seriale puts(""); puts("I caratteri ricevuti dal dispositivo RS 232 esterno vanno sul monitor,"); puts("i caratteri digitati sulla tastiera del PC vanno al dispositivo esterno,"); puts("premere F sul PC per terminare."); com2_printf("********* Demo per l'utilizzo della seriale software su JP4 **********\n"); do { if(kbhit()) // Se tasto premuto sul PC { com2_putc(dato=getc()); // Leggilo in dato e mandalo al terminale } if(com2_kbhit()) // Se c'e' un byte nella seriale software... putc(com2_getc()); // ...leggilo e stampalo. } while(toupper(dato)!='F'); // Esci se premuto 'f' o 'F' puts("Loop infinito"); while(1) ; }