Docker介绍

本文是Docker入门介绍,适合小白。介绍了Docker诞生背景,可解决环境配置问题。阐述其发展历史、基本组成、常用命令、镜像加载原理、容器数据卷、DockerFile编写及构建发布,还讲解了Docker网络,包括多种网络模式及不同网络下容器的访问方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

写在前面:该篇文章主要为Docker入门介绍,非常适合小白入门。Docker进阶部分后续将会持续更新~

Docker概述

Docker的诞生

一个应用的开发需要两个环境:开发环境和运行环境,可能会遇到一种情况就是服务在开发人员处能运行,到了运维人员就不能运行了,也就是环境配置出现问题。但是配置环境一般都比较繁琐,为了解决这个问题由此诞生了Docker。Docker 是一个开源的应用容器引擎,可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器,开发者在本地编译测试通过的容器可以直接在生产环境中部署。也就是说Docker可以将应用和他所需要的环境一起打包,只需要一次配置好环境,换到别的机器上就可以一键部署好,大大简化了操作。
在这里插入图片描述
Docker的思想来自于集装箱,就像船只、火车或卡车运输集装箱而不关心其内部的货物一样。

Docker的发展历史

2008年,Solomon Hykes 和他的朋友 Kamel Founadi、Sebastien Pahl 共同创立了一家名为 DotCloud 的公司;

2010年,dotCloud获得了创业孵化器Y Combinator的支持,并开始吸引到一些真正的投资,在接下来的3年中,dotCloud内部打算孵化了一款名为Docker的产品;

2013年,28岁Docker之父Solomon Hykes 决定将Docker项目开源,并发布Docker 0.1 版本;

2017年,docker技术开始成为主流,像Google、Microsoft、Amazon、VMware这样的巨头,都对它青睐有加,表示将全力支持。

Docker和VMware

VMware属于虚拟化技术, 而Docker这样的容器技术,也是一种虚拟化技术,但是他是属于轻量级的虚拟化。

  1. 传统虚机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用。
  2. docker容器内的应用进程直接运行于宿主机的内核,容器内没有自己的内核,而且也没有进行硬件虚拟,直接使用的是实际物理机的硬件资源。
    在这里插入图片描述在这里插入图片描述在这里插入图片描述

Docker的安装与配置

访问 Docker 的官方网站: Docker Download

验证是否安装成功:docker --version

配置镜像:

中科大镜像:https://docker.mirrors.ustc.edu.cn/
网易镜像:https://hub-mirror.c.163.com/

在这里插入图片描述

Docker的基本组成

Docker主要由镜像、容器、仓库这三部分构成。

镜像(image)
image 是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数。

容器(container)
image是静态的定义,container是image运行时的定义。container和image的关系就好比是面向对象程序设计中的类和对象一样,镜像就好比是类,容器就好比是对象。

仓库(repository)
repository是集中存放镜像文件的场所, repository分为公开仓库(Public)和私有仓库(Private)两种形式,最大的公开仓库是 Docker Hub.

Docker常用命令

镜像命令:
docker images [OPTIONS]:列出本地主机上的镜像

-q: 只显示镜像id
–digests: 显示镜像的摘要信息

docker search image: 搜索镜像

–filter=stars=100:列出star数>=100的镜像

docker pull image: 下载镜像
docker rmi image:删除镜像

docker rmi image_id1 image_id2: 删除多个镜像
docker rmi $(docker images -qa): 删除全部镜像

容器命令:
docker run [OPTIONS] image

–name=name: 给容器指定一个名字
-d: 后台方式运行容器,并返回容器id
-i: 以交互模式运行容器,通常和 -t 一起使用
-t: 给容器重新分配一个终端,通常和 -i 一起使用
-P: 随机端口映
-p: 指定端口映射

docker ps [OPTIONS]

-a: 列出当前所有正在运行的容器 + 历史运行过的容器
-q: 只显示容器编号

docker start/restart/stop/kill/rm/ : 启动容器/重启容器/停止容器/强制停止容器/删除指定容器
docker rm -f $(docker ps -a -q): 删除所有容器
docker exec -it 容器id bashshell: 进入正在运行的容器
docker cp 容器id:容器内路径 目的主机路径: 从容器内拷贝文件到主机上
docker commit -m=“提交的描述信息” -a=“作者” 容器id 要创建的目标镜像名:[标签名]: 从容器创建一个新的镜像
在这里插入图片描述

Docker镜像加载原理

联合文件系统(UnionFS)

联合文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统, 它支持对文件系统的修改作为一次提交来一层层的叠加。UnionFS是 Docker 镜像的基础,镜像可以通过分层来进行继承,基于基础镜像可以制作各种具体的应用镜像。

bootfs(boot file system)

bootfs主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层用的宿主机的bootfs。

rootfs (root file system)

在bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等。

分层理解

在这里插入图片描述
下载一个nginx镜像

(base) didi@DIDI-C02G137NQ05P ~ % docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
e886f0f47ef5: Pull complete
9a9138853e32: Pull complete
598a42ec6587: Pull complete
82e490cc2043: Pull complete
948128637a91: Pull complete
e4cad15ac3f6: Pull complete
096332b242c2: Pull complete
Digest: sha256:32da30332506740a2f7c34d5dc70467b7f14ec67d912703568daff790ab3f755
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest

下载另外一个nginx版本镜像

(base) didi@DIDI-C02G137NQ05P ~ % docker pull nginxinc/nginx-unprivileged
Using default tag: latest
latest: Pulling from nginxinc/nginx-unprivileged
e886f0f47ef5: Already exists
2aa7a0145e75: Pull complete
123bf892d71d: Pull complete
67b1ba97f9d1: Pull complete
a1e29ed27a2b: Pull complete
2a2ba3137419: Pull complete
180f749837c7: Pull complete
89dc6329e0b4: Pull complete
Digest: sha256:ad9a0ffaf09f6631f0f6a11f20a981e72a4b2a0c79a9b5429af1ee5709b7d69e
Status: Downloaded newer image for nginxinc/nginx-unprivileged:latest
docker.io/nginxinc/nginx-unprivileged:latest

Docker镜像要采用这种分层的结构,最大的好处就是资源共享了。比如有多个镜像都从相同的Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。

容器数据卷

什么是容器数据卷

当容器删除后,容器里面的数据自然也就没有了,这样是非常不符合常理的! 为了能保存数据,在Docker中一般使用使用卷技术,让数据挂载到我们宿主机,也就是将 Docker 容器内的数据保存并同步到宿主机的硬盘中,Docker不会在容器删除时删除其挂载的数据卷,这样数据就不会因为容器删除而丢失。

#docker volume ls  浏览容器数据卷
DRIVER    VOLUME NAME
local     2a8db050db700573fbc6619c8ee61847e34bf22366ad0c8b8703e2333d8caf95
local     9f32611e21cea7381b2fd1ff725e9d6621013108e68ef0fb54b0fee6369f428f
local     afb82b29f99c6263f53e9b5abc5ec7ccc388fb0c1e1ef12ae49560c97db7c059
local     c61c160b6a6df8550e0e632cbb82254d38972eb409b0cea791a3d1126a43e8ff
local     nginx_conf

指定路径挂载

docker run -v 宿主机目录路径:容器内路径 镜像名

# docker run -p 3307:3306 --name mysql02 -e MYSQL_ROOT_PASSWORD=123456 -d -v ./docker_mysql/mysql02/conf:/etc/mysql/conf.d  -v ./docker_mysql/mysql02/data:/var/lib/mysql mysql
# docker inspect 55e9744ec1f6
"Mounts": [
            {
                "Type": "bind",
                "Source": "/Users/didi/docker_mysql/mysql02/conf",
                "Destination": "/etc/mysql/conf.d",
            },
            {
                "Type": "bind",
                "Source": "/Users/didi/docker_mysql/mysql02/data",
                "Destination": "/var/lib/mysql",
            }
        ]
  • 在容器中修改数据会同步到宿主机,相反宿主机修改数据也可以同步到容器
  • 容器停止退出后,宿主机修改数据依旧会同步到容器
  • 删除容器,挂载到宿主机的数据依然不会丢失

这样就实现容器内数据持久化功能

匿名挂载

docker run -v 容器内路径

# docker run -d -P --name nginx01 -v /etc/nginx nginx
# docker volume ls 查看数据卷
DRIVER    VOLUME NAME
local     c61c160b6a6df8550e0e632cbb82254d38972eb409b0cea791a3d1126a43e8ff
 
# docker volume inspect nginx_conf c61c160b6a6df8550e0e632cbb82254d38972eb409b0cea791a3d1126a43e8ff 查看匿名数据卷信息
[
    {
        "CreatedAt": "2023-10-06T10:57:17Z",
        "Driver": "local",
        "Mountpoint": "/var/lib/docker/volumes/c61c160b6a6df8550e0e632cbb82254d38972eb409b0cea791a3d1126a43e8ff/_data",
        "Name": "c61c160b6a6df8550e0e632cbb82254d38972eb409b0cea791a3d1126a43e8ff",
    }
]

具名挂载

docker run -v 卷名:容器内路径

# docker run -d -P --name nginx02 -v nginx_conf:/etc/nginx nginx
# docker volume ls 查看数据卷
DRIVER    VOLUME NAME
local     nginx_conf
 
# docker volume inspect nginx_conf  查看具名数据卷信息
[
    {
        "CreatedAt": "2023-10-06T10:35:24Z",
        "Driver": "local",
        "Mountpoint": "/var/lib/docker/volumes/nginx_conf/_data",
        "Name": "nginx_conf",
    }
]

指定容器内数据的读写权限

docker run -v 宿主机路径:容器内路径:ro 【容器内只读】
docker run -v 宿主机路径:容器内路径:rw 【容器内可读可写】

数据卷容器

其他容器通过挂载父容器实现数据共享,挂载父容器数据卷的容器,称为数据卷容器。

docker run -d -P --name centos02 --volumes-from centos01 centos

DockerFile

dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。构建步骤:

  1. 编写DockerFile文件
  2. docker build 构建镜像
  3. docker run 成为容器
    在这里插入图片描述

DockerFile 编写

FROM # 基础镜像,当前新镜像是基于哪个镜像的
MAINTAINER # 镜像维护者的姓名,新版本建议用LABEL,以键值对方式添加
RUN # 容器构建时需要运行的命令
EXPOSE # 当前容器对外暴露出的端口
WORKDIR # 指定在创建容器后,终端默认登录时的工作目录
ENV # 用来在构建镜像过程中设置环境变量
ADD # 将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包
COPY # 拷贝文件和目录到镜像中,一般用于将在宿主机上事先准备的配置文件复制到镜像中
VOLUME # 容器数据卷,用于数据保存和持久化工作
CMD # 指定一个容器启动时要运行的命令,dockerFile中可以有多个CMD指令,但只有最后一个生效!
ENTRYPOINT # 指定一个容器启动时要运行的命令!
ONBUILD # 当构建一个被继承的DockerFile时运行命令,父镜像在被子镜像继承后,父镜像的ONBUILD被触发

CMD 和 ENTRYPOINT

# Dockerfile01
FROM centos:7
CMD ["ls","-a"]
 
# Dockerfile02
FROM centos:7
ENTRYPOINT ["ls","-a"]

CMD 和 ENTRYPOINT 两个命令都是指定一个容器启动时要运行的命令:

  • CMD:Dockerfile 中可以有多个CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换[docker run test01 ls -l ]
  • ENTRYPOINT:docker run 之后的参数会被当做参数传递给 ENTRYPOINT,之后形成新的命令组合[ docker run test02 -l ]

DockerFile构建镜像&发布镜像

docker build -f DockerFile地址 -t 新镜像名字:TAG . ps:注意后面这个.

  1. 注册账户 dockerhub 需要有一个账号
  2. 登陆仓库 docker login -u username
  3. 推送镜像 docker push 镜像名

查看镜像构建过程

docker history 镜像名

# docker history mycentos01
IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
63bb12bb16ac   19 months ago   ENTRYPOINT ["ls" "-a"]                          0B        buildkit.dockerfile.v0
<missing>      19 months ago   /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B       
<missing>      19 months ago   /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B       
<missing>      19 months ago   /bin/sh -c #(nop) ADD file:5b1e63a3cb041177b…   301MB

Docker网络

安装docker后,他会自动通过三种驱动创建三个不同类型的网络,分别为bridge、host、none,可以通过docker network ls 查看这些网络:

# docker network ls:查看docker所有网络
NETWORK ID     NAME      DRIVER    SCOPE
52dbeabb95c7   bridge    bridge    local
86da01f95212   host      host      local
3a0880d024de   none      null      local

veth-pair(Virtual Ethernet Pair)

在了解docker默认创建的这三种网络之前,先了解一下veth-pair(Virtual Ethernet Pair) 技术,veth-pair 是一种 Linux 内核技术,可用于将两个网络接口连接在一起,这两个网络接口是成对出现的,一个在一个命名空间中,另一个在另一个命名空间中,它提供了一种方式实现了不同网络之间的通信。它常常被用于容器的实现,比如 Docker 中的容器网络,以提供网络隔离和互联。例如,当创建一个 Docker 容器时,内部将会创建一个独立的网络命名空间。此时,将会创建两个 veth-pair 接口,一个接口将附加到容器内的网络命名空间中,另一个接口将附加到主机的网络命名空间中。这些 veth-pair 接口之间的通信将被用来进行容器中的应用程序访问主机网络的操作,以及主机网络中的应用程序访问容器中的应用程序的操作。

bridge网络模式

配置:docker run -d --net=bridge 「不支持通过容器名互相访问」

  • bridge网络就是docker默认的网络,即使在启动容器的时候如果不指定bridge模式,那么我们创建的容器所分配的ip都会默认在该网络下
# 查看网络信息:docker network inspect bridge
{
  "Name": "bridge",
  "Id": "52dbeabb95c7486fb9be40fdcb5d99f75e08f5605dc4ca740d8bdaabd4151e8a",
  "Created": "2023-10-05T08:09:47.640833083Z",
  "Scope": "local",
  "Driver": "bridge",
  "EnableIPv6": false,
  "IPAM": {
    "Config": [
      {
        "Subnet": "172.17.0.0/16",
        "Gateway": "172.17.0.1"
      }
    ]
  }
}

host网络模式

配置:docker run -d --net=host

  • 如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,该容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口
# 查看网络信息:docker network inspect host
{
  "Name": "host",
  "Id": "86da01f95212c7edd83a23c0b48c471f5a2af090e2d6168906c873d3df3b05d6",
  "Created": "2022-09-01T20:55:41.101556166Z",
  "Scope": "local",
  "Driver": "host",
  "EnableIPv6": false,
  "IPAM": {
    "Config": []
  }
}

none网络模式

配置:docker run -d --net=none

  • 如果启动容器的时候使用none模式,Docker容器拥有自己的NetworkNamespace,但是并不为Docker容器进行任何网络配置。这个Docker容器只有回环网络,没有其他网卡信息。
# 查看网络信息:docker network inspect none
{
  "Name": "none",
  "Id": "3a0880d024de753befddc9f77c6207e979fd4823ea14472891093c814764a2e2",
  "Created": "2022-09-01T20:55:41.093611833Z",
  "Scope": "local",
  "Driver": "null",
  "EnableIPv6": false,
  "IPAM": {
      "Config": []
   }
}

自定义网络模式

配置:docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet 「支持通过容器名互相访问」

# 查看网络信息:docker network inspect mynet
{
  "Name": "mynet",
  "Id": "26769acdff3fcceda2dfb0e69b6b2d3b086d6b038be683d6303e54ee21f80126",
  "Created": "2023-10-08T09:13:45.643984422Z",
  "Scope": "local",
  "Driver": "bridge",
  "EnableIPv6": false,
  "IPAM": {
    "Config": [
      {
        "Subnet": "192.168.0.0/16",
        "Gateway": "192.168.0.1"
      }
    ]
  }
}

不在同一个网络下的容器如何访问?

假设:

  • 在 bridge 网络下有一个:centos01
# docker network inspect bridge
"Containers": {
    "52471ac2f2cbf1e9a9b4d99095b5e690329c6d184462aa6cf8ae114dfcdd5f88": {
      "Name": "centos02",
      "EndpointID": "b2e9318706334092215bbda884830938860cd7a0fb28cb822f480f1717d1ef7d",
      "MacAddress": "02:42:ac:11:00:03",
      "IPv4Address": "172.17.0.3/16",
      "IPv6Address": ""
    }
  }
  • 在 mynet 网络下有一个:centos02
# docker network inspect mynet
"Containers": {
    "52471ac2f2cbf1e9a9b4d99095b5e690329c6d184462aa6cf8ae114dfcdd5f88": {
      "Name": "centos02",
      "EndpointID": "74308f38d725a824d3707efa733aba95c440cee72fb6d462398a2fbc159fcefa",
      "MacAddress": "02:42:c0:a8:00:02",
      "IPv4Address": "192.168.0.2/16",
      "IPv6Address": ""
    }
  }

如果centos01需要访问centos02,就可以使用:docker network connect bridge centos02

"Containers": {
            "52471ac2f2cbf1e9a9b4d99095b5e690329c6d184462aa6cf8ae114dfcdd5f88": {
                "Name": "centos02",
                "EndpointID": "b2e9318706334092215bbda884830938860cd7a0fb28cb822f480f1717d1ef7d",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            },
            "e0e9175adcb0d40013a15d17a52b8526a61e0aaee428618ff06578d946341665": {
                "Name": "centos01",
                "EndpointID": "6d045dcc5fdb55eb6768a985a7f6aa1edd1881451290c2dd71124e622a421415",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        }
#include "mt6701.h" #include "spi.h" int rotationCount = 0; // 旋转过的圈数 int rotationCount_Last; // 上一次循环时转过的圈数 /******************************/ //函数名:MT6701_GetRawData //参 数:uint16_t* rawData //返回值:0代表,没有错误。1,2为error //作 用:使用SPI获取mt6701的原始数据 //作 者: //时 间: /******************************/ int MT6701_GetRawData(uint16_t* rawData){ uint16_t txData = 0xFFFF; uint16_t timeout = 200; while(HAL_SPI_GetState(&hspi3) != HAL_SPI_STATE_READY){ if(timeout-- ==0){ return 1;//超时直接返回,避免执行后面代码 } } MT6701_CS_Enable(); HAL_StatusTypeDef spiStatus = HAL_SPI_TransmitReceive(&hspi3,(uint8_t *)&txData,(uint8_t *)rawData,1, HAL_MAX_DELAY); if(spiStatus != HAL_OK){ MT6701_CS_Disable(); return 2;//在SPI传输错误的时候,避免执行后面代码 } MT6701_CS_Disable(); *rawData >>= 2;//右移动两位,取出高位置14位角度原始数据 return 0; } /******************************/ //函数名:MT6701_GetRawAngle //参 数: //返回值: //作 用:对RawData进行处理,得到无圈数累加的原始角度 //作 者: //时 间: /******************************/ float MT6701_GetRawAngle(void){ uint16_t rawData; int a = 5; a = MT6701_GetRawData(&rawData); // printf("%d\r\n",a); return ((float)rawData / 16384.0f) * 2 * pi; } /******************************/ //函数名:MT6701_GetSumAngle //参 数: //返回值: //作 用:对RawData进行处理,得到无圈数累加的原始角度 //作 者: //时 间: /******************************/ float MT6701_GetSumAngle(){ float angle = 0.0f; //当前轴角度 static float anglelast = 0.0f; //上次轴角度 angle = MT6701_GetRawAngle(); float deltaAngle = angle - anglelast; if(fabsf(deltaAngle) > (0.8f * 6.036982f)){ rotationCount += (deltaAngle > 0) ? -1 : 1; rotationCount_Last = rotationCount; } anglelast = angle; return rotationCount * 6.28318530718f + anglelast; // 转过的圈数 * 2pi + 未转满一圈的角度值 } 这段代码,我读出来的原始无累计角度为0到6.并不是0到360度这是因为什么
最新发布
03-25
<think>好的,用户的问题是关于MT6701磁编码器的原始角度返回值范围为什么是0到6而不是0到360度,并且想知道原始角度的计算公式。我需要先理解MT6701的数据结构和寄存器配置。 首先,根据用户提供的引用资料,MT6701的14位角度数据存储在0x03和0x04寄存器中,读取时需要先读0x03再读0x04。14位的数据最大值是16383(2^14-1),所以原始角度值应该是0到16383。但用户提到的返回值是0到6,这似乎不符合常规的度数范围。 接下来,我需要考虑原始数据的处理方式。可能开发者将原始数据进行了归一化处理,将14位的数值转换为浮点数范围。例如,16383对应360度,所以每个单位的数值对应360/16384≈0.02197度。但用户提到的范围是0-6,这可能是因为将原始值除以某个系数,比如16384/6≈2730.6667,但这样的转换不太常见。 另一种可能性是用户提到的返回值实际上是弧度值。因为360度等于2π弧度,约6.283弧度。如果函数返回的是弧度,那么范围0到6可能是近似值。这时候,原始角度数据可能需要将14位的值转换为弧度,公式为:弧度 = (原始值 / 16384) * 2π。这样最大值接近6.283,但可能代码中截断或取整导致显示0到6。 需要检查用户提到的函数MT6701_GetRawAngle的具体实现。例如,代码中是否将原始数据转换为弧度,或者进行了某种比例缩放。例如,如果代码中使用的是原始值除以2730(16384/6≈2730.6667),那么结果就会是0到6。但这样的处理方式可能不太常见,除非有特定的应用需求。 另外,查看数据手册中的说明是关键。根据引用提供的链接,MT6701的数据手册应详细说明角度数据的表示方式。可能手册中提到角度数据以某种比例因子表示,例如每单位代表0.02197度,或者以弧度或其他单位输出。 综合来看,最可能的情况是原始数据被转换为弧度,范围0到2π(约6.283),而代码中可能将其四舍五入或截断为0到6的整数,或者直接返回浮点数但用户看到的是近似值。例如,原始公式可能是:(raw_value / 16384) * 2π,结果范围0到约6.283,但代码中可能乘以了一个系数导致显示为0到6。 需要确认数据手册中的角度计算部分。例如,是否将14位数据映射到0到360度,或者直接输出弧度。如果函数返回的是弧度,那么0到6是合理的,因为2π约等于6.283,通常显示为0到6.28或截断到0到6。 另外,用户提到的“原始无累计角度”可能指的是单圈绝对值,所以14位覆盖了0到360度,但代码中可能将其转换为其他单位,比如弧度,或者通过某种比例缩放用于特定应用。 总结,可能的原因是: 1. 原始数据被转换为弧度,范围0到2π(约6.283),代码中显示为0到6。 2. 代码中的比例缩放有误,导致数值范围不正确。 3. 数据手册中提到的特定转换公式,例如将14位数据映射到0到6的单位。 需要根据数据手册和代码实现来确认。例如,引用中提到SSI接口读取的数据是14位,所以正确的转换应该是将原始值除以16384再乘以360得到度数,或者乘以2π得到弧度。如果函数返回的是乘以2π后的值,那么范围就是0到约6.283,可能被截断为0到6。</think>MT6701磁编码器的原始角度返回值范围设计为$0$到$6$而非$0$到$360$度的核心原因,与其数据格式和物理量纲转换相关。根据数据手册,MT6701的14位绝对角度值存储在两个寄存器中,其原始数据范围为$0$到$16383$(即$2^{14}-1$)。通过以下公式可推导出返回值范围: **原始角度计算公式**: $$ \text{RawAngle} = \frac{\text{RegisterValue}}{16384} \times 2\pi \approx \frac{\text{RegisterValue}}{16384} \times 6.283185307 $$ 该公式将14位二进制值映射为弧度制角度,覆盖单圈旋转范围$0$到$2\pi$(约$6.283$)。部分实现中可能因以下原因显示为$0$到$6$: 1. **浮点数精度简化**:代码可能对计算结果进行截断或四舍五入,例如保留整数部分; 2. **单位转换约定**:某些应用场景可能要求以$\pi/3$(即$60^\circ$)为基本单位,但此情况较少见[^1][^2]。 **代码实现验证**: ```c // 示例代码片段(基于SSI接口读取) uint16_t read_angle() { uint8_t high_byte = read_register(0x03); // 先读高位寄存器 uint8_t low_byte = read_register(0x04); // 再读低位寄存器 return ((high_byte << 8) | low_byte) >> 2; // 14位有效数据 } float MT6701_GetRawAngle() { uint16_t raw = read_angle(); return (raw / 16384.0f) * 6.283185307f; // 弧度制输出 } ``` 此代码中返回值的理论范围为$0$到$6.283$,若显示为$0$到$6$,可能是浮点显示精度限制或文档描述简化所致。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值