/********************************************************************** * File demo_int.C - Rel. 1.1 con uC/51 V. 1.10.10 * * GRIFO(R) via Dell'Artigiano 8/6 40016 S. Giorgio di Piano (BO) * * Schede: GPC F2 d.s. 130688 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 29.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. La seriale ausiliaria della GPC(r) F2 e' in grado solo di trasmettere, quindi la ricezione e' simulata, mai bloccante e ritorna sempre 0. Inoltre, per compatibilita' con il programma demo, il viene usato timer0. */ #include #include #include #include #include "demo_int.h" #define TRBIT TR0 #define THREG TH0 #define TLREG TL0 #define TENA ET0 #define TXPIN P1.7 #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 _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 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 ; *** 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 ; * 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 R7,#0 ; Always return 0 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 ; Always return 0 ret ; * Init COM2 _com2_init: clr ET0 ; Timer 0 IRQ disable 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! 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*11059200)/(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(9600); com2_init(); TI=RI=0; ES=1; EA=1; clrscr(); // Cancello lo schermo puts(""); puts("********* Demo per l'utilizzo della seriale software su CN3 **********"); puts(""); puts("Per il corretto funzionamento del demo, collegare il connettore CN3 della"); puts("GPC(r) F2 al connettore K1 della G02 I/O, collegare un dispositivo RS 232"); puts("esterno su K6 della G02 I/O configurato con: Baud Rate = 19200, Data Bit = 8,"); puts("Stop Bit = 1, Nessuna Parita'"); puts("Si ricorda che la seriale ausiliaria (software) della GPC(r) F2 e' solamente"); puts("in trasmissione."); 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 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 CN3 **********\n"); do { if(kbhit()) // Se tasto premuto sul PC { com2_putc(dato=getc()); // Leggilo in dato e mandalo al terminale // com2_kbhit() e com2_getc() esistono per compatibilita' // ma restituiscono sempre 0 } } while(toupper(dato)!='F'); // Esci se premuto 'f' o 'F' puts("Loop infinito"); while(1) ; }