delay совместно с UltraLogik использовать, конечно, не стоит. Лучше пользоваться встроенными в UL таймерами. Связано это, я думаю, с тем, что UL перепрограммирует системный таймер под свои нужды. А delay использует его для расчета количества циклов, необходимых для задержки.
Что касается работы с портами в CPU188, достаю покрытый пылью исходник соответствующего модуля. Наверняка что-то в нем нужно подправить, но по RS-232 он работал (и до сих пор, надеюсь, работает
). Здесь используется прямой доступ к портам. Как им пользоваться, думаю, разберётесь.
=== начало ser188.c
#include <dos.h>
#include <conio.h>
#include "am188es.h"
#include "uart188.h"
#include "serialx.h"
static unsigned intrpt = 0x11;
static void interrupt (*old_handler)();
static unsigned setup = 0;
static int transmition = 0;
void interrupt new_handler()
{
static unsigned state;
static unsigned char rbyte;
static unsigned char sbyte;
state = inpw (ASYNC_SP1STS);
if (state & ASYNC_RDR) // byte received
{
rbyte = inpw (ASYNC_SP1RD); // get byte
if (state & (ASYNC_FER | ASYNC_OER | ASYNC_PER)) // errors
{
_AX = 0;
outp (ASYNC_SP1STS, _AL); // clear errors
}
else
{
async_byte_received (rbyte);
}
}
if (transmition && (state & ASYNC_THRE)) // send byte
{
sbyte = async_byte_send();
outp (ASYNC_SP1TD, sbyte);
}
_AX = intrpt;
outp (IC_EOI, _AL); // end of interrupt
};
// prototypes for these functions are in serialx.h:
void async_disable_transmit (void)
{
setup &= ~ASYNC_TXIE; // disable interrupts
_AX = setup;
outp (ASYNC_SP1CT, _AL);
//setup &= ~ASYNC_TMODE; // disable transmit
//_AX = setup;
//outp (ASYNC_SP1CT, _AL);
//_AX = inpw (0xff7a) | 0x0008; // disable RS-485 transmitter
//outp (0xff7a, _AL); // for COM2
transmition = 0;
};
void async_enable_transmit (void)
{
transmition = 1;
//_AX = inpw (0xff7a) & ~0x0008; // enable RS-485 transmitter
//outp (0xff7a, _AL); // for COM2
//setup |= ASYNC_TMODE; // enable transmit
setup |= ASYNC_TXIE; // enable interrupts
_AX = setup;
outp (ASYNC_SP1CT, _AL);
};
void async_disable_receive (void)
{
//setup &= ~ASYNC_RMODE; // disable receive
setup &= ~ASYNC_RXIE; // disable interrupts
_AX = setup;
outp (ASYNC_SP1CT, _AL);
};
void async_enable_receive (void)
{
//setup |= ASYNC_RMODE; // enable receive
setup |= ASYNC_RXIE; // enable interrupts
_AX = setup;
outp (ASYNC_SP1CT, _AL);
};
void async_install_handler (void)
{
old_handler = _dos_getvect (intrpt);
_dos_setvect (intrpt, new_handler);
};
void async_unmask_interrupts (void)
{
unsigned mask;
mask = inpw (IC_SP1CON);
mask &= ~IC_MSK;
_AX = mask;
outp (IC_SP1CON, _AX);
};
void async_init_port (void)
{
setup |= ASYNC_NO_DMA; // disable DMA
setup |= ASYNC_MODE1; // 8 data, no parity, 1 stop
_AX = setup;
outp (ASYNC_SP1CT, _AL);
inpw (ASYNC_SP1RD); // clear buffer
_AX = 0;
outp (ASYNC_SP1STS, _AL); // clear errors
_AX = BAUD115K;
outp (ASYNC_SP1BAUD, _AL);
//setup |= ASYNC_RXIE; // enable interrupts for receive
setup |= ASYNC_RMODE | ASYNC_TMODE; // enable receive && transmit
_AX = setup;
outp (ASYNC_SP1CT, _AL);
_AX = inpw (0xff7a) & ~0x0008; // enable RS-485 transmitter
outp (0xff7a, _AL); // for COM2
};
void async_uninstall_handler (void)
{
_dos_setvect (intrpt, old_handler); // uninstall handler
_AX = inpw (0xff7a) | 0x0008; // disable RS-485 transmitter
outp (0xff7a, _AL); // for COM2
};
=== конец ser188.c
=== начало uart188.h
// UART - compatibility constants for CPU188-5
#include "am188es.h"
#ifndef FREQUENCY
#define FREQUENCY 40000000UL // Processor's internal freq
#endif
#define COM1BASE 0xff80
#define COM1IRQ 8 // int 11h
#define COM2BASE 0xff10
#define COM2IRQ 11 // int 14h
#define LCR 0x0000 // control register offset
#define IER 0x0000 // in UARTs - interrupt enable register offset
// always use 8 data bits
#define DATA8 ASYNC_MODE1 // parity: 7, no parity: 8 bits
#define STOP1 0x0000 // always one stop bit
#define PARITYNONE 0x0000
#define PARITYODD (ASYNC_PE | ASYNC_MODE3) // add one data bit if parity is used
#define PARITYEVEN (ASYNC_PE | ASYNC_EVN | ASYNC_MODE3) // add one data bit if parity is used
#define RXINTEN ASYNC_RXIE // enable interrupt when transmit buffer is empty
#define TXINTEN ASYNC_TXIE // enable interrupt when rec'd data is available
#define SENDBREAK ASYNC_BRK
#define LSINTEN ASYNC_RSIE // enable int on rec'r line status (err or break)
#define LSR 0x0002 // line status register offset
#define DR ASYNC_RDR // data ready
#define OE ASYNC_OER // overrun error
#define PE ASYNC_PER // parity error
#define FE ASYNC_FER // framing error
#define BI (ASYNC_BRK0 | ASYNC_BRK1) // break indicated
#define THREMPTY ASYNC_THRE // transmitter holding register empty
#define TXREMPTY ASYNC_TEMT // transmitter empty
#define THR 0x0004 // transmitter holding register offset
#define RBR 0x0006 // receiver buffer register offset
#define DLW 0x0008 // divisor latch word
// These values are frequency dependent. See FREQUENCY
#define BAUD110 (FREQUENCY / (16UL * 110UL))
#define BAUD150 (FREQUENCY / (16UL * 150UL))
#define BAUD300 (FREQUENCY / (16UL * 300UL))
#define BAUD600 (FREQUENCY / (16UL * 600UL))
#define BAUD1200 (FREQUENCY / (16UL * 1200UL))
#define BAUD2400 (FREQUENCY / (16UL * 2400UL))
#define BAUD4800 (FREQUENCY / (16UL * 4800UL))
#define BAUD9600 (FREQUENCY / (16UL * 9600UL))
#define BAUD19K (FREQUENCY / (16UL * 19200UL))
#define BAUD38K (FREQUENCY / (16UL * 38400UL))
#define BAUD57K (FREQUENCY / (16UL * 57600UL))
#define BAUD115K (FREQUENCY / (16UL * 115200UL))
#define BAUD128K (FREQUENCY / (16UL * 128000UL))
#define BAUD153K (FREQUENCY / (16UL * 153600UL))
#define BAUD230K (FREQUENCY / (16UL * 230400UL))
#define BAUD230K (FREQUENCY / (16UL * 230400UL))
#define BAUD460K (FREQUENCY / (16UL * 460800UL))
#define BAUD921K (FREQUENCY / (16UL * 921600UL))
// EOF
=== конец uart188.h
=== начало am188es.h
// Am188ES registers
#define IC_EOI 0xff22 // End of Interrupt register
#define IC_SP0CON 0xff44 // Serial Port 0 Interrupt Control
#define IC_SP1CON 0xff42 // Serial Port 1 Interrupt Control
#define ASYNC_SP0CT 0xff80 // Serial port 0 control
#define ASYNC_SP0STS 0xff82 // Serial port 0 status
#define ASYNC_SP0BAUD 0xff88 // Serial port 0 baud rate divisor
#define ASYNC_SP0RD 0xff86 // Serial port 0 receive
#define ASYNC_SP0TD 0xff84 // Serial port 0 transmit
#define ASYNC_SP1CT 0xff10 // Serial port 1 control
#define ASYNC_SP1STS 0xff12 // Serial port 1 status
#define ASYNC_SP1BAUD 0xff18 // Serial port 1 baud rate divisor
#define ASYNC_SP1RD 0xff16 // Serial port 1 receive
#define ASYNC_SP1TD 0xff14 // Serial port 1 transmit
#define PER_AUXCON 0xfff2 // Auxiliary Configuration Register
// SP0CT and SP1CT register values
#define ASYNC_NO_DMA 0x0000 // Disable DMA mode
#define ASYNC_RSIE 0x1000 // Receive status interrupt enable
#define ASYNC_BRK 0x0800 // Send break
#define ASYNC_TB8 0x0400 // Transmit Bit 8
#define ASYNC_FC 0x0200 // Flow Control Enable
#define ASYNC_TXIE 0x0100 // Transmitter Ready Interrupt Enable
#define ASYNC_RXIE 0x0080 // Receive Data Ready Interrupt Enable
#define ASYNC_TMODE 0x0040 // Transmit Mode
#define ASYNC_RMODE 0x0020 // Receive Mode
#define ASYNC_EVN 0x0010 // Even Parity
#define ASYNC_PE 0x0008 // Parity Enable
#define ASYNC_MODE1 0x0001 // Data Mode 1
#define ASYNC_MODE2 0x0002 // Data Mode 2
#define ASYNC_MODE3 0x0003 // Data Mode 3
#define ASYNC_MODE4 0x0004 // Data Mode 4
// SP0STS and SP1STS register values
#define ASYNC_BRK1 0x0400 // Long Break Detected
#define ASYNC_BRK0 0x0200 // Short Break Detected
#define ASYNC_RD8 0x0100 // Received Bit 8
#define ASYNC_RDR 0x0080 // Receive Data Ready
#define ASYNC_THRE 0x0040 // Transmit Holding Register Empty
#define ASYNC_FER 0x0020 // Framing Error Detected
#define ASYNC_OER 0x0010 // Overrun Error Detected
#define ASYNC_PER 0x0008 // Parity Error Detected
#define ASYNC_TEMT 0x0004 // Transmitter Empty
#define ASYNC_HS0 0x0002 // Handshake Signal 0
// interrupt control register values
#define IC_MSK 0x0008 // mask interrupt
// AUXCON register values
#define PER_IOSIZ 0x0001 // I/O Space Data Bus Size
#define PER_MSIZ 0x0002 // Midrange Data Bus Size
#define PER_LSIZ 0x0004 // LCS Data Bus Size
#define PER_RTS0 0x0008 // Serial Port 0 Request to Send
#define PER_ENRX0 0x0010 // Serial Port 0 Enable Receiver Request
#define PER_RTS1 0x0020 // Serial Port 1 Request to Send
#define PER_ENRX1 0x0040 // Serial Port 1 Enable Receiver Request
=== конец am188es.h