A. 通过串口下载文件到指定的内存后如何运行这个文件
尽量关闭消耗资源的程序运行.如WORD里面老跳的话,就把拼写检查之类的东西都关了,应该会好点,128M的内存,在电脑属性里查,只有96M可用,把这些关了后,WORD编辑里面内存不足就不会再跳出来了.也可将虚拟内存稍微设置大一点,运行个后台内存整理的软件,可能会好一点.
不知道你是内存太小了还是其他别的原因,如果仅仅只是内存太小了,那没办法了,只能想办法将就着用了.一般来说现在128M的内存处理文字玩小游戏都还行,部分数码图片处理,跳出内存不足是很正常的,WORD老跳就要检查下了.
B. 请问:希捷硬盘500G 32MB缓存,32MB缓存的代码是多少
希捷7200.11
500GB串口盒包硬盘的编号为ST3500320AS,ST代表希捷,3代表是3.5英寸的桌面硬盘,500代表硬盘容量是500GB,320代表32MB缓存及两盘片设计,AS代表这块硬盘是SATA接口
C. linux 内核 uart driver 只有fifo满才向用户buf传递数据吗
对于串口驱动的移植准备自己分析一下源代码的,但是发现自己好多地方都只知道一 些皮毛,不明白其中的道理,所以我上网搜的时候发现有好多人写了很多很好的文章了,下面我转载的这篇就非常不错,一个困恼我好久的问题是驱动代码中只是注 册了platform驱动,而platform设备注册在哪里?这个问题困恼我好久,源代码中一直没找到,下面文章就解决了这个问题。当然文章中详细了讲 述了很多细节的知识。
原文地址 http://chxxxyg.blog.163.com/blog/static/150281193201082044140894/
(1)串口移植
S3C2440共有3个串口,在SMDK2440平台上串口0和串口1都作为普通串口使用,串口2工作在红外收发模式。TQ2440开发板将它们都作为普通串口,目前所需要的只有串口0,作为控制终端,所以此处不作修改。
在文件 linux/arch/arm/plat-s3c24xx/devs.c中定义了三个串口的硬件资源。
static struct resource s3c2410_uart0_resource[] = {
………………………………
};
static struct resource s3c2410_uart1_resource[] = {
………………………………
};
static struct resource s3c2410_uart2_resource[] = {
………………………………
};
在文件linux/arch/arm/plat-samsung/dev-uart.c中定义了每个串口对应的平台设备。
static struct platform_device s3c24xx_uart_device0 = {
.id = 0,
};
static struct platform_device s3c24xx_uart_device1 = {
.id = 1,
};
static struct platform_device s3c24xx_uart_device2 = {
.id = 2,
};
在文件linux/arch/arm/mach-s3c2440/mach-smdk2440.c中有串口一些寄存器的初始化配置。
static struct s3c2410_uartcfg smdk2440_uartcfgs[] __initdata = {
[0] = {
…………………………
},
[1] = {
…………………………
},
/* IR port */
[2] = {
…………………………
}
};
在文件linux/arch/arm/mach-s3c2440/mach-smdk2440.c中将调用函数
s3c24xx_init_uarts()最终将上面的硬件资源,初始化配置,平台设备整合到一起。
在文件 linux/arch/arm/plat-s3c/init.c中有
static int __init s3c_arch_init(void)
{
………………………………
ret = platform_add_devices(s3c24xx_uart_devs, nr_uarts);
return ret;
}
这个函数将串口所对应的平台设备添加到了内核。
(2)串口设备驱动原理浅析
我认为任何设备在linux中的实现就“两条线”。一是设备模型的建立,二是读写数据流。串口驱动也是这样。
串口设备模型建立:
串口设备驱动的核心结构体在文件linux/drivers/serial/samsuing.c中如下
static struct uart_driver s3c24xx_uart_drv = {
.owner = THIS_MODULE,
.dev_name = "s3c2410_serial",
.nr = CONFIG_SERIAL_SAMSUNG_UARTS,
.cons = S3C24XX_SERIAL_CONSOLE,
.driver_name = S3C24XX_SERIAL_NAME,
.major = S3C24XX_SERIAL_MAJOR,
.minor = S3C24XX_SERIAL_MINOR,
};
串口驱动的注册
static int __init s3c24xx_serial_modinit(void)
{
………………………………
ret = uart_register_driver(&s3c24xx_uart_drv);
………………………………
}
串口驱动其实是一个典型的tty驱动
int uart_register_driver(struct uart_driver *drv)
{
………………………………
//每一个端口对应一个state
drv->state = kzalloc(sizeof(struct uart_state) * drv->nr, GFP_KERNEL);
………………………………
normal = alloc_tty_driver(drv->nr); //分配该串口驱动对应的tty_driver
………………………………
drv->tty_driver = normal; //让drv->tty_driver字段指向这个tty_driver
………………………………
normal->driver_name = drv->driver_name;
normal->name = drv->dev_name;
normal->major = drv->major;
normal->minor_start = drv->minor;
………………………………
//设置该tty驱动对应的操作函数集tty_operations (linux/drivers/char/core.c)
tty_set_operations(normal, &uart_ops);
………………………………
retval = tty_register_driver(normal); //将tty驱动注册到内核
………………………………
}
其实tty驱动的本质是一个字符设备,在文件 linux/drivers/char/tty_io.c中
int tty_register_driver(struct tty_driver *driver)
{
………………………………
cdev_init(&driver->cdev, &tty_fops);
driver->cdev.owner = driver->owner;
error = cdev_add(&driver->cdev, dev, driver->num);
………………………………
}
它所关联的操作函数集tty_fops在文件linux/drivers/char/tty_io.c中实现
static const struct file_operations tty_fops = {
.llseek = no_llseek,
.read = tty_read,
.write = tty_write,
………………………………
.open = tty_open,
………………………………
};
到此串口的驱动作为tty_driver被注册到了内核。前面提到串口的每一个端口都是作为平台设备被添加到内核的。那么这些平台设备就对应着有它们的平台设备驱动。在文件linux/drivers/serial/s3c2440.c中有:
static struct platform_driver s3c2440_serial_driver = {
.probe = s3c2440_serial_probe,
.remove = __devexit_p(s3c24xx_serial_remove),
.driver = {
.name = "s3c2440-uart",
.owner = THIS_MODULE,
},
};
当其驱动与设备匹配时就会调用他的探测函数
static int s3c2440_serial_probe(struct platform_device *dev)
{
return s3c24xx_serial_probe(dev, &s3c2440_uart_inf);
}
每一个端口都有一个描述它的结构体s3c24xx_uart_port 在 文件linux/drivers/serial/samsuing.c
static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS] = {
[0] = {
.port = {
.lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[0].port.lock),
.iotype = UPIO_MEM,
.irq = IRQ_S3CUART_RX0, //该端口的中断号
.uartclk = 0,
.fifosize = 16,
.ops = &s3c24xx_serial_ops, //该端口的操作函数集
.flags = UPF_BOOT_AUTOCONF,
.line = 0, //端口编号
}
},
………………………………
}
上面探测函数的具体工作是函数s3c24xx_serial_probe()来完成的
int s3c24xx_serial_probe(struct platform_device *dev,
struct s3c24xx_uart_info *info)
{
………………………………
//根据平台设备提供的硬件资源等信息初始化端口描述结构体中的一些字段
ret = s3c24xx_serial_init_port(ourport, info, dev);
//前面注册了串口驱动,这里便要注册串口设备
uart_add_one_port(&s3c24xx_uart_drv, &ourport->port);
………………………………
}
int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport)
{
………………………………
//前面说串口驱动是tty_driver,这里可以看到串口设备其实是tty_dev
tty_dev = tty_register_device(drv->tty_driver, uport->line, uport->dev);
………………………………
}
串口数据流分析:
在串口设备模型建立中提到了三个操作函数集,uart_ops ,tty_fops,s3c24xx_serial_ops数据的流动便是这些操作函数间的调用,这些调用关系如下:
在对一个设备进行其他操作之前必须先打开它,linux/drivers/char/tty_io.c
static const struct file_operations tty_fops = {
………………………………
.open = tty_open,
………………………………
};
static int tty_open(struct inode *inode, struct file *filp)
{
………………………………
dev_t device = inode->i_rdev;
………………………………
driver = get_tty_driver(device, &index); //根据端口设备号获取它的索引号
………………………………
if (tty) {
………………………………
} else
tty = tty_init_dev(driver, index, 0); //创建一个tty_struct 并初始化
………………………………
}
struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,int first_ok)
{
………………………………
tty = alloc_tty_struct(); //分配一个tty_struct结构
//一些字段的初始化,
initialize_tty_struct(tty, driver, idx);
//完成的主要工作是driver->ttys[idx] = tty;
retval = tty_driver_install_tty(driver, tty);
………………………………
/*
下面函数主要做的就是调用线路规程的打开函数ld->ops->open(tty)。
在这个打开函数中分配了一个重要的数据缓存
tty->read_buf = kzalloc(N_TTY_BUF_SIZE, GFP_KERNEL);
*/
retval = tty_ldisc_setup(tty, tty->link);
}
void initialize_tty_struct(struct tty_struct *tty,struct tty_driver *driver, int idx)
{
………………………………
//获取线路规程操作函数集tty_ldisc_N_TTY,并做这样的工作tty->ldisc = ld;
tty_ldisc_init(tty);
………………………………
/*
下面函数的主要工作是INIT_DELAYED_WORK(&tty->buf.work, flush_to_ldisc);
初始化一个延时tty->buf.work 并关联一个处理函数flush_to_ldisc(),这个函数将在
数据读取的时候用到。
*/
tty_buffer_init(tty);
………………………………
tty->driver = driver;
tty->ops = driver->ops; //这里的ops就是struct tty_operations uart_ops
tty->index = idx; //idx就是该tty_struct对应端口的索引号
tty_line_name(driver, idx, tty->name);
}
端口设备打开之后就可以进行读写操作了,这里只讨论数据的读取,在文件 linux/drivers/char/tty_io.c中,
static const struct file_operations tty_fops = {
………………………………
.read = tty_read,
………………………………
};
static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
loff_t *ppos)
{
………………………………
ld = tty_ldisc_ref_wait(tty); //获取线路规程结构体
if (ld->ops->read) //调用线路规程操作函数集中的n_tty_read()函数
i = (ld->ops->read)(tty, file, buf, count);
else
………………………………
}
在linux/drivers/char/N_tty.c中:
struct tty_ldisc_ops tty_ldisc_N_TTY = {
………………………………
.open = n_tty_open,
………………………………
.read = n_tty_read,
………………………………
};
static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
unsigned char __user *buf, size_t nr)
{
………………………………
while (nr) {
………………………………
if (tty->icanon && !L_EXTPROC(tty)) {
//如果设置了tty->icanon 就从缓存tty->read_buf[]中逐个数据读取,并判断读出的每一个数//据的正确性或是其他数据类型等。
eol = test_and_clear_bit(tty->read_tail,tty->read_flags);
c = tty->read_buf[tty->read_tail];
………………………………
} else {
………………………………
//如果没有设置tty->icanon就从缓存tty->read_buf[]中批量读取数据,之所以要进行两次读
//取是因为缓存tty->read_buf[]是个环形缓存
uncopied = _from_read_buf(tty, &b, &nr);
uncopied += _from_read_buf(tty, &b, &nr);
………………………………
}
}
………………………………
}
用户空间是从缓存tty->read_buf[]中读取数据读的,那么缓存tty->read_buf[]中的数据有是从那里来的呢?分析如下:
回到文件 linux/drivers/serial/samsuing.c中,串口数据接收中断处理函数实现如下:
这是串口最原始的数据流入的地方
static irqreturn_t s3c24xx_serial_rx_chars(int irq, void *dev_id)
{
………………………………
while (max_count-- > 0) {
………………………………
ch = rd_regb(port, S3C2410_URXH); //从数据接收缓存中读取一个数据
………………………………
flag = TTY_NORMAL; //普通数据,还可能是其他数据类型在此不做讨论
………………………………
/*
下面函数做的最主要工作是这样
struct tty_buffer *tb = tty->buf.tail;
tb->flag_buf_ptr[tb->used] = flag;
tb->char_buf_ptr[tb->used++] = ch;
将读取的数据和该数据对应标志插入 tty->buf。
*/
uart_insert_char(port, uerstat, S3C2410_UERSTAT_OVERRUN, ch, flag);
}
tty_flip_buffer_push(tty); //将读取到的max_count个数据向上层传递。
out:
return IRQ_HANDLED;
}
void tty_flip_buffer_push(struct tty_struct *tty)
{
………………………………
if (tty->low_latency)
flush_to_ldisc(&tty->buf.work.work);
else
schele_delayed_work(&tty->buf.work, 1);
//这里这个延时work在上面串口设备打开中提到过,该work的处理函数也是flush_to_ldisc。
}
static void flush_to_ldisc(struct work_struct *work)
{
………………………………
while ((head = tty->buf.head) != NULL) {
………………………………
char_buf = head->char_buf_ptr + head->read;
flag_buf = head->flag_buf_ptr + head->read;
………………………………
//刚才在串口接收中断处理函数中,将接收到的数据和数据标志存到tty->buf中,现在将
//这些数据和标志用char_buf 和flag_buf指向进一步向上传递。
disc->ops->receive_buf(tty, char_buf,flag_buf, count);
spin_lock_irqsave(&tty->buf.lock, flags);
}
}
上面调用的函数disc->ops->receive_buf在文件linux/drivers/char/N_tty.c中实现
struct tty_ldisc_ops tty_ldisc_N_TTY = {
………………………………
.receive_buf = n_tty_receive_buf,
………………………………
};
static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
{
………………………………
//现在可以看到缓冲区tty->read_buf 中数据的由来了。
if (tty->real_raw) {
//如果设置了tty->real_raw将上面讲到的些传入数据批量拷贝到tty->read_head中。
//对环形缓存区的数据拷贝需要进行两次,第一次拷贝从当前位置考到缓存的末尾,如果还//有没考完的数据而且缓存区开始出处还有剩余空间,就把没考完的数据考到开始的剩余空
//间中。
spin_lock_irqsave(&tty->read_lock, cpuflags);
i = min(N_TTY_BUF_SIZE - tty->read_cnt,N_TTY_BUF_SIZE - tty->read_head);
i = min(count, i);
memcpy(tty->read_buf + tty->read_head, cp, i);
tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
tty->read_cnt += i;
cp += i;
count -= i;
i = min(N_TTY_BUF_SIZE - tty->read_cnt,
N_TTY_BUF_SIZE - tty->read_head);
i = min(count, i);
memcpy(tty->read_buf + tty->read_head, cp, i);
tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
tty->read_cnt += i;
spin_unlock_irqrestore(&tty->read_lock, cpuflags);
} else {
for (i = count, p = cp, f = fp; i; i--, p++) {
//如果没有设置tty->real_raw,就根据传入数据标志分类获取数据。
………………………………
}
………………………………
}
………………………………
}
到此,数据读取的整个过程就结束了。可以看出数据读取可以分为两个阶段,一个阶段是上层函数从环形缓存区tty->read_buf 读取数据,第二阶段是底层函数将接收的数据考到环形缓存区tty->read_buf 中。
D. 串口向单片机发送指令,接受环形队列怎么理解
多的先不说了,就说6个字符的:
开两个6个数组空间,将采集的数据存在一个数组,判断起始位,和结束位,是否符合,符合就将4数据送下个数组,不符就不送下个数组.
ea 不用,es用,传很多数据时必须用,不然会错
E. c# 如何将串口数据写入缓存(一个arraylist[])
BytesBuffer.Add("你要写入的东西.");如:你读到
一个字符串
string
str="abc";写入缓存:
BytesBuffer.Add(str);
F. 关于串口的代码
你的电脑上面没有串口吧,用GetPortName获取到一个空数组,数组ports的长度为-1,你所引ports的时候就会报错,你可以用虚拟串口软件虚拟串口,或者加一条判断有没有串口
G. 想清除串口缓存区,怎么做
tcflush函数清除串口输入缓存(终端驱动已接到,但用户尚未读取)或串口输出缓存(用户已经写如缓存,但尚未发送)。函数原型:int tcflush(int filedes,int quene)参数解释filedes: 描述符。quene取值及含义: *TCIFLUSH 清除输入队列 *TCOFLUSH 清除输出队列 *TCIOFLUSH 清除输入、输出队列举例:tcflush(fd,TCIOFLUSH);另加的说明:在打开串口后,用户其实其实已经可以开始从串口读取数据了,但如果用户没有读取,数据将被将保存在缓冲区里。如果用户不想要开始的一段数据,或者发现缓冲区数据有误,可以使用这个函数将缓冲区清空。应用举例:tcflush(fd, TCIOFLUSH);sleep(2); read_len = read(fd, buff, 10);
H. labview串口接收缓存数据问题
1. 你的程序有些问题,你不能每次都打开串口,在循环中,这样会导致串口不断的开启和关闭。
2. 数据接收时,只有长度大于0,才去读取信息。不要每次都强行读取。
3. 当点击发送命令后,要加个延时,才能去读取。
I. C#串口通信中COM口的缓存为4096,假设1个2MB的数据通过此COM口,怎么样实现全部读取,而没有遗漏或错误
发送数据大于缓冲区时,一般采用分片多次发送的方法,另外可以另外开辟一块缓冲区,将缓冲区数据读完之后立刻刷新等待后续数据,但是此种方法依然可能造成数据丢失。
J. 求上位机串口程序代码
以下是根据“人民邮电出版社”的“VISUAL BASIC 串口通讯实例导航”一书的第一章代码修改用于发送和接收十六进制的数据流实用可运行代码.
标准模块:
Option Explicit
Public fMainForm As frmMain
Public yibiao_wei(10) As Integer
Public di1 As String * 2
Public main_i As Integer
Public i As Integer
Public j As Integer
Public fasong_sj(10, 5) As String
Public xh As Integer
Public di As Integer
Public sj_bm(10, 5) As Single
Public number As Byte
Public setMingling(10) As String * 16
Public alame(10) As String * 1
Public record_jm(5) As Single
Public a As Double
Public PRINT_Cs(14) As String
Public PRINT_WzCs(12) As String
Public shiYAnH As String
Public shiYAnTime As String
Public shiyan_sj(4) As String
Public print_fg As Byte
Option Explicit
Dim sum_zs
Dim xuhao_zs As String * 2
Dim i As Byte
Dim j As Byte
Dim ccl(2) As String * 1
Dim blL As String * 2
Dim bl As String * 1
Dim cclL(2) As String * 4
Dim bl_dm As String * 4
Dim zt_dm1 As String * 8
Dim jieshou_sj As String * 6
Dim sum As Byte
Dim sum1 As Byte
Dim xuhao As String * 2
Dim fa0 As String * 2
Dim HexStr1 As String * 20
' 基本设置
Private intPort As Integer '串行口号
Private strSet As String '协议设置
Private intTime As Integer '发送时间间隔
'发送与接收标志
Private blnAutoSendFlag As Boolean '发送标志
Private blnAutoSendFlag1 As Boolean '发送标志
Private blnReceiveFlag As Boolean '接收标志
'发送模块
Private intOutMode As Integer '发送模式
Private strSendText As String '发送文本数据
Private bytSendByte() As Byte '发送二进制数据
'显示标志
Private intHexChk As Integer '十六进制编码标志
Private intAsciiChk As Integer 'ASCII码标志
Private intAddressChk As Integer '地址标志
Private intAdd48Chk As Integer '4/8位地址标志
'接收模块
Private bytReceiveByte() As Byte '接收到的字节
Private intReceiveLen As Integer '接收到的字节数
Private strTestn As String
'显示模块
Private strAddress As String '地址信息
Private strHex As String '十六进制编码
Private strAscii As String 'ASCII码
Private intHexWidth As Integer '显示列数
'
Private intOriginX As Long '横向原点(像素)
Private intOriginY As Integer '纵向原点(行)
Private intLine As Integer '总行数
'
Dim m As Integer
Dim blnChakanFlag As Boolean
'显示常量
Private Const ChrWidth = 105 '单位宽度
Private Const ChrHeight = 2 * ChrWidth '单位高度
Private Const BorderWidth = 210 '预留边界
Private Const LineMax = 16 '最大显示行数
'输入处理
'处理接收到的字节流,并保存在全局变量
'bytReceiveRyte()
Private Sub InputManage(bytInput() As Byte, intInputLenth As Integer)
Dim n As Integer '定义变量及初始化
ReDim Preserve bytReceiveByte(intReceiveLen + intInputLenth)
For n = 1 To intInputLenth Step 1
bytReceiveByte(intReceiveLen + n - 1) = bytInput(n - 1)
Next n
intReceiveLen = intReceiveLen + intInputLenth
End Sub
'为输出准备文本
'保存在全局变量
'strText
'strHex
'strAddress
'总行数保存在intLine
Private Sub GetDisplayText()
Dim n As Integer
Dim intValue As Integer
Dim intHighHex As Integer
Dim intLowHex As Integer
Dim strSingleChr As String * 1
Dim intAddress As Integer
Dim intAddressArray(8) As Integer
Dim intHighAddress As Integer
Dim HexStr As String
On Error GoTo abc
strAscii = "" '设置初值
strHex = ""
strAddress = ""
'获得16进制码和ASCII码的字符串
For n = 1 To intReceiveLen
intValue = bytReceiveByte(n - 1)
If intValue < 32 Or intValue > 128 Then '处理非法字符
strSingleChr = Chr(46) '对于不能显示的ASCII码,
Else '用"."表示
strSingleChr = Chr(intValue)
End If
strAscii = strAscii + strSingleChr
intHighHex = intValue \ 16
intLowHex = intValue - intHighHex * 16
If intHighHex < 10 Then
intHighHex = intHighHex + 48
Else
intHighHex = intHighHex + 55
End If
If intLowHex < 10 Then
intLowHex = intLowHex + 48
Else
intLowHex = intLowHex + 55
End If
HexStr = HexStr & Chr$(intHighHex) & Chr$(intLowHex)
HexStr1 = HexStr '传递数据
strHex = strHex + " " + Chr$(intHighHex) + Chr$(intLowHex) + " "
If (n Mod intHexWidth) = 0 Then '设置换行
strAscii = strAscii + Chr$(13) + Chr$(10)
strHex = strHex + Chr$(13) + Chr$(10)
Else
End If
Next n
'获得地址字符串
intLine = intReceiveLen \ intHexWidth
If (intReceiveLen - intHexWidth * intLine) > 0 Then
intLine = intLine + 1
End If
For n = 1 To intLine
intAddress = (n - 1) * intHexWidth
If intAdd48Chk = 1 Then
intHighAddress = 8
Else
intHighAddress = 4
End If
intAddressArray(0) = intAddress
For m = 1 To intHighAddress
intAddressArray(m) = intAddressArray(m - 1) \ 16
Next m
For m = 1 To intHighAddress
intAddressArray(m - 1) = intAddressArray(m - 1) - intAddressArray(m) * 16
Next m
For m = 1 To intHighAddress
If intAddressArray(intHighAddress - m) < 10 Then
intAddressArray(intHighAddress - m) = intAddressArray(intHighAddress - m) + Asc("0")
Else
intAddressArray(intHighAddress - m) = intAddressArray(intHighAddress - m) + Asc("A") - 10
End If
strAddress = strAddress + Chr$(intAddressArray(intHighAddress - m))
Next m
strAddress = strAddress + Chr$(13) + Chr$(10) '设置换行
Next n
'Text1 = "Ok"
Exit Sub
abc:
'Text1 = "Error"
Resume
End Sub
'显示输出
Private Sub display()
Dim intViewWidth As Long '横向宽度(像素)
Dim intViewLine As Integer '纵向宽度(行)
Dim strDisplayAddress As String
Dim strDisplayHex As String
Dim strDisplayAscii As String
strDisplayAddress = ""
strDisplayHex = ""
strDisplayAscii = ""
Dim intStart As Integer
Dim intLenth As Integer
'调整显示页面大小,设置滚动位置宽度
If intAdd48Chk = 1 Then
frmMain.txtHexEditAddress.Width = 8 * ChrWidth + BorderWidth
Else
frmMain.txtHexEditAddress.Width = 4 * ChrWidth + BorderWidth
End If
frmMain.txtHexEditHex.Width = intHexWidth * 4 * ChrWidth + BorderWidth
frmMain.txtHexEditText.Width = intHexWidth * ChrWidth + BorderWidth
frmMain.txtBlank.Width = BorderWidth
intViewWidth = frmMain.txtHexEditAddress.Width * intAddressChk + frmMain.txtHexEditHex.Width * intHexChk + frmMain.txtHexEditText.Width * intAsciiChk
If intViewWidth <= frmMain.fraHexEditBackground.Width And intLine < LineMax Then
frmMain.txtBlank.Width = frmMain.fraHexEditBackground.Width - intViewWidth
frmMain.hsclHexEdit.Visible = False
frmMain.vsclHexEdit.Visible = False
intViewWidth = frmMain.fraHexEditBackground.Width
intViewLine = intLine
intOriginX = 0
intOriginY = 0
ElseIf intViewWidth > frmMain.fraHexEditBackground.Width And intLine < LineMax - 1 Then
frmMain.hsclHexEdit.Visible = True
frmMain.vsclHexEdit.Visible = False
frmMain.hsclHexEdit.Width = frmMain.fraHexEditBackground.Width
intViewLine = intLine
intOriginY = 0
If intOriginX > intViewWidth - frmMain.fraHexEditBackground.Width Then
intOriginX = intViewWidth - frmMain.fraHexEditBackground.Width
End If
ElseIf intViewWidth < (frmMain.fraHexEditBackground.Width - frmMain.vsclHexEdit.Width) And intLine >= LineMax Then
frmMain.vsclHexEdit.Visible = True
frmMain.hsclHexEdit.Visible = False
frmMain.txtBlank.Width = frmMain.fraHexEditBackground.Width - intViewWidth
intViewWidth = frmMain.fraHexEditBackground.Width
intViewLine = LineMax
intOriginX = 0
If intOriginY > intLine - LineMax Then
intOriginY = intLine - LineMax
End If
Else
frmMain.hsclHexEdit.Visible = True
frmMain.vsclHexEdit.Visible = True
frmMain.hsclHexEdit.Width = frmMain.fraHexEditBackground.Width - frmMain.vsclHexEdit.Width
intViewLine = LineMax - 1
If intOriginX > intViewWidth - frmMain.fraHexEditBackground.Width Then
intOriginX = intViewWidth - frmMain.fraHexEditBackground.Width
End If
If intOriginY > intLine - LineMax + 1 Then
intOriginY = intLine - LineMax + 1
End If
End If
frmMain.txtHexEditAddress.Left = intOriginX
frmMain.txtHexEditHex.Left = intOriginX + frmMain.txtHexEditAddress.Width * intAddressChk
frmMain.txtHexEditText.Left = intOriginX + frmMain.txtHexEditAddress.Width * intAddressChk + frmMain.txtHexEditHex.Width * intHexChk
frmMain.txtBlank.Left = intOriginX + frmMain.txtHexEditAddress.Width * intAddressChk + frmMain.txtHexEditHex.Width * intHexChk + frmMain.txtHexEditText.Width * intAsciiChk
intStart = intOriginY * (6 + 4 * intAdd48Chk) + 1
intLenth = intViewLine * (6 + 4 * intAdd48Chk)
strDisplayAddress = Mid(strAddress, intStart, intLenth)
intStart = intOriginY * (intHexWidth * 4 + 2) + 1
intLenth = intViewLine * (intHexWidth * 4 + 2)
strDisplayHex = Mid(strHex, intStart, intLenth)
intStart = intOriginY * (intHexWidth + 2) + 1
intLenth = intViewLine * (intHexWidth + 2)
strDisplayAscii = Mid(strAscii, intStart, intLenth)
'设置滚动条
frmMain.vsclHexEdit.Max = intLine - intViewLine
frmMain.hsclHexEdit.Max = (intViewWidth - frmMain.fraHexEditBackground.Width) \ ChrWidth + 1
'显示输出
frmMain.txtHexEditHex.Text = strDisplayHex
frmMain.txtHexEditText.Text = strDisplayAscii
frmMain.txtHexEditAddress.Text = strDisplayAddress
End Sub
'文本无变化的刷新
Private Sub ScrollRedisplay()
Call display
End Sub
'文本发生变化的刷新
Private Sub SlideRedisplay()
Call GetDisplayText
Call display
End Sub
'字符表示的十六进制数转化为相应的整数,错误则返回 -1
Function ConvertHexChr(str As String) As Integer
Dim test As Integer
test = Asc(str)
If test >= Asc("0") And test <= Asc("9") Then
test = test - Asc("0")
ElseIf test >= Asc("a") And test <= Asc("f") Then
test = test - Asc("a") + 10
ElseIf test >= Asc("A") And test <= Asc("F") Then
test = test - Asc("A") + 10
Else
test = -1 '出错信息
End If
ConvertHexChr = test
End Function
'字符串表示的十六进制数据转化为相应的字节串,返回转化后的字节数
Function strHexToByteArray(strText As String, bytByte() As Byte) As Integer
Dim HexData As Integer '十六进制(二进制)数据字节对应值
Dim hstr As String * 1 '高位字符
Dim lstr As String * 1 '低位字符
Dim HighHexData As Integer '高位数值
Dim LowHexData As Integer '低位数值
Dim HexDataLen As Integer '字节数
Dim StringLen As Integer '字符串长度
Dim Account As Integer
Dim n As Long
'计数
strTestn = "" '设初值
HexDataLen = 0
strHexToByteArray = 0
StringLen = Len(strText)
Account = StringLen \ 2
ReDim bytByte(Account)
For n = 1 To StringLen
Do '清除空格
hstr = Mid(strText, n, 1)
n = n + 1
If (n - 1) > StringLen Then
HexDataLen = HexDataLen - 1
Exit For
End If
Loop While hstr = " "
Do
lstr = Mid(strText, n, 1)
n = n + 1
If (n - 1) > StringLen Then
HexDataLen = HexDataLen - 1
Exit For
End If
Loop While lstr = " "
n = n - 1
If n > StringLen Then
HexDataLen = HexDataLen - 1
Exit For
End If
HighHexData = ConvertHexChr(hstr)
LowHexData = ConvertHexChr(lstr)
If HighHexData = -1 Or LowHexData = -1 Then '遇到非法字符中断转化
HexDataLen = HexDataLen - 1
Exit For
Else
HexData = HighHexData * 16 + LowHexData
bytByte(HexDataLen) = HexData
HexDataLen = HexDataLen + 1
End If
Next n
If HexDataLen > 0 Then '修正最后一次循环改变的数值
HexDataLen = HexDataLen - 1
ReDim Preserve bytByte(HexDataLen)
Else
ReDim Preserve bytByte(0)
End If
If StringLen = 0 Then '如果是空串,则不会进入循环体
strHexToByteArray = 0
Else
strHexToByteArray = HexDataLen + 1
End If
End Function
Public Function Hex_bin()
'输出口状态鉴别
For i = 1 To 2
ccl(i) = Mid(blL, i, 1)
If ccl(i) >= Chr(48) And ccl(i) <= Chr(57) Or ccl(i) >= Chr(65) And ccl(i) <= Chr(70) Then
ccl(i) = ccl(i)
Else
Exit Function '退出过程函数
ccl(i) = "0"
End If
Next i
For j = 1 To 2
bl = ccl(j)
If bl = "F" Then
bl_dm = "1111"
ElseIf bl = "E" Then
bl_dm = "1110"
ElseIf bl = "D" Then
bl_dm = "1101"
ElseIf bl = "C" Then
bl_dm = "1100"
ElseIf bl = "B" Then
bl_dm = "1011"
ElseIf bl = "A" Then
bl_dm = "1010"
ElseIf bl = "9" Then
bl_dm = "1001"
ElseIf bl = "8" Then
bl_dm = "1000"
ElseIf bl = "7" Then
bl_dm = "0111"
ElseIf bl = "6" Then
bl_dm = "0110"
ElseIf bl = "5" Then
bl_dm = "0101"
ElseIf bl = "4" Then
bl_dm = "0100"
ElseIf bl = "3" Then
bl_dm = "0011"
ElseIf bl = "2" Then
bl_dm = "0010"
ElseIf bl = "1" Then
bl_dm = "0001"
ElseIf bl = "0" Then
bl_dm = "0000"
Else:
bl_dm = ""
End If
cclL(j) = bl_dm
Next j
zt_dm1 = cclL(1) + cclL(2)
For i = 1 To 8
'zt_dm(i) = Mid$(zt_dm1, i, 1)
Next i
End Function
Private Sub cboHexAscii_Click()
If frmMain.cboHexAscii.Text = "按ASCII码" Then
intOutMode = 0
Else
intOutMode = 1
End If
End Sub
Private Sub chkAddress_Click()
If chkAddress.Value = 0 Then
intAddressChk = 0
Else
intAddressChk = 1
End If
Call ScrollRedisplay
End Sub
Private Sub chkAddress48_Click()
If chkAddress48.Value = 1 Then
intAdd48Chk = 1
Else
intAdd48Chk = 0
End If
Call SlideRedisplay
End Sub
Private Sub chkAscii_Click()
If chkAscii.Value = 1 Then
intAsciiChk = 1
Else
intAsciiChk = 0
End If
Call ScrollRedisplay
End Sub
Private Sub chkHex_Click()
If chkHex.Value = 0 Then
intHexChk = 0
Else
intHexChk = 1
End If
Call ScrollRedisplay
End Sub
Private Sub cmdAutoSend_Click()
If blnAutoSendFlag Then
frmMain.ctrTimer.Enabled = False
If Not blnReceiveFlag Then
frmMain.ctrMSComm.PortOpen = False
End If
frmMain.cmdAutoSend.Caption = "自动寻址"
Else
If Not frmMain.ctrMSComm.PortOpen Then
frmMain.ctrMSComm.CommPort = intPort
frmMain.ctrMSComm.Settings = strSet
frmMain.ctrMSComm.PortOpen = True
End If
frmMain.ctrTimer.Interval = intTime
frmMain.ctrTimer.Enabled = True
frmMain.cmdAutoSend.Caption = "停止寻址"
End If
blnAutoSendFlag = Not blnAutoSendFlag
End Sub
Private Sub cmdAutoSend1_Click()
'用于设置参数
If blnAutoSendFlag1 Then
Call cmdAutoSend_Click
frmMain.ctrTimer1.Enabled = False
frmMain.cmdAutoSend1.Caption = "自动设置"
Else
If Not frmMain.ctrMSComm.PortOpen Then
frmMain.ctrMSComm.CommPort = intPort
frmMain.ctrMSComm.Settings = strSet
frmMain.ctrMSComm.PortOpen = True
End If
Call cmdAutoSend_Click
frmMain.cmdAutoSend1.Caption = "停止设置"
frmMain.ctrTimer1.Enabled = True
End If
blnAutoSendFlag1 = Not blnAutoSendFlag1
End Sub
Private Sub cmdChakan_Click()
If blnChakanFlag Then
frmMain.cmdChakan.Caption = "查看"
frmMain.Height = 2800
Else
frmMain.cmdChakan.Caption = "恢复"
frmMain.Height = 6700
End If
blnChakanFlag = Not blnChakanFlag
End Sub
Private Sub cmdClear_Click()
Dim bytTemp(0) As Byte
ReDim bytReceiveByte(0)
intReceiveLen = 0
Call InputManage(bytTemp, 0)
Call GetDisplayText
Call display
End Sub
Private Sub cmdManualSend_Click()
If Not frmMain.ctrMSComm.PortOpen Then
frmMain.ctrMSComm.CommPort = intPort
frmMain.ctrMSComm.Settings = strSet
frmMain.ctrMSComm.PortOpen = True
End If
Call ctrTimer_Timer
If Not blnAutoSendFlag Then
frmMain.ctrMSComm.PortOpen = False
End If
End Sub
Private Sub cmdReceive_Click()
If blnReceiveFlag Then
If Not blnAutoSendFlag And Not blnReceiveFlag Then
frmMain.ctrMSComm.PortOpen = False
End If
frmMain.cmdReceive.Caption = "开始接收"
Else
If Not frmMain.ctrMSComm.PortOpen Then
frmMain.ctrMSComm.CommPort = intPort
frmMain.ctrMSComm.Settings = strSet
frmMain.ctrMSComm.PortOpen = True
End If
frmMain.ctrMSComm.InputLen = 0
frmMain.ctrMSComm.InputMode = 0
frmMain.ctrMSComm.InBufferCount = 0
frmMain.ctrMSComm.RThreshold = 10
frmMain.cmdReceive.Caption = "停止接收"
End If
blnReceiveFlag = Not blnReceiveFlag
End Sub
因长度超10000字,请另行提问给于补充.