【嵌入式】嵌入式Linux开发实战指南:从交叉编译到触摸屏交互

news2024/10/5 21:23:12

文章目录

  • 前言:
  • 1.简介
    • 1.1. 交叉编译工具
    • 1.2. 项目开发流程:
    • 1.3. ARM开发板的连接方法
  • 2. 开发板连接
  • 3. 系统文件 IO
  • 4. 设置共享文件夹
    • 3.1. 读文件
    • 3.2. 写文件
    • 3.2. 设置文件偏移量
  • 4. LCD显示屏显示
    • 4.1. LCD 显示颜色
    • 4.2. 将文件下载到开发板
      • 4.2.1. 在CRT链接开发板中输入命令"rx 需要下载的文件名"
    • 4.3. lcd 使用 write 函数直接写入像素点出现噪点等待一点后又能完全显示
    • 4.4. 开发板lcd 显示 bmp 图片
  • 5. 触摸屏
    • 5.1. 触摸屏 之 Linux 输入子系统模型
    • 5.1.1 input.h
    • 5.1.2 事件数据分析
  • 总结:

前言:

在嵌入式系统开发领域,交叉编译、系统文件IO操作、LCD显示以及触摸屏处理是一些基本且关键的技能。本文将详细介绍这些技能的实现方法和相关技术细节,旨在帮助开发者更好地理解和掌握嵌入式Linux开发过程中的常用操作。我们将从交叉编译工具的介绍开始,逐步深入到项目开发流程、开发板连接方法、系统文件IO的基本操作,再到LCD显示屏的显示技术以及触摸屏的Linux输入子系统模型和事件分析。通过本文的学习,读者将能够获得从硬件连接到软件编程的全面知识。

1.简介

1.1. 交叉编译工具

每个不同的平台可执行的格式都不尽相同,我们需要Linux系统的ARM平台执行程序,故需要ARM-Linux交叉编译工具,ubuntu 交叉编译工具链“arm-linux-gcc”

1.2. 项目开发流程:

1、使用C语言编写项目源代码
2、使用交叉编译工具编译项目源码
3、将编译生成的可执行程序下载到ARM开发板
4、在ARM开发板执行项目程序
5、验证项目程序的准确性

1.3. ARM开发板的连接方法

SecureCRT是一款支持SSH(SSH1和SSH2)的终端仿真程序,简单的说是Windows下登录UNIX或Linux服务器主机的软件。

2. 开发板连接

  1. 使用 串口线 与 usb 转串口线将开发板与电脑进行连接

  2. 检查电脑是否识别 usb 转串口驱动
    在这里插入图片描述

  3. 打开 CRT 软件

  4. 在快速链接向导里向导中进行配置
    在这里插入图片描述

  5. 打开开发板
    在这里插入图片描述

3. 系统文件 IO

  1. 打开文件 open
   #include <sys/types.h>
   #include <sys/stat.h>
   #include <fcntl.h>

   int open(const char *pathname, int flags); 
   // pathname:	需要打开的文件的路径名+文件名
   // flag:		打开文件的模式( O_RDONLY, O_WRONLY, or O_RDWR)
   // 返回值:	成功返回新的文件描述符,失败返回-1和出错码(perror)
  1. 关闭文件 close
   #include <unistd.h>
   int close(int fd);
   // fd:	文件描述符
   // 返回值: 成功返回0,失败返回-1和错误码
  1. 读取文件内容 read
   #include <unistd.h>
   ssize_t read(int fd, void *buf, size_t count);
   // fd:	文件描述符
   // buf:	读到的数据缓冲区
   // count:需要读取的字节数
   // 返回值: 成功返回实际度到的字节数,失败返回-1 和 错误码
  1. 写数据到文件中 write
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
   // fd:	文件描述符
   // buf:	写到的数据缓冲区
   // count:需要写入的字节数
   // 返回值: 成功返回实际度写入字节数,失败返回-1 和 错误码
  1. 设置文件偏移量 Iseek
   #include <sys/types.h>
   #include <unistd.h>

   off_t lseek(int fd, off_t offset, int whence);  
   // fd:	文件描述符
   // offset:偏移量
   // whence:基准点(SEEK_SET开头、SEEK_CUR当前、SEEK_END结尾)
   // 返回值:成功返回文件新的文件偏移量,失败返回-1

4. 设置共享文件夹

  1. 打开VMware虚拟机打开设置
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在ubantu虚拟机中检查是否创建成功。

3.1. 读文件

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main()
{
    // 1.打开文件
    int rd_fd = open("1.txt", O_RDONLY); 
    if (rd_fd == -1) // 判断是否打开成功
    {
        perror("open 1.txt failed");
        exit(-1); // 退出程序
    }
    // 2.读取文件
    char buf[1024]; //定义缓冲区
    bzero(buf, sizeof(buf)); //清空缓冲区
    int ret = read(rd_fd, buf, sizeof(buf));
    if (ret == -1)
    {
        perror("read 1.txt failed");
        exit(-2); // 退出程序
    }
    
    // 3.查看数据
    printf("read 1.txt %d byte is: %s\n", ret, buf);

    // 4.关闭文件
    close(rd_fd);
}

在这里插入图片描述

3.2. 写文件

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main()
{
    // 1.打开文件
    int wd_fd = open("2.txt", O_WRONLY | O_CREAT, 0644); 
    if (wd_fd == -1) // 判断是否打开成功
    {
        perror("open 1.txt failaed");
        exit(-1); // 退出程序
    }
    // 2.写数据
    int ret = write(wd_fd, "zhangsan hello", sizeof("zhangsan hello"));
    if (ret == -1)
    {
        perror("write 2.txt failed");
        exit(-2); // 退出程序
    }

    // 4.关闭文件
    close(wd_fd);
}

在这里插入图片描述

3.2. 设置文件偏移量

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main()
{
    // 1.打开文件
    int wd_fd = open("2.txt", O_WRONLY | O_CREAT, 0644); 
    if (wd_fd == -1) // 判断是否打开成功
    {
        perror("open 1.txt failaed");
        exit(-1); // 退出程序
    }
    // 2.写数据
    int l_ret = lseek(wd_fd, 0, SEEK_END); // 将偏移量移动到文件末尾
    int ret = write(wd_fd, "zhangsan hello", sizeof("zhangsan hello"));
    if (ret == -1)
    {
        perror("write 2.txt failed");
        exit(-2); // 退出程序
    }
    printf("lseek %d byte; write %d byte\n", l_ret, ret);
    // 4.关闭文件
    close(wd_fd);
}

在这里插入图片描述

4. LCD显示屏显示

4.1. LCD 显示颜色

lcd屏可显示显示像素点得组成ARGB四个元素组成,一个元素得有256个不同的值故需要8位二进制来描述,因此4个元素要需要32位(4字节)二进制来表示。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main()
{
    // 打开lcd设备
    int lcd_fd = open("/dev/fb0", O_RDWR);
    if (lcd_fd == -1)
    {
        perror("open LCD failed");
        exit(-1);
    }
    // 定义色彩
    int color = 0xFF0000; // 假设是红色
    // 将色彩写入lcd设备文件
    for (int i = 0; i < 800 * 480; i++)
    {
        write(lcd_fd, &color, sizeof(color)); //写一个像素点
    }  
    // 关闭lcd设备
    close(lcd_fd);
    return 0;
}

在这里插入图片描述

4.2. 将文件下载到开发板

4.2.1. 在CRT链接开发板中输入命令"rx 需要下载的文件名"

在这里插入图片描述
通过Xmode发送
在这里插入图片描述
发送完成
在这里插入图片描述
下载文件执行成功后修改文件权限,修改文件权限后方可执行
在这里插入图片描述
屏幕显示红色:
请添加图片描述

4.3. lcd 使用 write 函数直接写入像素点出现噪点等待一点后又能完全显示

问题分析:由于系统调用需要花费时间
解决办法:给 lcd 申请一片显存
使用 mmap 函数可以采用内存映射的方式来为 lcd 映射一块特殊的内存作为 lcd 的显存

#include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); // 映射函数 
// 主要参数:
// addr:	映射内存的起始地址(NULL表述由内核自己找到符合要求的地址)
// length:	映射内存的大小
// prot: 	映射内存的权限(与 open 的权限一致)
//       		PROT_EXEC  Pages may be executed.
//       		PROT_READ  Pages may be read.
//       		PROT_WRITE Pages may be written.
//      		PROT_NONE  Pages may not be accessed.
// flags: 	映射内存的更新方式
//				MAP_SHARED: 共享内存的方式更新(更新已有的内存)
//				MAP_PRIVATE: 创建新的内存并更新
// fd: 		需要映射的文件描述符
// offset: 	映射内存的偏移量
// 返回值:
//	成功返回映射内存基地址
//	失败返回 MAP_FAILED 和 错误码

int munmap(void *addr, size_t length); // 解除映射函数

显示绿色:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>

int main()
{
    int i;
    // 打开lcd设备
    int lcd_fd = open("/dev/fb0", O_RDWR);
    if (lcd_fd == -1)
    {
        perror("open LCD failed");
        exit(-1);
    }

    // 开启映射
    int* lcd_map = mmap(NULL, 800*480*4, PROT_READ|PROT_WRITE, MAP_SHARED, lcd_fd, 0);
    
    // 定义色彩
    int color = 0x00FF00; // 假设是绿色
    // 将色彩写入lcd设备文件
    for (i = 0; i < 800 * 480; i++)
    {
        *(lcd_map + i) = color; // 显示一个像素点
    }  
    // 关闭lcd设备
    close(lcd_fd);
    // 关闭映射
    munmap(lcd_map, 800 * 480);
    return 0;
}

请添加图片描述

4.4. 开发板lcd 显示 bmp 图片

  1. 常见的图片格式:jpeg / jpg, png, bmp
  2. jpeg / jpg: 采用专用的图像压缩算法进行压缩
    bmp: 它采用位映射存储格式,除了图像深度可选外,不采用其他任何压缩,因此,BMP 文件所占用的空间很大(推荐24位的位图)。
    在这里插入图片描述
    分析:由于 lcd 显示的像素点是 32位 的彩色,而bmp图片的像素点是 24位,所以需要要完成 24位 到 32位 的转换
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>


int main()
{
    int i;
    // 打开lcd设备
    int lcd_fd = open("/dev/fb0", O_RDWR);
    if (lcd_fd == -1)
    {
        perror("open LCD failed");
        exit(-1);
    }

    // 开启映射
    int* lcd_map = mmap(NULL, 800*480*4, PROT_READ|PROT_WRITE, MAP_SHARED, lcd_fd, 0);
    if (lcd_map == MAP_FAILED)
    {
        perror("mmap failed");
        close(lcd_fd);
        exit(-1);
    }

    // 打开bmp图片
    int bmp_fd = open("bgt.bmp", O_RDONLY);
    if (bmp_fd == -1)
    {
        perror("open BMP failed");
        munmap(lcd_map, 800*480*4);
        close(lcd_fd);
        exit(-1);
    }

    // 跳过BMP文件头(假设54字节标准头)
    lseek(bmp_fd, 54, SEEK_SET);

    // 读取图片数据
    int bmp_buf[800*480]; // 图片的大致大小
    char tmp_buf[800*480*3]; 
    bzero(bmp_buf, sizeof(bmp_buf)); // 清除缓冲区
    bzero(tmp_buf, sizeof(tmp_buf));
    read(bmp_fd, tmp_buf, sizeof(tmp_buf)); // 读取数据

    // 关闭bmp图片文件
    close(bmp_fd);

    // 将 24位 的像素点转换为 32位
    for (i = 0; i < 800*480; ++i)
    {
        bmp_buf[i] = tmp_buf[i*3]|tmp_buf[i*3+1]<<8|tmp_buf[i*3+2]<<16|0x00<<24;
    }
    
    // 显示
    for (i = 0; i < 800*480; i++)
    {
        *(lcd_map + i) = bmp_buf[i]; // 显示一个像素点
    } 


    // 关闭lcd设备
    close(lcd_fd);
    // 关闭映射
    munmap(lcd_map, 800*480*4);
    return 0;
}

请添加图片描述
但是图片是反转过来的
在这里插入图片描述

// 将 24位 的像素点转换为 32位,并将图片翻转过来
for (i = 0; i < 480; ++i) {
    for (j = 0; j < 800; ++j) {
        bmp_buf[i*800+j] = tmp_buf[((479-i)*800 + j)*3] | 
                        tmp_buf[((479-i)*800 + j)*3+1]<<8 | 
                        tmp_buf[((479-i)*800 + j)*3+2]<<16 | 
                        0x00<<24;
    }
}

现在就正了:
请添加图片描述

5. 触摸屏

5.1. 触摸屏 之 Linux 输入子系统模型

可以通过查看 input.h 的代码,了解输入子系统的框架

cd /usr/include/linux/

5.1.1 input.h

/*
 * The event structure itself
 */

struct input_event {
	struct timeval time; // 事件发生的时间
	__u16 type;			 // 事件发生类型
	__u16 code;			 // 事件的代码
	__s32 value;		 // 事件的值
};

在开发板上有这样一些事件:
在这里插入图片描述

/*
 * Event types
 */

#define EV_SYN			0x00
#define EV_KEY			0x01
#define EV_REL			0x02
#define EV_ABS			0x03
#define EV_MSC			0x04
#define EV_SW			0x05
#define EV_LED			0x11
#define EV_SND			0x12
#define EV_REP			0x14
#define EV_FF			0x15
#define EV_PWR			0x16
#define EV_FF_STATUS		0x17
#define EV_MAX			0x1f
#define EV_CNT			(EV_MAX+1)
/*
 * Absolute axes
 */

#define ABS_X			0x00
#define ABS_Y			0x01
#define ABS_Z			0x02
#define ABS_RX			0x03
#define ABS_RY			0x04
#define ABS_RZ			0x05
#define ABS_THROTTLE		0x06
#define ABS_RUDDER		0x07
#define ABS_WHEEL		0x08
#define ABS_GAS			0x09
#define ABS_BRAKE		0x0a
// ...

5.1.2 事件数据分析

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include<linux/input.h>

int main(void)
{
    // 打开触摸屏
    int ts_fd = open("/dev/input/event0", O_RDONLY);
    if(ts_fd == -1)
    {
        perror("open touchscreen failed");
        exit(-1);
    }

    // 定义输入事件缓冲区
    struct input_event myevent;

    while(1)
    {
        // 读入数据并输出
        read(ts_fd, &myevent, sizeof(struct input_event)); //阻塞等待输入数据
        printf("type:%d code:%d value:%d\n", myevent.type, myevent.code, myevent.value);
    }

    // 关闭文件
    close(ts_fd);

    return 0;
}

在这里插入图片描述

type:0 code:0 value:0 // 同步事件
type:3/*EV_ABS触摸屏事件*/ code:0/*ABS_X x轴*/ value:520
type:3/*EV_ABS触摸屏事件*/ code:1/*ABS_Y y轴*/ value:457
type:0 code:0 value:0 // 同步事件
type:1/*EV_KEY键盘事件*/ code:330/*BTN_TOUCH键盘事件*/ value:0//松开
type:0 code:0 value:0 // 同步事件

获取触摸屏 的 x,y值:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include<linux/input.h>

int main(void)
{
    // 打开触摸屏
    int ts_fd = open("/dev/input/event0", O_RDONLY);
    if(ts_fd == -1)
    {
        perror("open touchscreen failed");
        exit(-1);
    }

    // 定义输入事件缓冲区
    struct input_event myevent;
    int x, y, count = 0;
    while(1)
    {
        // 读入数据并输出
        read(ts_fd, &myevent, sizeof(struct input_event)); //阻塞等待输入数据
        
        if(myevent.type == EV_ABS) // 触摸屏事件
        {
            if(myevent.code == ABS_X) // X轴
            {
                x = myevent.value;
                count++;
            }
            if(myevent.code == ABS_Y)
            {
                y=myevent.value;
                count++;
            }
            if (count == 2) 
            {
                count = 0;
                printf("(%d, %d)\n", x, y);
            }
        }
        
        //printf("type:%d code:%d value:%d\n", myevent.type, myevent.code, myevent.value);
    }

    // 关闭文件
    close(ts_fd);

    return 0;
}

在这里插入图片描述

总结:

本文全面介绍了嵌入式Linux开发中的一系列关键技术,包括交叉编译工具的使用、项目开发流程、开发板的连接方法、系统文件IO的基本操作、LCD显示屏的显示技术以及触摸屏的输入子系统模型和事件分析。通过详细的代码示例和步骤说明,读者可以对这些技术有一个清晰的认识,并能够在实际开发中灵活应用。

交叉编译工具是开发过程中不可或缺的一部分,它允许开发者在不同平台之间进行代码的编译和移植。而项目开发流程的介绍,为读者提供了一个清晰的开发路线图,确保开发工作的有序进行。开发板的连接方法和系统文件IO操作是进行硬件交互的基础,LCD显示屏的显示技术和触摸屏事件分析则进一步扩展了开发者在用户界面交互方面的技能。

通过本文的学习,开发者不仅能够掌握嵌入式Linux开发的基本技能,还能够对LCD显示和触摸屏处理等高级主题有更深入的理解。希望本文能够成为嵌入式Linux开发者的一份宝贵参考资料,帮助他们在项目开发中更加得心应手。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1839875.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

shadertoy-安装和使用

一、安装vscode 安装vscode流程 二、安装插件 1.安装glsl编辑插件 2.安装shader toy插件 三、创建glsl文件 test.glsl文件 float Grid(float size, vec2 fragCoord) {vec2 r fragCoord / size;vec2 grid abs(fract(r - 0.5) - 0.5) / fwidth(r);float line min(grid…

免费域名第二弹:手把手教你获取个性化免费域名并托管至Cloudflare

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 免费申请域名的方法 📒📝 注册账号📝 创建免费域名📝 将域名添加到 Cloudflare⚓️ 相关链接 ⚓️📖 介绍 📖 在如今的数字时代,拥有一个个性化的域名已经成为越来越多人的需求。无论是建立个人博客、项目展示,还…

JWT整合Gateway实现鉴权(RSA与公私密钥工具类)

一.业务流程 1.使用RSA生成公钥和私钥。私钥保存在授权中心&#xff0c;公钥保存在网关(gateway)和各个信任微服务中。 2.用户请求登录。 3.授权中心进行校验&#xff0c;通过后使用私钥对JWT进行签名加密。并将JWT返回给用户 4.用户携带JWT访问 5.gateway直接通过公钥解密JWT进…

前端页面实现【矩阵表格与列表】

实现页面&#xff1a; 1.动态表绘制&#xff08;可用于矩阵构建&#xff09; <template><div><h4><b>基于层次分析法的权重计算</b></h4><table table-layout"fixed"><thead><tr><th v-for"(_, colI…

王思聪隐形女儿曝光

王思聪"隐形"女儿曝光&#xff01;黄一鸣独自面对怀孕风波&#xff0c;坚持生下爱情结晶近日&#xff0c;娱乐圈掀起了一场惊天波澜&#xff01;前王思聪绯闻女友黄一鸣在接受专访时&#xff0c;大胆揭露了她与王思聪之间的爱恨纠葛&#xff0c;并首度公开承认&#…

VBA技术资料MF161:按需要显示特定工作表

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…

重生之 SpringBoot3 入门保姆级学习(24、场景整合 kafka 消息发送服务)

重生之 SpringBoot3 入门保姆级学习&#xff08;24、场景整合 kafka 消息发送服务&#xff09; 6.4 消息发送服务 6.4 消息发送服务 访问 kafka-ui &#xff08;注意这里需要换成你自己的服务器或者虚拟机的 IP 地址&#xff0c;虚拟机可以用局域网 192.168.xxx.xxx 的地址&…

05-对混合app应用中的元素进行定位

本文介绍对于混合app应用中的元素如何进行定位。 一、app的类型 1&#xff09;Native App&#xff08;原生应用&#xff09; 原生应用是指利用Android、IOS平台官方的开发语言、开发类库、工具等进行开发的app应用&#xff0c;在应用性能和交互体验上应该是最好的。 通俗点来…

富唯智能复合机器人

复合机器人&产品概述 富唯智能复合机器人集协作机器人、移动机器人和视觉引导技术于一体&#xff0c;搭载ICD系列核心控制器&#xff0c;一体化控制整个复合机器人系统&#xff0c;并且可以对接产线系统&#xff0c;搭配我司自研的2D/3D视觉平台&#xff0c;能够轻松实现工…

【Java】已解决Java中的java.util.NoSuchElementException异常

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决Java中的java.util.NoSuchElementException异常 一、分析问题背景 java.util.NoSuchElementException是Java中常见的运行时异常&#xff0c;它通常发生在使用迭代器&#xf…

文献阅读:SpaceX:空间转录组学的基因共表达网络估计

文献介绍 「文献题目」 SpaceX: gene co-expression network estimation for spatial transcriptomics 「研究团队」 Veerabhadran Baladandayuthapani&#xff08;美国密歇根大学&#xff09;、Xiang Zhou&#xff08;美国密歇根大学&#xff09; 「发表时间」 2022-09-30 「…

鸿蒙HarmonyOS实战:渲染控制、路由案例

条件渲染 简单来说&#xff0c;就是动态控制组件的显示与隐藏&#xff0c;类似于vue中的v-if 但是这里写法就是用if、else、else if看起来更像是原生的感觉 效果 循环渲染 我们实际开发中&#xff0c;数据一般是后端返回来的对象格式&#xff0c;对此我们需要进行遍历&#…

【决战欧洲杯巅峰】欧洲杯含金量比世界杯高吗?有走地数据分析软件吗?

关于欧洲杯和世界杯的含金量对比&#xff0c;这是一个相当主观的问题&#xff0c;因为两者的价值和重要性很大程度上取决于个人的喜好和观点。但我可以从一些关键方面来为你提供比较的视角。 首先&#xff0c;从参赛队伍和竞技水平来看&#xff0c;世界杯无疑是全球范围内最具…

探索 JQuery EasyUI:构建简单易用的前端页面

介绍 当我们站在网页开发的浩瀚世界中&#xff0c;眼花缭乱的选择让我们难以抉择。而就在这纷繁复杂的技术海洋中&#xff0c;JQuery EasyUI 如一位指路明灯&#xff0c;为我们提供了一条清晰的航线。 1.1 什么是 JQuery EasyUI&#xff1f; JQuery EasyUI&#xff0c;简单来…

尚硅谷爬虫学习第一天(2) 爬虫案例

import urllib.request# 下载网页 url_page http://www.baidu.com # url 代表下载的路径&#xff0c;filename 代表文件的名字 # urllib.request.urlretrieve(url_page,baidu.html) # 在python中 可以写变量的名字&#xff0c;也可以直接写值,这不就是java吗# 下载图片 # url_…

关于app爬虫的环境准备

摘要 有些数据需要在手机应用中才能查看&#xff0c;没有网页版&#xff0c;所以学习移动端的爬虫是有必要的。 手机系统分为安卓和苹果两大系统&#xff0c;本次讲解主要以安卓手机为例 有安卓手机的可以使用手机&#xff0c;没有的可以使用模拟器&#xff0c;本次以夜神模…

为什么带上符号位计算,仍然可以算出正负数对应的补码

文章目录 &#x1f680;前言&#x1f680; 为什么要引入原反补码✈️ 利用加法表示减法✈️ 关于数字在计算机中的存储&#x1f680; 数学解释 &#x1f680; 为什么带上符号位计算&#xff0c;仍然可以算出正负数对应的补码 &#x1f680;前言 为应付期末&#xff0c;速成数电…

N7745A Keysight 是德 多端口光功率计 简述

N7745A光功率计专为表征多端口光器件而设计&#xff0c;适用于多路复用器、PON分路器、波长选择开关&#xff08;WSS&#xff09;和ROADM等多端口器件的测试。它可以节省通道空间&#xff0c;通过LAN或USB连接进行并行编程&#xff0c;集成多种设备到单一设置&#xff0c;提高了…

[Qt] Qt Creator中配置 Vs-Code 编码风格

新建vscode-onedark.xml文档 &#xff0c;将如下内容复制进去&#xff0c;并配置到Creator中&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <style-scheme version"1.0" name"One Dark"><style name"Tex…

打造一个属于你的桌面天气 超级有个性的天气桌面

打造一个属于你的桌面天气 超级有个性的天气桌面。大家好&#xff0c;今天我们带来一个非常有趣的桌面天气工具&#xff0c;喜欢桌面diy的你&#xff0c;快点用上它吧&#xff01; 桌面上的美化&#xff0c;是许多爱美用户的心血和热爱。每个地方的美化&#xff0c;都是自己亲…