Visual Basic上位机与51单片机通信实践

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:本文将深入探讨如何利用Visual Basic(VB)编写上位机代码,并与C语言编写的51单片机程序协作,实现对LED灯的控制。上位机是指在个人计算机上运行的应用程序,用于与单片机等下位机通信控制硬件设备。文中详细说明了VB创建图形用户界面、处理串口通信、以及编写事件驱动程序的过程,同时介绍了如何使用C语言编写51单片机固件代码,进行串口初始化、中断服务和GPIO控制。文章还讨论了串口通信参数的配置,以及如何通过文件”串口2控制led”来理解VB与单片机的通信实现。最终目标是帮助读者掌握上位机与下位机通信的编程知识,以及硬件控制的实现。
VB编写上位机代码

1. VB编程基础与GUI构建

VB(Visual Basic)作为一种简便易学的编程语言,广泛用于快速开发Windows平台下的应用程序。本章将带领读者入门VB编程,并展示如何构建图形用户界面(GUI),这对于提升用户体验至关重要。

1.1 VB语言的基本语法和结构

1.1.1 数据类型和变量声明

在VB中,数据类型决定变量能存储的数据种类。常见的数据类型包括整型(Integer)、长整型(Long)、单精度浮点型(Single)、双精度浮点型(Double)等。变量声明用于指定数据类型并命名,使程序易于理解和维护。

Dim number As Integer
Dim pi As Double = 3.14159

1.1.2 控制结构和循环语句

控制结构如If…Then…Else或Select Case用于基于条件执行代码块。循环语句包括For…Next、While…Wend和Do…Loop,它们控制代码的重复执行。

If number > 0 Then
    MsgBox "Number is positive."
ElseIf number < 0 Then
    MsgBox "Number is negative."
Else
    MsgBox "Number is zero."
End If

For i As Integer = 1 To 10
    ' Do something
Next

1.1.3 过程和函数的使用

过程和函数是组织代码的逻辑单元。过程(Sub)执行任务但不返回值,函数(Function)则返回一个值。

Sub SayHello()
    MsgBox "Hello, World!"
End Sub

Function AddNumbers(a As Integer, b As Integer) As Integer
    Return a + b
End Function

1.2 VB中图形用户界面(GUI)的创建

1.2.1 窗体设计和属性设置

窗体(Form)是VB应用程序的用户界面容器。通过属性设置,如背景色、字体、标题等,可以定制窗体的外观。

1.2.2 控件的使用和布局

控件如按钮(Button)、文本框(TextBox)和标签(Label)等用于与用户交互。合理布局控件,确保界面直观易用。

1.2.3 界面美化技巧与用户体验

良好的用户体验(UX)设计考虑颜色搭配、图标设计、动画效果等,使应用程序更加友好。

VB的GUI构建是一个迭代和细化的过程,开发者需要不断地调整和优化界面元素以适应最终用户的需求。下一章节,我们将深入讨论如何在VB中实现串口通信。

2. VB串口通信实现

2.1 串口通信基础

串口通信原理简述

串口通信是计算机与外部设备或另一台计算机之间,通过串行方式进行数据传输的一种通信方式。在串口通信中,数据是按位顺序一位一位地传输的。这种通信方式简单、成本低,适合在较短距离内进行点对点通信。

VB中串口通信的设置和配置

在Visual Basic中,串口通信通常可以通过Microsoft Communications Control (MSComm) 控件来实现。MSComm控件封装了串口通信的基本功能,使用起来相对简便。设置串口参数,如波特率、数据位、停止位和校验位,通过MSComm控件的属性来完成。例如,设置波特率为9600,数据位为8,停止位为1,无校验位,可以通过以下代码实现:

MSComm1.CommPort = 1 ' 使用COM1端口
MSComm1.Settings = "9600,N,8,1" ' 波特率9600,无校验位,8数据位,1停止位
MSComm1.PortOpen = True ' 打开串口

2.2 VB实现串口数据的发送与接收

发送数据的方法和过程

在VB中发送数据,可以通过MSComm控件的Output属性来实现。例如,向串口发送字符串”Hello”:

MSComm1.Output = "Hello"

接收数据的事件和处理

数据的接收在MSComm控件中是通过事件驱动的方式处理的。需要在代码中处理MSComm控件的OnComm事件,在该事件中读取接收缓冲区的数据:

Private Sub MSComm1_OnComm()
    Dim strData As String
    Select Case MSComm1.CommEvent
        Case comEvReceive
            strData = MSComm1.Input
            ' 处理接收到的数据
    End Select
End Sub

数据流的监控与错误处理

在串口通信中,错误监控和处理是保证数据准确性的关键。MSComm控件提供了多个属性,例如 RThreshold SThreshold 来设置接收缓冲区字节数和发送缓冲区字节数达到一定值时触发OnComm事件。另外,通过 CommEvent 属性可以判断并处理不同的通信事件,如 comEvReceive (接收到数据)、 comEvSend (数据发送完毕)等。

2.3 实践案例分析

与特定设备通信的案例研究

在与特定设备进行通信时,必须了解该设备的通信协议细节,包括数据格式、命令集和响应机制等。例如,假设有一个温度传感器,其通过串口通信返回格式为“[温度值]\n”的数据,VB程序需要解析这个字符串并显示温度值。代码示例:

Private Sub MSComm1_OnComm()
    Dim strData As String
    Select Case MSComm1.CommEvent
        Case comEvReceive
            strData = MSComm1.Input
            ' 去除数据中的换行符
            strData = Trim(strData)
            ' 转换字符串为浮点数
            Dim temp As Single
            temp = CSng(strData)
            ' 显示温度
            lblTemperature.Caption = temp & "°C"
    End Select
End Sub

通信协议的实现细节

通信协议可能涉及握手过程、数据包的封装与解析等。在编写程序时,需要根据协议规范设计数据封装格式,并实现数据包的解析逻辑。例如,发送一个命令来请求数据:

' 发送请求数据的命令
MSComm1.Output = "REQUEST\n"

在接收数据时,根据已知的数据格式解析数据包内容。在实践中,解析逻辑的准确性和鲁棒性对于保证通信的可靠性至关重要。

3. C语言编写51单片机固件代码

3.1 51单片机基础和C语言编程环境搭建

3.1.1 51单片机的基本结构和工作原理

51单片机是微控制器领域中经典的8位单片机系列,起源于Intel的8051。它以简单、易用、成本低而广泛应用于嵌入式系统和电子项目中。51单片机的基本结构包括中央处理单元(CPU)、存储器、定时器/计数器、串行通信接口以及多个并行I/O端口。它采用哈佛结构,数据总线和地址总线分开,能够实现高效的指令和数据访问。

单片机的工作原理是通过CPU执行一系列的指令来控制外围设备。程序存储在ROM或Flash中,CPU从程序存储器中取指令、解码并执行,完成数据的处理和控制任务。51单片机的I/O端口可以连接各种传感器、显示器或执行器,根据程序逻辑完成数据的输入输出任务。

3.1.2 C语言开发环境配置

使用C语言开发51单片机固件代码需要搭建合适的开发环境。Keil µVision是开发51单片机的常用集成开发环境(IDE),它提供了编辑器、编译器、调试器等工具,可以方便地进行代码编写、编译、下载和调试。

在搭建开发环境时,首先需要安装Keil µVision软件。安装完成后,需要配置编译器,选择合适的单片机型号和晶振频率。然后配置工程设置,包括选择目标设备、设置编译器和链接器选项。在完成这些步骤之后,就可以创建一个新的项目,并开始编写或粘贴C语言代码了。

为了编译代码,通常需要安装一个8051编译器,例如Keil C51编译器。安装之后,创建一个新项目,并配置好编译器路径及硬件设置。在编码过程中,注意遵循C语言编程规范,并合理利用51单片机的特性,如位地址和位操作指令,以提高代码的效率和质量。

3.2 C语言在51单片机上的基础编程

3.2.1 寄存器操作和基本IO控制

51单片机提供了丰富的寄存器,这些寄存器在硬件层面控制着单片机的各类功能。在C语言中操作这些寄存器是通过定义特殊功能寄存器(SFR)的地址来实现的。例如,要控制P1口的LED灯亮起,可以使用以下代码:

#include <reg51.h> // 包含51单片机寄存器定义的头文件

void main() {
  P1 = 0x00; // 将P1端口所有位清零,假设低电平点亮LED
  while(1);  // 无限循环
}

在这段代码中, reg51.h 头文件包含了51单片机寄存器的定义。通过将 P1 端口的所有位清零,可以实现点亮P1端口连接的所有LED灯。 while(1); 是C语言中的无限循环,确保单片机在执行完毕主函数后不会进入休眠。

3.2.2 定时器和中断服务程序编写

51单片机的定时器用于在指定的时间间隔内产生中断,可以用于定时控制、事件计数等。使用C语言编写定时器中断服务程序的步骤如下:

#include <reg51.h>

void Timer0_Init() {
  TMOD &= 0xF0; // 设置定时器模式寄存器,仅保留高四位
  TMOD |= 0x01; // 设置定时器0为模式1(16位定时器/计数器)
  TH0 = 0xFC;   // 装载定时器初值,定时器溢出时间计算公式为 (65536 - THx * 256 - TLx)
  TL0 = 0x18;
  ET0 = 1;      // 开启定时器0中断
  EA = 1;       // 开启全局中断
  TR0 = 1;      // 启动定时器0
}

void main() {
  Timer0_Init();
  while(1) {
    // 主循环代码
  }
}

void Timer0_ISR() interrupt 1 {
  // 定时器0中断服务程序
  TH0 = 0xFC;   // 重新装载初值
  TL0 = 0x18;
  // 中断处理代码
}

在这段代码中,首先通过 Timer0_Init() 函数初始化定时器0。设置了定时器模式后,装载了初值并开启了中断和全局中断。在中断服务程序 Timer0_ISR 中,重新装载定时器初值并编写相应的中断处理代码,例如定时翻转LED状态。

3.2.3 数据存储和处理

51单片机的数据存储通常涉及到内部RAM以及外部数据存储器的读写。内部RAM有128字节,分为不同的寄存器组、位寻址区和一般存储区。外部数据存储器的访问则需要通过扩展接口和总线控制。例如,使用直接寻址方式访问内部RAM中的数据:

#include <reg51.h>

void main() {
  char xdata *ptr = 0x2000; // 指向外部数据存储器地址
  *ptr = 10;               // 将数值10写入外部存储器地址0x2000
  while(1) {
    // 主循环代码
  }
}

在上面的例子中, xdata 关键字用于指定外部数据存储器,通过指针 ptr 可以操作外部存储器中的数据。这种数据存储和处理的灵活性是嵌入式系统开发中的一个关键点。

3.3 高级固件功能实现

3.3.1 串口通信的C语言实现

串口通信是单片机与外部设备通信的重要手段,51单片机通过串行接口(SBUF)与外部进行串行数据的发送和接收。使用C语言实现串口通信,首先要进行串口的初始化设置:

#include <reg51.h>

void Serial_Init() {
  SCON = 0x50; // 设置串口为模式1(8位数据,可变波特率)
  TMOD |= 0x20; // 设置定时器1为模式2(8位自动重装载)
  TH1 = 0xFD;   // 装载定时器初值,设置波特率为9600
  TL1 = 0xFD;   // 定时器初值计算公式为 (256 - FOSC / (12 * 32 * 波特率))
  TR1 = 1;      // 启动定时器1
  ES = 1;       // 开启串口中断
  EA = 1;       // 开启全局中断
}

void main() {
  Serial_Init();
  while(1) {
    // 主循环代码
  }
}

void Serial_ISR() interrupt 4 {
  if (RI) {
    RI = 0; // 清除接收中断标志
    // 接收数据处理代码
  }
  if (TI) {
    TI = 0; // 清除发送中断标志
    // 发送数据处理代码
  }
}

在这段代码中, Serial_Init() 函数用于初始化串口和定时器1,设置波特率为9600。串口中断服务程序 Serial_ISR 用于处理接收到的数据和准备发送的数据。通过检查接收中断标志RI和发送中断标志TI来进行数据的接收和发送处理。

3.3.2 简单协议栈实现和数据封装

在嵌入式系统中,为了简化数据通信流程,往往需要实现简单的协议栈来进行数据的封装和解析。以下是一个简单的协议栈实现示例,用于封装和解析简单的命令控制信息:

#include <reg51.h>

#define CMD_HEAD 0xAA // 协议头部标识
#define CMD_TAIL 0xBB // 协议尾部标识

// 发送数据封装函数
void Send_Command(unsigned char cmd, unsigned char data) {
  SBUF = CMD_HEAD; // 发送头部标识
  while (!TI);     // 等待发送完成
  TI = 0;          // 清除发送标志
  SBUF = cmd;      // 发送命令字节
  while (!TI);     // 等待发送完成
  TI = 0;          // 清除发送标志
  SBUF = data;     // 发送数据字节
  while (!TI);     // 等待发送完成
  TI = 0;          // 清除发送标志
  SBUF = CMD_TAIL; // 发送尾部标识
  while (!TI);     // 等待发送完成
  TI = 0;          // 清除发送标志
}

// 接收数据解析函数
unsigned char Receive_Command() {
  unsigned char cmd;
  while (RI == 0); // 等待接收数据
  RI = 0;          // 清除接收标志
  if (SBUF == CMD_HEAD) { // 检查头部标识
    while (RI == 0);      // 等待接收命令字节
    RI = 0;               // 清除接收标志
    cmd = SBUF;           // 读取命令字节
    while (RI == 0);      // 等待接收数据字节
    RI = 0;               // 清除接收标志
    // 此处应有数据处理逻辑
    while (RI == 0);      // 等待接收尾部标识
    RI = 0;               // 清除接收标志
    if (SBUF == CMD_TAIL) { // 检查尾部标识
      // 此处处理接收到的数据
    }
  }
  return cmd;
}

在这个协议栈实现中,使用头部和尾部标识来界定一个完整的命令包。 Send_Command 函数用于发送命令和数据,而 Receive_Command 函数用于接收和解析命令。当接收到头部标识后,进入一个循环等待命令字节和数据字节,并在最后检查尾部标识来确定数据包的完整性。

在实际使用中,根据实际通信协议的复杂程度,协议栈的实现可以更加复杂,包括数据包校验、重传机制、数据加密等功能。这些都是在嵌入式系统设计中需要综合考虑的要素。

4. 串口通信参数配置

4.1 串口通信参数详解

4.1.1 波特率、数据位、停止位和校验位

串口通信中,波特率、数据位、停止位和校验位是四个核心参数,它们共同定义了数据的传输方式。

波特率(Baud Rate) 指的是每秒钟传输的符号数,通常用符号/秒表示。在串口通信中,它定义了数据传输的速率。常见的波特率有9600、19200、38400、57600、115200等。

| 波特率   | 描述                                         |
|----------|----------------------------------------------|
| 9600     | 每秒9600个符号,常用于低速通信设备           |
| 19200    | 每秒19200个符号,较9600有提高的传输速率      |
| 38400    | 每秒38400个符号,支持中等速度的通信需求      |
| 57600    | 每秒57600个符号,适用于需要快速传输的场合    |
| 115200   | 每秒115200个符号,高速数据传输的理想选择     |

数据位 是指每次传输的字节数。常见的数据位有5位、6位、7位和8位。在大多数现代通信中,使用8位数据位较为普遍,因为它可以表示256个不同的值,足以代表各种字符和控制信号。

停止位 表示在每个字节的传输后,用于标志字节结束的位。它可以是1位、1.5位或2位。较长的停止位用于提高信号的稳定性和可靠性,但相应会减少每秒可以传输的字节数。

校验位 用于检测传输过程中是否发生错误。常见的校验方法有奇校验(Odd Parity)、偶校验(Even Parity)、无校验(None)和标记校验(Mark)或空格校验(Space)。校验位的使用可以确保数据的完整性,但它也会降低传输效率。

4.1.2 硬件流控和软件流控的区别与应用

硬件流控 使用RTS/CTS(请求发送/清除发送)信号线进行流控制,通过硬件电路确保发送方和接收方的速度匹配,避免了缓冲区溢出。硬件流控适合于高速通信。

flowchart LR
    S[发送方]
    R[接收方]
    S -- RTS --> R
    R -- CTS --> S

软件流控 则是使用特殊的字符来控制数据流。例如,XON和XOFF用于开始和停止数据传输。软件流控简单,但不如硬件流控可靠,适用于低速通信。

| 控制字符 | 描述                                 |
|----------|--------------------------------------|
| XON      | 启动数据流传输                       |
| XOFF     | 暂停数据流传输                       |

4.2 参数配置在VB与51单片机中的应用

4.2.1 VB端串口参数配置方法

在VB中,串口参数配置主要通过MSComm控件进行。首先,需要在VB的工具箱中添加Microsoft Comm Control 6.0控件,然后在窗体中拖放此控件。

' VB中MSComm控件配置代码示例
Private Sub Form_Load()
    With MSComm1
        .CommPort = 1 ' 选择COM端口
        .Settings = "9600,N,8,1" ' 设置波特率、奇偶校验、数据位、停止位
        .PortOpen = True ' 打开串口
    End With
End Sub

4.2.2 51单片机端串口初始化配置

在51单片机的C语言编程中,串口初始化通过设置特殊功能寄存器来完成。例如,设置串口波特率、模式、使能串口接收等。

/* 51单片机串口初始化配置示例 */
void Serial_Init() {
    TMOD = 0x20;  // 使用定时器1作为波特率发生器
    TH1 = 0xFD;   // 设置波特率为9600
    SCON = 0x50;  // 设置串口为模式1(8位数据, 可变波特率)
    TR1 = 1;      // 启动定时器1
    TI = 1;       // 设置发送标志位
    RI = 0;       // 清除接收标志位
}

4.3 参数配置对通信效率的影响

4.3.1 参数配置对数据传输速率的影响

参数配置直接影响到数据传输速率。例如,波特率越高,单位时间内传输的数据量就越大。但是,波特率的提升也意味着对设备的处理能力要求更高,错误率也可能会有所增加。

4.3.2 实际通信中参数的调整与优化

在实际应用中,通信参数的配置需要根据实际场景来调整。例如,若通信环境复杂或数据传输任务繁重,需要设置合适的校验方式和流控方式来保障通信的可靠性。而在数据传输任务量较小的情况下,可以适当降低波特率来减小错误率。

| 场景条件         | 推荐配置               |
|------------------|------------------------|
| 数据量小,通信距离短 | 9600, 8N1, 无流控       |
| 数据量大,通信距离短 | 57600, 8E1, 硬件流控   |
| 数据量小,通信距离长 | 1200, 7E1, 软件流控     |

以上介绍的串口通信参数配置,都是为了确保数据传输的效率和可靠性。在实际应用中,开发者需要根据具体的硬件设备、通信距离和数据传输需求来优化参数配置。

5. “串口2控制led”文件分析

5.1 文件功能概述与需求分析

5.1.1 串口控制LED的基本原理

在嵌入式系统中,利用串口通信控制LED灯是一种常见的应用实例。基本原理是通过微控制器(如51单片机)的串口接收外部设备发送的指令,然后通过编写固件代码实现对LED灯亮灭或闪烁的控制。这个过程涉及到串口数据的发送、接收、解码和执行相应的硬件操作。

5.1.2 功能需求和性能指标

功能需求通常包括:
- LED灯的开关控制。
- LED灯的闪烁模式设置。
- 系统响应时间的最优化。
- 代码的模块化和可扩展性。

性能指标可能涉及:
- 系统实时响应时间。
- 程序的内存占用。
- 代码的执行效率和稳定性。

5.2 文件中程序结构与流程解析

5.2.1 VB程序的主控流程

VB程序通过一个循环监听串口,当接收到特定指令时,触发相应的事件处理函数。主控流程大致如下:

' VB端伪代码示例
Do While True
    If SerialPort.BytesToRead > 0 Then
        Dim command As String = SerialPort.ReadLine()
        HandleCommand(command)
    End If
Loop

' 处理接收到的指令
Sub HandleCommand(ByVal command As String)
    Select Case command
        Case "ON"
            TurnOnLed()
        Case "OFF"
            TurnOffLed()
        ' 其他指令处理
    End Select
End Sub

' 执行开启LED灯
Sub TurnOnLed()
    ' 发送指令到单片机
    SerialPort.WriteLine("LED ON")
End Sub

' 执行关闭LED灯
Sub TurnOffLed()
    ' 发送指令到单片机
    SerialPort.WriteLine("LED OFF")
End Sub

以上代码展示了VB程序如何监听串口并根据接收到的指令控制LED的状态。

5.2.2 51单片机程序的响应机制

在单片机端,通常会有一个主循环以及串口中断服务程序来响应VB端发送的指令。以下是单片机端的伪代码:

// 51单片机端伪代码示例
void main() {
    // 初始化串口
    SerialInit();
    while(1) {
        // 主循环保持空闲
    }
}

// 串口中断服务程序
void SerialInterrupt() {
    if (SerialDataReceived()) {
        char command = GetSerialData();
        HandleSerialCommand(command);
    }
}

// 根据指令控制LED
void HandleSerialCommand(char command) {
    switch(command) {
        case 'LED ON':
            SetLedHigh();
            break;
        case 'LED OFF':
            SetLedLow();
            break;
        // 其他指令处理
    }
}

// 设置LED高电平(开灯)
void SetLedHigh() {
    P1 = 0xFF; // 假设P1端口连接LED
}

// 设置LED低电平(关灯)
void SetLedLow() {
    P1 = 0x00; // 假设P1端口连接LED
}

这段代码表明了单片机如何通过串口中断来处理来自VB端的控制指令,并执行相应的硬件操作。

5.3 项目实践与问题解决

5.3.1 实际操作过程中的问题与调试

在实际操作中可能会遇到的问题包括串口通信不稳定、指令解析错误、硬件操作延时等。调试方法可能包括:
- 使用串口监视工具检查数据传输是否正确。
- 在单片机端增加指令解析验证,确保指令正确执行。
- 优化代码逻辑,减少不必要的延时和资源占用。

5.3.2 项目实践中的经验总结与优化建议

经验总结可能指出:
- 模块化编程有助于代码的维护和升级。
- 硬件与软件的调试过程需要并行进行,以便更快地发现问题。
- 详细的日志记录对于故障诊断至关重要。

优化建议可能包括:
- 使用校验和机制增加数据传输的可靠性。
- 在单片机端引入缓冲区,改善数据处理效率。
- 在VB端增加异常处理机制,提升系统稳定性。

通过这种方式,我们不仅能够理解串口控制LED灯的代码结构,还可以了解背后的实现原理和优化方法。最终,确保项目能够在各种情况下高效、稳定地运行。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:本文将深入探讨如何利用Visual Basic(VB)编写上位机代码,并与C语言编写的51单片机程序协作,实现对LED灯的控制。上位机是指在个人计算机上运行的应用程序,用于与单片机等下位机通信控制硬件设备。文中详细说明了VB创建图形用户界面、处理串口通信、以及编写事件驱动程序的过程,同时介绍了如何使用C语言编写51单片机固件代码,进行串口初始化、中断服务和GPIO控制。文章还讨论了串口通信参数的配置,以及如何通过文件”串口2控制led”来理解VB与单片机的通信实现。最终目标是帮助读者掌握上位机与下位机通信的编程知识,以及硬件控制的实现。


本文还有配套的精品资源,点击获取
menu-r.4af5f7ec.gif

内容概要:本文档定义了一个名为 `xxx_SCustSuplier_info` 的视图,用于整合和展示客户(Customer)和供应商(Supplier)的相关信息。视图通过连接多个表来获取组织单位、客户账户、站点使用、位置、财务代码组合等数据。对于客户部分,视图选择了账单相关的记录,并提取了账单客户ID、账单站点ID、客户名称、账户名称、站点代码、状态、付款条款等信息;对于供应商部分,视图选择了有效的供应商及其站点信息,包括供应商ID、供应商名称、供应商编号、状态、付款条款、财务代码组合等。视图还通过外连接确保即使某些字段为空也能显示相关信息。 适合人群:熟悉Oracle ERP系统,尤其是应付账款(AP)和应收账款(AR)模块的数据库管理员或开发人员;需要查询和管理客户及供应商信息的业务分析师。 使用场景及目标:① 数据库管理员可以通过此视图快速查询客户和供应商的基本信息,包括账单信息、财务代码组合等;② 开发人员可以利用此视图进行报表开发或数据迁移;③ 业务分析师可以使用此视图进行数据分析,如信用评估、付款周期分析等。 阅读建议:由于该视图涉及多个表的复杂连接,建议读者先熟悉各个表的结构和关系,特别是 `hz_parties`、`hz_cust_accounts`、`ap_suppliers` 等核心表。此外,注意视图中使用的外连接(如 `gl_code_combinations_kfv` 表的连接),这可能会影响查询结果的完整性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值