gpt4 book ai didi

c - 如何更改通过端口传输的字节数

转载 作者:行者123 更新时间:2023-11-30 18:00:06 26 4
gpt4 key购买 nike

如何更改端口传输的字节数?

  • 原为:中断。
  • 需要:根据民意调查。

插件-> http://pastie.org/3994352

客户:

#include <stdio.h>
#include <conio.h>
#include <dos.h>
#include "comm.h" // Connect module

void main(void)
{
char cmd[128];

/* Set the COM port */
printf("Adjustable com-port ...\n");
OpenSerial(COM_1, SER_BAUD_9600, SER_STOP_2 | SER_BITS_8 | SER_PARITY_EVEN);

printf("Submitting a request for a connection ...\n");
WriteSer(0xFF);

while (1)
{
if (kbhit())
{
int c = getche();
if (c == 13) putch(10);
WriteSer(c);
}

if (DataReadyCount())
{
int c = ReadQueue();
if (c == 0xFF) break;

putch(c);
}
}

printf("Ending a connection ...\n");
CloseSerial();
}

最佳答案

我在网上找到了一个示例,它可能很有值(value),至少在展示轮询与中断驱动方法方面是这样。注意,中断方法需要调用setvectoutportb、保存旧中断并恢复等。

接下来不要询问 TSR。 :)

// http://ragestorm.net
// serial communications example
// interrupt driven/polled method
#include <dos.h>
#include <conio.h>
#include <stdio.h>

// serial port base addresses:
#define COM1 (0x3f8)
#define COM2 (0x2f8)

// stack size for interrupt
#define STACK_SIZE 1024

// serial ports registers:

// receive buffer
#define RBR (0x0)
// transmitter hold
#define THR (0x0)
// interrupt enable
#define IER (0x1)
// interrupt identification
#define IIR (0x2)
// fifo control
#define FCR (0x2)
// line control
#define LCR (0x3)
// modem control
#define MCR (0x4)
// line status
#define LSR (0x5)
// modem status
#define MSR (0x6)
// scratch-pad
#define SPR (0x7)

// divisor lsb byte
#define DIVLSB (0x0)
// divisor msb byte
#define DIVMSB (0x1)

// possible irqs for com ports
int com_irqs[4] = {4, 3, 4, 3};

// the com port addr being used
int used_com_addr = 0;

// the irq being used if interrupt driven
int used_com_irq = 0;

// interrupt driven or polling method?
int intr_used = 0;

// built in stack for interrupt usage
unsigned char recv_stack[STACK_SIZE];
unsigned char* next_char = recv_stack;

// old handler address
void interrupt (*old_handler)(...) = NULL;
void interrupt new_handler(...);

// get com address from bios
unsigned short get_com_addr(int com_no)
{
if ((com_no <= 0) || (com_no >= 5)) return -1;

// bios seg addr
unsigned char* biosaddr = (unsigned char *)0x400;

// set irq according to com number
used_com_irq = com_irqs[com_no - 1];

// retreive addresses bios
return *(unsigned short*)&biosaddr[(com_no - 1) << 1];
}


// detect the uart type of the used com prot addr
// this is mainly to know if fifo is available.
// 0: no uart found, 1: 8250, 2: 16450 or 8250(with spr), 3: 16550, 4: 16550A
int detect_uart_type()
{
char old_data = 0;

// check UART presentation by checking loopback mode
old_data = inportb(used_com_addr + MCR);
outportb(used_com_addr + MCR, 0x10);
if ((inportb(used_com_addr + MSR) & 0xf0)) return 0;
outportb(used_com_addr + MCR, 0x1f);
if ((inportb(used_com_addr + MSR) & 0xf0) != 0xf0) return 0;
outportb(used_com_addr + MCR, old_data);

// write values to scratch pad and readback
old_data = inportb(used_com_addr + SPR);
outportb(used_com_addr + SPR, 0x55);
if (inportb(used_com_addr + SPR) != 0x55) return 1;
outportb(used_com_addr + SPR, 0xAA);
if (inportb(used_com_addr + SPR) != 0xAA) return 1;
outportb(used_com_addr + SPR, old_data);

// enable fifo and determine version by part identification
outportb(used_com_addr + FCR, 1);
old_data = inportb(used_com_addr + FCR);
outportb(used_com_addr + FCR, 0);

if ((~old_data & 0x80)) return 2; // 16450
if ((~old_data & 0x40)) return 3; // 16550
return 4; // 16550a +
}

// inits the serial com port with a specific baud rate,
// using interrupt or polling method.
void init_com_port(int com_no, long baudrate, int intr = 0)
{
// calculate divisor relative to the baudrate
short divisor = (long)115200 / baudrate;

used_com_addr = get_com_addr(com_no);

if (used_com_addr == 0) {

printf("no valid com port!\n");
return ;
}
printf("serial com port addr 0x%x", used_com_addr);
if (intr)
printf(" [irq %d, ", used_com_irq);
else printf("[");

int uart_type = detect_uart_type();
switch(uart_type) {
//case 0: break; // port must be found already by bios.
case 1: printf("8250"); break;
case 2: printf("16450"); break;
case 3: printf("16550"); break;
case 4: printf("16550a"); break;
}

printf("] is initialized!\n");

intr_used = intr;

disable();

// turn off interrupts
outportb(used_com_addr + 1, 0);

// set dlab bit, so we can update the divisor
outportb(used_com_addr + LCR, 0x80);

// set divisor lsb
outportb(used_com_addr + DIVLSB, divisor & 0xff);
// set msb
outportb(used_com_addr + DIVMSB, (divisor >> 8) & 0xff);

// frame: 8 data bits, no parity and 1 stop bit
outportb(used_com_addr + LCR, 0x3);

// set RTS | DTR | OUT2(if intr) to inform remote system that we are ready
outportb(used_com_addr + MCR, 0x3 | ((intr == 1) << 3));

// support interrupt?
if (intr) {

// save old serial port interrupt handler address
old_handler = getvect(8 + used_com_irq);
setvect(8 + used_com_irq, new_handler);

// enable serial port irq at pic
outportb(0x21, inportb(0x21) & ~(1 << used_com_irq));

// let the interrupt be triggered upon data arrival
outportb(used_com_addr + IER, 1);

} else {
// no interrupt should be triggered
outportb(used_com_addr + IER, 0);
}

// does the uart support fifo?
if (uart_type == 4) {
// set fifo buffer of 14 bytes, clear receive and transmit fifo's
outportb(used_com_addr + FCR, 0xc7);
}

// clear delta bits
inportb(used_com_addr + LSR);

// clear incoming byte
inportb(used_com_addr + RBR);

enable();
}

// the serial port interrupt handler
// called upon received data only
// saves data in a stack
void interrupt new_handler(...)
{
unsigned char status = 0;
disable();

// read iir and msr to acknowledge the uart
inportb(used_com_addr + IIR);
inportb(used_com_addr + MSR);

// as long as data is arriving, put it in the stack
do {
// read status register
status = inportb(used_com_addr + LSR) & 0x1;

if (status & 1) {
// read data from com port to the stack
*next_char++ = inportb(used_com_addr + RBR);
// overlap offset in case the stack is full
next_char = ((next_char - recv_stack) % STACK_SIZE) + recv_stack;
}
}while (status & 1);

enable();
// let the pic know we are done
outportb(0xa0, 0x20);
outportb(0x20, 0x20);
}

// send a byte to the initialized com port
void send_byte(unsigned char ch)
{
// make sure the connection is alive
if (inportb(used_com_addr + MSR) & 0x80 == 0) return;

// make sure the transmit hold register is empty
while (inportb(used_com_addr + LSR) & 0x20 == 0) ;

// send the character
outportb(used_com_addr + THR, ch);
}

// receive a byte from the initialized com port
unsigned char recv_byte(int* is_read)
{
int i;

*is_read = 0;
if (intr_used)
if (next_char > recv_stack)
{
*is_read = 1;
return *--next_char;
} else return 0;

// is data set ready high?
for (i = 5; i > 0; i--)
if (inportb(used_com_addr + MSR) & 0x20) break;
if (!i) return -1;

// is there anything to read?
for (i = 5; i > 0; i--)
if (inportb(used_com_addr + LSR) & 0x1) break;
if (!i) return -2;

*is_read = 1;
return inportb(used_com_addr + RBR);
}

// enter loop-mode for debugging and testing.
void enter_loop_mode()
{
outportb(used_com_addr + MCR, inportb(used_com_addr + MCR) | 0x10);
}

// exit a loop mode, change to transimtter/receiver mode
void exit_loop_mode()
{
outportb(used_com_addr + MCR, inportb(used_com_addr + MCR) & ~0x10);
}

// shut down serial port connection
void shutdown_com_port()
{
disable();

if (intr_used) {

// set the old handler
setvect(8 + used_com_irq, old_handler);

// disable used serial port interrupt at pic
outportb(0x21, inportb(0x21) | (1 << used_com_irq));
}

// disable serial port interrupt
outportb(used_com_addr + IER, 0);

// disable interrupt, RTS and DTR
outportb(used_com_addr + MCR, 0);

outportb(used_com_addr + FCR, 0);

enable();
}

int main()
{
clrscr();
init_com_port(1, 9600, 1);

for(;;) {
if (kbhit()) {
int c = getch();
if (c == 27) break;
printf("%c", c);
send_byte(c);
}
int b = 0;
unsigned char c = recv_byte(&b);
if (b) printf("%c", c);
}

shutdown_com_port();
return 1;
}

关于c - 如何更改通过端口传输的字节数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10814216/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com