引言:随着嵌入式系统的发展,串口通信(UART)成为了不同硬件平台之间进行数据传输和控制的重要手段。在嵌入式系统中,串口通信的应用十分广泛,尤其是在处理器与外设、微控制器之间的数据交换中,串口通信的稳定性和高效性至关重要。本文将重点介绍 K230 系列处理器的 UART 外设及其在实际开发中的应用,结合具体的代码示例,深入探讨如何利用串口进行数据的发送、接收及串口回环测试等常见操作。
通过本篇文章,读者将能够全面了解 K230 的 UART 外设功能,掌握如何通过 CanMV IDE 环境开发串口通信程序,并通过具体案例学习如何在 K230 与其他硬件设备(如 STM32)之间实现数据交换。
目录
一、什么是串口?串口的本质
对于协议类的问题,我们应该系统性的学习,在之前笔者有对于各种协议的汇总,包含uart、IIC、SPI、CAN、232、485、等等基础协议以及变种协议modbus等,如果想系统性学习可以回到之前看看文章,接下来就是先认识串口通信了,在使用相关API的时候,很少会理解该协议的本质,如下笔者开始阐述,带你搞懂UART协议。
UART(Universal Asynchronous Receiver-Transmitter,通用异步收发传输器)是嵌入式系统和电子设备中常用的一种串行通信协议。UART的广泛应用主要集中在微控制器、嵌入式系统模块、传感器以及调试接口等方面。甚至以前的电脑都是自带串口的老式的DB9
接口,不过随着科技发展在个人PC上被逐渐淘汰了,被USB等更现代化的接口替代了。
其是一种异步串行通信协议,发送端和接收端的数据传输不需要时钟信号同步,也就是说不需要额外的时钟线。UART主要通过以下两条线来进行数据传输:
- TXD(Transmit Data):数据发送端,将数据从发送设备发送到接收设备。
- RXD(Receive Data):数据接收端,用于接收从发送设备发来的数据。
通信时,UART会将并行数据(如8位数据)用移位寄存器转换成串行格式逐位按照比特顺序发送发送;接收端会将将比特(bit)数据组装为字节,供系统进一步处理。
UART数据帧格式,UART的本质(重要)
-
空闲位:
- 处于高电平(逻辑 1)。
-
起始位:
- 1 位,发送 0(逻辑低电平)。
- 用于标识数据传输的开始。
-
数据位:
- 一般为 8 位,数据以二进制 0 或 1 的形式传输。
- 在 5 至 8 位的数据中,低位先发送(从右至左)。
-
校验位:
- 可选的 1 位,用于检验数据的准确性。
- 常见的校验方式有奇偶校验(可以是奇校验或偶校验)。
-
停止位:
- 停止位用来结束数据传输,通常为 1 位,发送 1(高电平)。
- 可以选择 1 位、1.5 位或 2 位的停止位。
- 发送端:先发送起始位,将TX线拉低,然后依次发送数据位,接着发送可选的奇偶校验位,最后发送停止位。
- 接收端:检测起始位的到来,然后按顺序接收数据位,校验位(如果有),并通过停止位判断传输结束。
串口可以工作在单工【一根数据线】、半双工【一根数据线】和全双工【两根数据线】模式下。
- 单工:在通信的任意时刻,信息只能由 A 传到 B。
- 半双工:在通信的任意时刻,信息即可由 A 传到 B,又能由 B 传到 A,但同时只能有一个方向上的传输存在。同一条数据线。
- 全双工:在通信的任意时刻,通信线路上存在 A 到 B 和 B 到 A 的双向信号传输。
二、K230的UART外设
针对于K230我们还是可以用之前的办法来查询相关外设,也就是如下的方法:
from machine import FPIOA
# 实例化FPIOA
fpioa = FPIOA()
# 打印所有引脚配置
fpioa.help()
我们也可以根据下述表格来找到相关引脚。
排针引脚号 | 芯片引脚号 | 串口功能号 | 备注 |
---|---|---|---|
03 | GPIO 49 | UART4_RXD | 同时连入摄像头2(CSI2)用作IIC通讯,板子内部有4.7K的电阻上拉至3.3V |
05 | GPIO 48 | UART4_TXD | 同时连入摄像头2(CSI2)用作IIC通讯,板子内部有4.7K的电阻上拉至3.3V |
08 | GPIO 03 | UART1_TXD | Na |
10 | GPIO 04 | UART1_RXD | Na |
11 | GPIO 05 | UART2_TXD | Na |
13 | GPIO 06 | UART2_RXD | Na |
27 | GPIO 41 | UART1_RXD | 同时连入摄像头1(CSI1)用作IIC通讯,板子内部有4.7K的电阻上拉至3.3V |
28 | GPIO 40 | UART1_TXD | 同时连入摄像头1(CSI1)用作IIC通讯,板子内部有4.7K的电阻上拉至3.3V |
29 | GPIO 36 | UART4_TXD | Na |
31 | GPIO 37 | UART4_RXD | Na |
37 | GPIO 32 | UART3_TXD | Na |
40 | GPIO 33 | UART3_RXD | Na |
本身是有五个串口可以使用的,但是有些串口会被占用以及与上位机通讯调试之类的作用,因此我们需要结合自身的开发板找到合适的串口才行,我们需要根据原理图以及相关固件程序来明确。
这里笔者使用串口2,如下所示:
丝印简称 | 芯片引脚号 | 串口功能号 | 备注 |
---|---|---|---|
V | Na | Na | 5V输入输出口 |
R | GPIO 11 | UART2_RXD | Na |
T | GPIO 12 | UART2_TXD | Na |
G | Na | Na | GND,接地点 |
需要注意的是 K230 芯片内部集成了 5 个 UART 硬件模块,其中 UART0 被小核(sh)占用,UART3 被大核(sh)占用,剩余的 UART1、UART2 和 UART4 供用户使用。用户在使用时,可通过 IOMUX 模块进行 UART 引脚的配置。
三、CanMV IDE UART 使用方法
K230 内部集成了五个 UART(通用异步收发传输器)硬件模块,串口3(当前固件没被占用,但如果使用的是Linux+RT-Smart SDK就会被小核占用,如果用最新的CanMV固件则用户可以使用);串口0(被RT-Smart占用,最新的CanMV K230固件中只在大核中运行了RT-Smart),剩下的串口1,2,3,4均可被用户正常调用。
使用 machine
模块来配置 UART 串口的引脚,并使用 FPIOA
来设置引脚的功能。
from machine import UART
from machine import FPIOA
fpioa = FPIOA()
# 将指定引脚配置为 UART 功能
fpioa.set_function(11, FPIOA.UART2_TXD)
fpioa.set_function(12, FPIOA.UART2_RXD)
1.构造函数
uart = UART(id, baudrate=115200, bits=UART.EIGHTBITS, parity=UART.PARITY_NONE, stop=UART.STOPBITS_ONE)
参数 | 类型 | 有效值 | 默认值 | 描述 |
---|---|---|---|---|
id | 常量 | UART.UART1 、UART.UART2 、UART.UART3 、UART.UART4 | 无(必须指定) | UART 模块编号,选择对应的 UART 模块(如 UART1 、UART2 等)。 |
baudrate | 整数 | 任意正整数(如 9600、115200、460800、921600 等) | 115200 | 波特率,表示串口通信的传输速率,单位为比特每秒(bps)。 |
bits | 常量 | UART.FIVEBITS 、UART.SIXBITS 、UART.SEVENBITS 、UART.EIGHTBITS | UART.EIGHTBITS | 数据位数,表示每个字符的位数。常见的为 8 位。 |
parity | 常量 | UART.PARITY_NONE 、UART.PARITY_ODD 、UART.PARITY_EVEN | UART.PARITY_NONE | 校验位,用于检查数据传输中的错误。可选择无校验、奇校验或偶校验。 |
stop | 常量 | UART.STOPBITS_ONE 、UART.STOPBITS_TWO | UART.STOPBITS_ONE | 停止位数,标识数据帧结束时使用的停止位数。常见的为 1 位或 2 位停止位。 |
案例:
uart = UART(UART.UART1, baudrate=9600, bits=UART.SEVENBITS, parity=UART.PARITY_EVEN, stop=UART.STOPBITS_ONE)
创建了一个 UART1
模块,波特率为 9600,比特位为 7 位,使用偶校验位,停止位为 1 位。
2.串口初始化
uart.init(baudrate=115200, bits=UART.EIGHTBITS, parity=UART.PARITY_NONE, stop=UART.STOPBITS_ONE)
3.串口read
函数
uart.read([nbytes])
4.串口readline
函数
uart.readline()
5.串口readinto
函数
uart.readinto(buf[, nbytes])
6.串口write
函数
uart.write(buf)
7.串口deinit
函数
uart.deinit()
四、实际案例-K230发送数据
发送基本数据
K230 UART发送基本数据
from machine import UART
from machine import FPIOA
# 配置引脚
fpioa = FPIOA()
fpioa.set_function(11, FPIOA.UART2_TXD)
fpioa.set_function(12, FPIOA.UART2_RXD)
# 初始化UART2,波特率115200,8位数据位,无校验,1位停止位
uart = UART(UART.UART2, baudrate=115200, bits=UART.EIGHTBITS, parity=UART.PARITY_NONE, stop=UART.STOPBITS_ONE)
# 要发送的字符串
message = "Hello,LuShan-Pi!\n"
# 通过UART发送数据
uart.write(message)
# 释放UART资源
uart.deinit()
使用 UART2
串口进行数据通信。首先,使用 FPIOA
类来配置物理引脚,将引脚 11 设置为 UART2
的发送数据引脚(TXD),将引脚 12 设置为 UART2
的接收数据引脚(RXD)。接下来,初始化 UART2
串口,设置波特率为 115200,数据位为 8 位,无奇偶校验,停止位为 1 位。然后,定义了一个字符串 message = "Hello,LuShan-Pi!\n"
作为要发送的内容,并通过 uart.write(message)
通过 UART2
发送该字符串。最后,通过 uart.deinit()
释放了 UART2
资源,关闭了串口通信。
发送字节数组
如下方式即可,非常简单,相信大家都可以看懂。
from machine import UART
from machine import FPIOA
# 配置引脚
fpioa = FPIOA()
fpioa.set_function(11, FPIOA.UART2_TXD)
fpioa.set_function(12, FPIOA.UART2_RXD)
# 初始化UART2,波特率115200,8位数据位,无校验,1位停止位
uart = UART(UART.UART2, baudrate=115200, bits=UART.EIGHTBITS, parity=UART.PARITY_NONE, stop=UART.STOPBITS_ONE)
# 发送字节数组
data = bytes([0x01, 0x02, 0x03, 0x04])
uart.write(data)
# 释放UART资源
uart.deinit()
五、实际案例-K230接收数据
接收数据代码
K230 UART的接收数据代码如下所示:
from machine import UART
from machine import FPIOA
# 配置引脚
fpioa = FPIOA()
fpioa.set_function(11, FPIOA.UART2_TXD)
fpioa.set_function(12, FPIOA.UART2_RXD)
# 初始化UART2,波特率115200,8位数据位,无校验,1位停止位
uart = UART(UART.UART2, baudrate=115200, bits=UART.EIGHTBITS, parity=UART.PARITY_NONE, stop=UART.STOPBITS_ONE)
data = b''
#如果接收不到数据就一直尝试读取
while data == b'':
# 读取数据
data = uart.read() # 尝试读取数据
#通过CanMV IDE K230中的串行终端控制台打印出来
print("Received:", data)
#通过串口2发送接收到的数据
uart.write("UART2 Received:{}\n".format(data))
# 释放UART资源
uart.deinit()
通过 FPIOA
配置了 UART2
的传输和接收引脚,随后初始化了 UART2
串口,设置了波特率为 115200,数据位为 8 位,无校验位,停止位为 1 位。接下来,代码在一个 while
循环中持续尝试读取通过 UART2
接收到的数据,如果没有数据接收,则会继续读取。一旦接收到数据,它会打印该数据到控制台,并将接收到的数据通过串口回传。最后,代码通过 uart.deinit()
释放了 UART2
资源,关闭了串口通信。这段代码适用于串口通信的基本数据接收与回传操作。
接受换行符结尾的文本
如果接收的数据是以换行符结尾的文本,可以使用 uart.readline()
方法读取一整行数据。
from machine import UART
from machine import FPIOA
# 配置引脚
fpioa = FPIOA()
fpioa.set_function(11, FPIOA.UART2_TXD)
fpioa.set_function(12, FPIOA.UART2_RXD)
# 初始化UART2,波特率115200,8位数据位,无校验,1位停止位
uart = UART(UART.UART2, baudrate=115200, bits=UART.EIGHTBITS, parity=UART.PARITY_NONE, stop=UART.STOPBITS_ONE)
line = b''
#如果接收不到数据就一直尝试读取
while line == b'':
# 读取数据
line = uart.read() # 尝试读取数据
#通过CanMV IDE K230中的串行终端控制台打印出来
print("Received:", line)
#通过串口2发送接收到的数据
uart.write("UART2 Received:{}\n".format(line))
# 释放UART资源
uart.deinit()
通过 UART2
串口接收数据,并通过串口将接收到的数据回传。首先,使用 FPIOA
配置了引脚 11 和 12,分别作为 UART2
的发送(TXD)和接收(RXD)引脚。接着,初始化了 UART2
,设置波特率为 115200,数据位为 8 位,无校验位,停止位为 1 位。在进入一个 while
循环后,代码持续尝试读取串口接收到的数据(通过 uart.read()
),直到接收到数据为止。当数据被成功接收后,打印接收到的数据到控制台。接着,通过 UART2
将接收到的数据回传并格式化显示。最后,使用 uart.deinit()
释放 UART2
资源,关闭串口通信。这个过程展示了如何通过 UART 接收数据并将其回传的基本操作。
六、实际案例-串口回环测试
import time
from machine import UART
from machine import FPIOA
# 配置引脚
fpioa = FPIOA()
fpioa.set_function(11, FPIOA.UART2_TXD)
fpioa.set_function(12, FPIOA.UART2_RXD)
# 初始化UART2,波特率115200,8位数据位,无校验,1位停止位
uart = UART(UART.UART2, baudrate=115200, bits=UART.EIGHTBITS, parity=UART.PARITY_NONE, stop=UART.STOPBITS_ONE)
# 要测试的消息
test_message = b'UART Loopback Test!'
# 发送数据
uart.write(test_message)
# 等待数据发送和接收(根据波特率和数据长度,调整延时)
time.sleep(0.1)
# 如果接收不到数据就一直尝试读取
received_data = b''
received_data = uart.read()
if received_data:
received_message = received_data
print("Received:", received_message)
if received_message == test_message:
print("Loopback Test Passed!")
else:
print("Loopback Test Failed: Data Mismatch")
else:
print("Loopback Test Failed: No Data Received")
print("test_message is {}".format(test_message))
print("received_message is {}".format(received_message))
# 释放UART资源
uart.deinit()
UART 环回测试。首先,使用 FPIOA
配置了引脚 11 和 12,分别作为 UART2
的发送(TXD)和接收(RXD)引脚。接着,初始化了 UART2
,设置了波特率为 115200,数据位为 8 位,无校验位,停止位为 1 位。然后定义了一个要测试的消息 test_message
,并通过 uart.write()
发送这个消息。
在发送数据之后,代码通过 time.sleep(0.1)
让程序暂停 0.1 秒,等待数据发送和接收。接下来,通过 uart.read()
尝试读取接收到的数据。如果成功接收到数据,程序会判断接收到的数据是否与发送的测试消息一致。如果一致,则打印 "Loopback Test Passed!",否则打印 "Loopback Test Failed: Data Mismatch"。如果没有接收到任何数据,则会打印 "Loopback Test Failed: No Data Received"。
最后,代码通过 print()
显示了发送的消息和接收到的消息,并使用 uart.deinit()
释放 UART 资源,关闭串口通信。这段代码的目的是验证 UART 串口的环回功能,确保发送的数据能够被正确接收。
七、STM32与K230串口通信 数据包的形式接收发送
K230与STM32串口连接(接线TX对RX即可),如下就是K230发送一个含有包头包尾的数据包格式,然后呈现在oled屏幕上。
直接附上所有代码,首先是K230的,如下所示:
import time
import os
import gc
import sys
import math
from media.sensor import *
from media.display import *
from media.media import *
from machine import UART
from machine import FPIOA
DETECT_WIDTH = 640
DETECT_HEIGHT = 480
# 只跟踪红色物体的阈值 (L Min, L Max, A Min, A Max, B Min, B Max)
# 红色的阈值
red_thresholds = [(30, 68, 9, 127, -12, 73)] # 通用红色阈值 -> 索引为 0,所以代码 == (1 << 0)
sensor = None
# 配置引脚
fpioa = FPIOA()
fpioa.set_function(11, FPIOA.UART2_TXD)
fpioa.set_function(12, FPIOA.UART2_RXD)
# 初始化UART2,波特率115200,8位数据位,无校验,1位停止位
uart = UART(UART.UART2, baudrate=115200, bits=UART.EIGHTBITS, parity=UART.PARITY_NONE, stop=UART.STOPBITS_ONE)
try:
# 使用默认配置构造一个Sensor对象
sensor = Sensor(width=DETECT_WIDTH, height=DETECT_HEIGHT)
# sensor复位
sensor.reset()
# 设置通道 0 输出大小
sensor.set_framesize(width=DETECT_WIDTH, height=DETECT_HEIGHT)
# 设置通道 0 输出格式
sensor.set_pixformat(Sensor.RGB565)
# 设置显示
Display.init(Display.VIRT, width=DETECT_WIDTH, height=DETECT_HEIGHT, fps=100)
# 初始化媒体管理器
MediaManager.init()
# sensor开始运行
sensor.run()
fps = time.clock()
while True:
fps.tick()
# 检查是否应该退出
os.exitpoint()
img = sensor.snapshot()
# 只检测符合红色阈值的斑点
for blob in img.find_blobs(red_thresholds, pixels_threshold=100, area_threshold=100, merge=True):
if blob.code() == 1: # 代码为 1 表示仅红色
# 绘制矩形框
img.draw_rectangle([v for v in blob.rect()])
# 绘制十字准星
img.draw_cross(blob.cx(), blob.cy())
# 绘制旋转角度
img.draw_keypoints([(blob.cx(), blob.cy(), int(math.degrees(blob.rotation())))], size=20)
# 获取色块在屏幕上的位置
x, y, w, h = blob.rect()
print(f"Blob position: (x: {x}, y: {y}, w: {w}, h: {h})")
# 发送 x 和 y 坐标到串口
data = bytes([0xFF, x & 0xFF, (x >> 8) & 0xFF,
y & 0xFF, (y >> 8) & 0xFF, 0xFE])
uart.write(data)
# 将结果绘制到屏幕上
Display.show_image(img)
gc.collect()
print(fps.fps())
except KeyboardInterrupt as e:
print(f"user stop")
except BaseException as e:
print(f"Exception '{e}'")
finally:
# sensor停止运行
if isinstance(sensor, Sensor):
sensor.stop()
# 销毁display
Display.deinit()
os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)
time.sleep_ms(100)
# 释放媒体缓冲区
MediaManager.deinit()
# 释放UART资源
uart.deinit()
上述代码就是一个根据色度追踪图片呈现在画面屏幕的位置,然后发送到STM32。
其次是STM32的代码,如下所示:
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Serial.h"
#include "Key.h"
int main(void)
{
OLED_Init();
Serial_Init();
OLED_ShowString(1, 1, "RxPacket");
while (1)
{
if (Serial_GetRxFlag() == 1)
{
OLED_ShowHexNum(2, 1, Serial_RxPacket[0], 2);
OLED_ShowHexNum(2, 4, Serial_RxPacket[1], 2);
OLED_ShowHexNum(2, 7, Serial_RxPacket[2], 2);
OLED_ShowHexNum(2, 10, Serial_RxPacket[3], 2);
}
}
}
#include "stm32f10x.h" // Device header
#include <stdio.h>
#include <stdarg.h>
uint8_t Serial_TxPacket[4]; //FF 01 02 03 04 FE
uint8_t Serial_RxPacket[4];
uint8_t Serial_RxFlag;
void Serial_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1, &USART_InitStructure);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);
USART_Cmd(USART1, ENABLE);
}
void Serial_SendByte(uint8_t Byte)
{
USART_SendData(USART1, Byte);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
void Serial_SendArray(uint8_t *Array, uint16_t Length)
{
uint16_t i;
for (i = 0; i < Length; i ++)
{
Serial_SendByte(Array[i]);
}
}
void Serial_SendString(char *String)
{
uint8_t i;
for (i = 0; String[i] != '\0'; i ++)
{
Serial_SendByte(String[i]);
}
}
uint32_t Serial_Pow(uint32_t X, uint32_t Y)
{
uint32_t Result = 1;
while (Y --)
{
Result *= X;
}
return Result;
}
void Serial_SendNumber(uint32_t Number, uint8_t Length)
{
uint8_t i;
for (i = 0; i < Length; i ++)
{
Serial_SendByte(Number / Serial_Pow(10, Length - i - 1) % 10 + '0');
}
}
int fputc(int ch, FILE *f)
{
Serial_SendByte(ch);
return ch;
}
void Serial_Printf(char *format, ...)
{
char String[100];
va_list arg;
va_start(arg, format);
vsprintf(String, format, arg);
va_end(arg);
Serial_SendString(String);
}
void Serial_SendPacket(void)
{
Serial_SendByte(0xFF);
Serial_SendArray(Serial_TxPacket, 4);
Serial_SendByte(0xFE);
}
uint8_t Serial_GetRxFlag(void)
{
if (Serial_RxFlag == 1)
{
Serial_RxFlag = 0;
return 1;
}
return 0;
}
void USART1_IRQHandler(void)
{
static uint8_t RxState = 0;
static uint8_t pRxPacket = 0;
if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
{
uint8_t RxData = USART_ReceiveData(USART1);
if (RxState == 0)
{
if (RxData == 0xFF)
{
RxState = 1;
pRxPacket = 0;
}
}
else if (RxState == 1)
{
Serial_RxPacket[pRxPacket] = RxData;
pRxPacket ++;
if (pRxPacket >= 4)
{
RxState = 2;
}
}
else if (RxState == 2)
{
if (RxData == 0xFE)
{
RxState = 0;
Serial_RxFlag = 1;
}
}
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
}
上述涉及到十进制转十六进制,如果不会转的读者可以看下述例子,
表达式 x = (0x01 << 8) | 0x5F
可以分解为两步:
-
0x01 << 8
:将0x01
(十六进制的1)左移8位,得到0x0100
(十六进制的256)。 -
0x0100 | 0x5F
:按位或运算,将0x0100
(十六进制的256)和0x5F
(十六进制的95)进行按位或。计算如下:0x0100
= 00000001 000000000x5F
= 00000000 01011111 按位或的结果是:0x015F
(十六进制的351)。
所以,最终结果 x = 0x015F
,十进制值为 351。