蓝桥杯2024/1/26笔记-----基于PCF8591的电压采集装置
功能实现要求:
每次建好工程文件夹,里边包含User(放工程文件,mian.c,可以在这里写如同我这个文章的文本文档)、Driver(存放底层文件如Led.c,Led.h等)
新建的工程先搭建框架,可以先书写底层函数(此次书写了五个函数并包含相应的头文件共十个底层文件)
底层函数内容:
1.初始化底层驱动专用文件
比如先用3个IO口控制74HC138译码器,控制Y4为低电平;当Y4为低电平时,或非门74HC02控制Y4C为高电平,使74HC573的OE端口有效,OE端口有效时,可使用P0口控制LED的亮灭。
可以去多了解74HC138译码器,74HC02或非门,74HC573八路输出透明锁存器的相关内容会更好理解
#include <Init.h>
//关闭外设
void System_Init()
{
P0 = 0xff;
P2 = P2 & 0x1f | 0x80;
P2 &= 0x1f;
P0 = 0x00;
P2 = P2 & 0x1f | 0xa0;
P2 &= 0x1f;
}
//头文件
#include <STC15F2K60S2.H>
void System_Init();
2.Led底层驱动专用文件
与初始化底层驱动专用文件同理,需要了解对应的锁存器控制,可以在使用的芯片数据手册查看
#include <Led.h>
void Led_Disp(unsigned char addr,enable)
{
static unsigned char temp = 0x00;
static unsigned char temp_Old = 0xff;
if(enable)
temp |=0x01 << addr;
else
temp&= ~ (0x01 << addr);
if(temp != temp_Old)
{
P0 = ~ temp;
P2 = P2 & 0x1f | 0x80;
P2 &= 0x1f;
temp_Old = temp;
}
}
void Beep(unsigned char flag)
{
static unsigned char temp = 0x00;
static unsigned char temp_Old = 0xff;
if(flag)
temp |=0x40 ;
else
temp &= ~ 0x40 ;
if(temp != temp_Old)
{
P0 = ~ temp;
P2 = P2 & 0x1f | 0xa0;
P2 &= 0x1f;
temp_Old = temp;
}
}
void Relay(unsigned char flag)
{
static unsigned char temp = 0x00;
static unsigned char temp_Old = 0xff;
if(flag)
temp |= 0x10 ;
else
temp &= ~ 0x10 ;
if(temp != temp_Old)
{
P0 = ~ temp;
P2 = P2 & 0x1f | 0xa0;
P2 &= 0x1f;
temp_Old = temp;
}
}
//头文件
#include <STC15F2K60S2.H>
void Led_Disp(unsigned char addr,enable);
3.按键底层驱动专用文件
(板子上的按键从按键4开始到按键19,可根据实际硬件修改)
#include <Key.h>
unsigned char Key_Read()
{
unsigned char temp = 0;
P44 = 0;P42 = 1; P35 = 1;P34 = 1;//这个仿真没有P4口,不适用,但是实际运行使用这个
P37 = 0; P36 = 1; P35 = 1; P34 = 1;
if(P33 == 0) temp = 4;
if(P32 == 0) temp = 5;
if(P31 == 0) temp = 6;
if(P30 == 0) temp = 7;
P37 = 1; P36 = 0; P35 = 1; P34 = 1;
if(P33 == 0) temp = 8;
if(P32 == 0) temp = 9;
if(P31 == 0) temp = 10;
if(P30 == 0) temp = 11;
P37 = 1; P36 = 1; P35 = 0; P34 = 1;
if(P33 == 0) temp = 12;
if(P32 == 0) temp = 13;
if(P31 == 0) temp = 14;
if(P30 == 0) temp = 15;
P37 = 1; P36 = 1; P35 = 1; P34 = 0;
if(P33 == 0) temp = 16;
if(P32 == 0) temp = 17;
if(P31 == 0) temp = 18;
if(P30 == 0) temp = 19;
return temp;
}
//头文件
#include <STC15F2K60S2.H>
unsigned char Key_Read();
4.数码管底层驱动专用文件
#include <Seg.h>
unsigned char Seg_Dula[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};//数码管段码储存数组
unsigned char Seg_Wela[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//数码管位码储存数组
void Seg_Disp(unsigned char wela,dula,point)
{
P0 = 0xff; //
P2 = P2 & 0x1f |0xe0;
P2 &= 0x1f;
P0 = Seg_Wela[wela];
P2 = P2 & 0x1f |0xc0;
P2 &= 0x1f;
P0 = Seg_Dula[dula];
if(point)
P0 &= 0x7f;
P2 = P2 & 0x1f |0xe0;
P2 &= 0x1f;
}
//头文件
#include <STC15F2K60S2.H>
void Seg_Disp(unsigned char wela,dula,point);
5.IIC底层驱动文件
/* # I2C代码片段说明
1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include "iic.h"
#include "reg52.h"
#include <intrins.h>
sbit sda = P2^1;
sbit scl = P2^0;
#define DELAY_TIME 5
//
static void I2C_Delay(unsigned char n)
{
do
{
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
}
while(n--);
}
//
void I2CStart(void)
{
sda = 1;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 0;
I2C_Delay(DELAY_TIME);
scl = 0;
}
//
void I2CStop(void)
{
sda = 0;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 1;
I2C_Delay(DELAY_TIME);
}
//
void I2CSendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++){
scl = 0;
I2C_Delay(DELAY_TIME);
if(byt & 0x80){
sda = 1;
}
else{
sda = 0;
}
I2C_Delay(DELAY_TIME);
scl = 1;
byt <<= 1;
I2C_Delay(DELAY_TIME);
}
scl = 0;
}
//
unsigned char I2CReceiveByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++){
scl = 1;
I2C_Delay(DELAY_TIME);
da <<= 1;
if(sda)
da |= 0x01;
scl = 0;
I2C_Delay(DELAY_TIME);
}
return da;
}
//
unsigned char I2CWaitAck(void)
{
unsigned char ackbit;
scl = 1;
I2C_Delay(DELAY_TIME);
ackbit = sda;
scl = 0;
I2C_Delay(DELAY_TIME);
return ackbit;
}
//
void I2CSendAck(unsigned char ackbit)
{
scl = 0;
sda = ackbit;
I2C_Delay(DELAY_TIME);
scl = 1;
I2C_Delay(DELAY_TIME);
scl = 0;
sda = 1;
I2C_Delay(DELAY_TIME);
}
unsigned char Ad_Read(unsigned char addr)//AD读取,要有一个入口参数
{
unsigned char temp;//接收返回值变量
I2CStart();//启动单总线
I2CSendByte(0x90);//发送一个0x90,告诉单片机要写数据了
I2CWaitAck();//等待应答
I2CSendByte(addr);//发送一个地址(获取的数据)
I2CWaitAck();//等待应答
I2CStart();//启动单总线
I2CSendByte(0x91);//写一个0x91
I2CWaitAck();//等待应答
temp = I2CReceiveByte();//读取数据
I2CSendAck(1);//发送一个非应答信号
I2CStop();//停止
return temp;
}
void Da_Write(unsigned char dat)
{
I2CStart();//启动单总线
I2CSendByte(0x90);//发送一个0x90,告诉单片机要写数据了
I2CWaitAck();//等待应答
I2CSendByte(0x41);//使能DAC转换
I2CWaitAck();//等待应答
I2CSendByte(dat);
I2CWaitAck();//等待应答
I2CStop();//停止
}
//头文件
#ifndef _IIC_H
#define _IIC_H
unsigned char Ad_Read(unsigned char addr);//AD读取,要有一个入口参数
void Da_Write(unsigned char dat);
void IIC_Start(void);
void IIC_Stop(void);
bit IIC_WaitAck(void);
void IIC_SendAck(bit ackbit);
void SendByte(unsigned char byt);
unsigned char IIC_RecByte(void);
#endif
工程主函数内容:
1.头文件声明(把需要用到的头文件添加进来)
/*头文件声明区*/
#include <STC15F2K60S2.H>//单片机寄存器专用头文件
#include <Init.h>//初始化底层驱动专用头文件
#include <Led.h>//LED底层驱动专用头文件
#include <Key.h>//按键底层驱动专用头文件
#include <Seg.h>//数码管底层驱动专用头文件
#include "iic.h"//数模转换底层驱动头文件
2.变量声明(把需要用到的所有变量现在这里进行声明)
/*变量声明区*/
unsigned char Key_Val,Key_Old,Key_Down,Key_Up;//按键扫描专用变量
unsigned char Key_Slow_Down;//按键减速专用变量 10ms
unsigned char Seg_Buf[8] = {10,10,10,10,10,10,10,10};//数码管显示数据存放数组
unsigned char Seg_Point[8] = {0,0,0,0,0,0,0,0};//数码管小数点数据存放数组
unsigned char Seg_Pos;//数码管扫描专用变量
unsigned char Seg_Slow_Down;//数码管减速专用变量
unsigned char ucLed[8] = {0,0,0,0,0,0,0,0};//LED显示数据存放数组
//unsigned char dat,dat2;
bit Seg_Disp_Mode;//数码管显示模式变量 0-电压显示界面 1-电压输出界面
float voltage;//实时电压变量
float voltage_Output;//实时电压输出变量
bit Output_Mode;//输出模式专用变量 0-2V 1-随AD输出
bit Seg_Flag = 1;//数码管功能标志位
3.按键处理函数(在这里编写按键控制的函数)
/*键盘处理函数*/
void Key_Proc()
{
if(Key_Slow_Down)return;
Key_Slow_Down = 1;//按键减速程序
Key_Val = Key_Read();//读取按下的键码值
Key_Down = Key_Val & (Key_Val ^ Key_Old);//捕捉下降沿
Key_Up = ~ Key_Val & (Key_Val ^ Key_Old);//捕捉上升沿
Key_Old = Key_Val;//辅助扫描
switch(Key_Down)
{
case 19://显示界面切换按键
Seg_Disp_Mode ^= 1;//取反
break;
case 18://输出模式切换按键
Output_Mode ^= 1;
break;
case 16://数码管功能按键
Seg_Flag ^= 1;
break;
}
}
4.信息处理函数(需要使用到到的函数进行简单的预处理)
/*信息处理函数*/
void Seg_Proc()
{
if(Seg_Slow_Down)return;
Seg_Slow_Down = 1;//数码管减速程序
voltage = Ad_Read(0x43) / 51.0;//实时读取RB2电压数据
if(Output_Mode == 0)//固定输出2V
voltage_Output = 2;
else
voltage_Output = voltage;//随AD输出
//voltage_Output = Output_Mode?voltage:2;//这个同样可以判断输出电压,使用实现两种电压值输出
if(Seg_Disp_Mode == 0)
{
Seg_Buf[0] = 11;//显示U
Seg_Buf[5] = (unsigned char)voltage;//
Seg_Buf[6] = (unsigned int)(voltage * 100) / 10 % 10;//
Seg_Buf[7] = (unsigned int)(voltage * 100) % 10;//
Seg_Point[5] = 1;//点亮小数点
}
else//处于电压输出界面
{
Seg_Buf[0] = 12;//显示U
Seg_Buf[5] = (unsigned char)voltage_Output;//
Seg_Buf[6] = (unsigned int)(voltage_Output * 100) / 10 % 10;//
Seg_Buf[7] = (unsigned int)(voltage_Output * 100) % 10;//
Seg_Point[5] = 1;//点亮小数点
}
// //读取的值是上一次转换的结果,读取两个数据时,人为调换一下
// dat2 = Ad_Read(0x41);//读取AD0x41数据量
// dat = Ad_Read(0x43);
// Da_Write(255);
//
// Seg_Buf[0] = dat / 100 % 10;
// Seg_Buf[1] = dat / 10 % 10;
// Seg_Buf[2] = dat % 10;
//
// Seg_Buf[4] = dat2 / 100 % 10;
// Seg_Buf[5] = dat2 / 10 % 10;
// Seg_Buf[6] = dat2 % 10;
}
5.其他函数(其他编写的函数,在这里书写会比较方便理解)
/*其他函数*/
void Led_Proc()
{
unsigned char i;
Relay(1);//关闭继电器
Beep(1);//关闭蜂鸣器
Da_Write(voltage_Output);//电压输出
for(i =0;i<2;i++)//互斥点亮
ucLed[i] = (i == Seg_Disp_Mode);
if(voltage < 1.5 || (voltage >= 2.5 && voltage < 3.5))
ucLed[2] = 0;
else
ucLed[2] = 1;
ucLed[3] = Output_Mode;
}
6.定时器0中断初始化函数
(这个可以使用STC的定时器计算那里生成c代码,后面要自己添加ET0,EA打开中断)
/*定时器0初始化函数*/
void Timer0Init(void) //1毫秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1;
EA = 1;
}
7.定时器0中断服务函数
(为了定时执行特定的任务,如此处设置了定时的时间触发了数码管和LED产生特定反应)
/*定时器0中断服务函数*/
void Timer0Serve() interrupt 1
{
if(++Key_Slow_Down == 10)Key_Slow_Down = 0;
if(++Seg_Slow_Down == 500)Seg_Slow_Down = 0;
if(++Seg_Pos == 8)Seg_Pos = 0;
if(Seg_Flag == 1)
Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);
else
Seg_Disp(Seg_Pos,10);//熄灭数码管
Led_Disp(Seg_Pos,ucLed[Seg_Pos]);
}
8.主函数Main(调用书写的函数实现所需的相应功能)
/*Main*/
void main()
{
Sys_Init();
Timer0Init();
while(1)
{
Key_Proc();
Seg_Proc();
Led_Proc();
}
}
其他的详细资料在另一篇PCF8591的笔记,有详细讲解AD数模转换的内容和IIC的使用等等。
相关文章:

蓝桥杯2024/1/26笔记-----基于PCF8591的电压采集装置
功能实现要求: 每次建好工程文件夹,里边包含User(放工程文件,mian.c,可以在这里写如同我这个文章的文本文档)、Driver(存放底层文件如Led.c,Led.h等) 新建的工程先搭建框…...

【一】esp32芯片开发板环境搭建
1、esp32的源码在github上的地址 不同的芯片支持的源码版本不一样,需要根据自己的实际的esp32开发板的芯片下载不用版本的代码 esp32支持多种开发方式,如arduino,ESP-IDF等。官方推荐使用idf开发,ESP-IDF 是乐鑫官方推出的物联网开…...

PyTorch2ONNX-分类模型:速度比较(固定维度、动态维度)、精度比较
图像分类模型部署: PyTorch -> ONNX 1. 模型部署介绍 1.1 人工智能开发部署全流程 #mermaid-svg-bAJun9u4XeSykIbg {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-bAJun9u4XeSykIbg .error-icon{fill:#552222;}…...

Docker命令快车道:一票通往高效开发之旅
欢迎登上 Docker 命令快车!在这趟旅程中,你不仅会学会如何驾驭 Docker 这辆神奇的车,还会发现如何让你的开发旅程变得更加轻松愉快。现在,请系好安全带,我们即将出发! Docker 是什么 Docker 就像是一辆超…...

IP类接口大全,含免费次数
IP查询 IP归属地-IPv4高精版:根据IP地址查询归属地信息,支持到中国地区(不含港台地区)街道级别,包含国家、省、市、区县、详细地址和运营商等信息。IP归属地-IPv4区县级:根据IP地址查询归属地信息…...

LLMs 的记忆和信息检索服务器 Motorhead
LLMs 的记忆和信息检索服务器 Motorhead 1. 为什么使用 Motorhead?2. 通过 Docker 启动 Motorhead3. Github 地址4. python 使用示例地址 1. 为什么使用 Motorhead? 使用 LLMs构建聊天应用程序时,每次都必须构建记忆处理。Motorhead是协助该…...

vue3项目中让echarts适应div的大小变化,跟随div的大小改变图表大小
目录如下 我的项目环境如下利用element-resize-detector插件监听元素大小变化element-resize-detector插件的用法完整代码如下:结果如下 在做项目的时候,经常会使用到echarts,特别是在做一些大屏项目的时候。有时候我们是需要根据div的大小改…...

springboot启动异常
Error creating bean with name ‘dataSource’ org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name dataSource: Unsatisfied dependency expressed through field basicProperties; nested exception is org.springframew…...

直播主播之互动率与促单
直播互动率是衡量直播间观众参与度的重要指标,通常指的是直播间的观众点赞、评论以及转发的数量。互动率越高,表明观众参与度越高,直播间的人气值也相应越高。 为了提升直播互动率,主播可以采取以下策略: 1.积极引导观众参与互动…...

Android 基础技术——Bitmap
笔者希望做一个系列,整理 Android 基础技术,本章是关于 Bitmap Bitmap 内存如何计算 占用内存 宽 * 缩放比例 * 高 * 缩放比例 * 每个像素所占字节 缩放比例 设备dpi/图片所在目录的dpi Bitmap加载优化?不改变图片质量的情况下怎么优化&am…...

数据结构奇妙旅程之七大排序
꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好,我是xiaoxie.希望你看完之后,有不足之处请多多谅解,让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …...

【JavaScript】Generator
MDN-Generator Generator对象由生成器函数返回,并且它符合可迭代协议和迭代器协议。 Generator-核心语法 核心语法: 定义生成器函数获取generator对象yield表达式的使用通过for of获取每一个yield的值 // 1. 通过function* 创建生成器函数 function* foo() {//…...

河南省考后天网上确认,请提前准备证件照哦
✔报名时间:2024年1月18号一1月24号 ✔报名确认和缴费:2024年1月 31号一2月4号 ✔准考证打印:2024年3月12号一3月17号 ✔笔试时间:2024年3月16日-2024年3月17日。 ✔面试时间:面试时间拟安排在2024年5月中旬 报名网址&…...

【前端】防抖和节流
防抖 防抖用于限制连续触发的事件的执行频率。当一个事件被触发时,防抖会延迟一定的时间执行对应的处理函数。如果在延迟时间内再次触发了同样的事件,那么之前的延迟执行将被取消,重新开始计时。 总结:在单位时间内频繁触发事件,只有最后一次生效 场景 :用户在输入框输…...

【网络】:网络套接字(UDP)
网络套接字 一.网络字节序二.端口号三.socket1.常见的API2.封装UdpSocket 四.地址转换函数 网络通信的本质就是进程间通信。 一.网络字节序 我们已经知道,内存中的多字节数据相对于内存地址有大端和小端之分, 磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分,网…...

Linux编程 1/2 数据结构
数据结构: 程序 数据结构 算法 1.数据结构: 1.时间复杂度: 数据量的增长与程序运行时间增长所呈现的比例函数,则称为时间渐进复杂度函数简称时间复杂度 O(c) > O(logn)> O(n) > O(nlogn) > O(n^2) > O(n^3) > O(2^n) 2.空间复杂度: 2.类…...

【UE Niagara】实现闪电粒子效果的两种方式
目录 效果 步骤 方式一(网格体渲染器) (1)添加网格体渲染器 (2)修改粒子显示方向 (3)添加从上到下逐渐显现的效果 (4)粒子颜色变化 方式二࿰…...

js数组/对象的深拷贝与浅拷贝
文章目录 一、js中的深拷贝和浅拷贝二、浅拷贝1、Object.assign()2、利用es6扩展运算符(...) 二、深拷贝1、JSON 序列化和反序列化2、js原生代码实现3、使用第三方库lodash等 四、总结 一、js中的深拷贝和浅拷贝 在JS中,深拷贝和浅拷贝是针对…...

HCIA学习第六天:OSPF:开放式最短路径优先协议
OSPF:开放式最短路径优先协议 无类别链路状态IGP动态路由协议 1.距离矢量协议:运行距离矢量协议的路由器会周期性的泛洪自己的路由表。通过路由的交互,每台路由器从相邻的路由器学习到路由,并且加载进自己的路由表中;…...

从四个方面来解决企业在项目管理中遇到的各类问题
案例背景:某建筑集团有限公司成立于1949年,拥有国家房屋建筑工程施工总承包一级、建筑装修装饰工程专业承包一级、市政公用工程施工总承包一级资质。是一家集建筑施工、设备安装、装饰装潢、仿古建筑、房地产开发、建材试验为一体的具有综合生产能力的建…...

使用代码取大量2*2像素图片各通道均值,存于Excel文件中。
任务是取下图RGB各个通道的均值及标签(R, G,B,Label),其中标签由图片存放的文件夹标识。由于2*2像素图片较多,所以将结果放置于Excel表格中,之后使用SVM对他们进行分类。 from PIL import Image import os …...

React16源码: React中commit阶段的commitBeforeMutationLifecycles的源码实现
commitBeforeMutationLifecycles 1 )概述 在 react commit 阶段的 commitRoot 第一个while循环中调用了 commitBeforeMutationLifeCycles现在来看下,里面发生了什么 2 )源码 回到 commit 阶段的第一个循环中,在 commitRoot 函数…...

压制二元组的总价值
压制二元组的总价值 对于每一个 a i a_i ai, 看它能压制它前面的多少个元素, 那么它对总价值的贡献就是: 在a数组中: a i a_i ai压制了x个数, 贡献为: x ∗ i x*i x∗i被 a i a_i ai所压制的所有数在 a a a中的下标和为 y y y, 贡献为 − y -y −y 树状数组来求: 为了…...

【习题】保存应用数据
判断题 1. 首选项是关系型数据库。 错误(False) 2. 应用中涉及到Student信息,如包含姓名,性别,年龄,身高等信息可以用首选项来存储。 错误(False) 3. 同一应用或进程中每个文件仅存在一个Preferences实例。 正确(True) 单选题 …...

Flask框架小程序后端分离开发学习笔记《5》简易服务器代码
Flask框架小程序后端分离开发学习笔记《5》 Flask是使用python的后端,由于小程序需要后端开发,遂学习一下后端开发。 简易服务器代码 接口解析那一块很关键,学后端服务器这一块,感觉主要就是学习相应地址的接口怎么处理。 然后…...

“计算机视觉处理设计开发工程师”专项培训(第二期)
“人工智能技术与咨询” 发布...

R语言学习case7:ggplot基础画图(核密度图)
step1: 导入ggplot2库文件 library(ggplot2)step2:带入自带的iris数据集 iris <- datasets::irisstep3:查看数据信息 dim(iris)维度为 [150,5] head(iris)查看数据前6行的信息 step4:画图展示 plot2 <- ggplot(iris,aes(Sepal.W…...

Ubuntu18配置Docker
1.基本过程 1.更新软件源列表 sudo apt update2.安装软件包依赖 sudo apt install apt-transport-https ca-certificates curl software-properties-common3.在系统中添加Docker的官方密钥 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - …...

Keil/MDK平台 - 结构体成员指针注意事项
文章目录 1 . 前言总结2 . 问题现象3 . 解决思路4 . 细节扩展5 . 总结 【极客技术传送门】 : https://blog.csdn.net/Engineer_LU/article/details/135149485 1 . 前言总结 有时候希望通过类定义的类型指向数据包来解析,恰好又想结构体内定义指针指向一段数据&…...

一款超级好用的远程控制APP,你值得拥有
在这个科技日新月异的时代,我们的生活被各种手机软件所包围。几乎每个人都有一个甚至多个手机,你是否也有遇到过需要远程操作自己某一台手机的场景呢?今天,我要向大家推荐一款神奇的手机远程操作神器,让你可以随时随地…...