HDMI ——CEC 协议详解以及待机唤醒 实现

news2024/10/4 0:26:08

本文讲解的是基于HDMI CEC的待机唤醒方案的设计。

目录

cec基本介绍

CEC协议时序:

CEC数据帧

cec待机唤醒介绍

待机唤醒的处理流程和实现

cec基本介绍

如今常见的高清视频接口有HDMI,VGA,DP和DVI。HDMI(High-Definition Multimedia Interface)为当今主流的多媒体高速数字接口,下图为最常见的线缆引脚分布图。其中,CEC(Consumer Electronics Control)信号通过13引脚传输,作为HDMI接口的一部分。CEC总线作为控制信号被分离出来,使得在不增加数据占用宽带的情况下完成高速复杂的通信要求。

CEC 是一套完整的单总线协议,电子设备可以借助CEC信号让使用可控制HDMI接口上所连接的装置,比如单独播放,系统待机,可以实现由单一遥控器控制所有HDMI连接的装置。最多15个设备,允许HDMI设备在没有用户干扰情况下互相命令控制。

CEC 是与其他HDMI信号分开的电信号。这允许设备在睡眠模式下禁止其高速电路,但是可以被CEC唤醒。他是一个单独的共享总线,直接连接在设备上的所有HDMI端口间,可以流过所有完全断电的设备。

总线是开路集电极线,有点像IIC,被动上拉至3.3V,设备拉低进行数据传输。

与IIC相似之处:低速串行总线;采用无源上拉的集电极开路;速度受分布电容影响;接收器可以将发送的1位转换为0:发送1比特并观察是否转换为0以查看是否丢失;面向字节都附加一个应答位;特殊的启动信息

与IIC不同之处:单线并不是两根线;以固定时序发送比特;低速串行总线(417bit/s);四个地址位;定义了动态地址分配协议;标头包括发起者和收件人地址;没有特殊停止信号,每个字节附加一个消息结束标志;没有读操作,通过获取请求获取响应帧,所有数据均从数据发送;每个设备都必须能够作为主设备传输数据;地址后字节数据有详细规定说明。

CEC协议时序:

bit Timing

每个位从线拉低(下降沿)开始,保持时间表示位值,之后拉高,直至后续位开始

正常数据位长为2.40.35ms。保持低电平0.6±0.2ms为逻辑1;保持低电平1.5±0.2ms表示逻辑0。接收器在下降沿后1.05±0.2ms对线路进行采样,然后在下降沿1.9±0.15ms开始观察下一位。

接收者可以将传输的传输的1bt转换为0通过在下降沿后0.35s拉低总线并保持直到表示逻辑0的电平时间。这个通常用于确认传输。

每个帧都有起始位,通过拉低总线3.7±0.2ms,然后允许上升,总持续时间为4.5±0.2ms。在观察总线空闲之后,任何设备都可以发送起始位。(通常5位时间,但成功后立即传输7位时间,以促进总线的公平共享,以及传输失败和重传之间的3位时间。)

对于单接收消息,应答位类似于C:以1位发送,接收器将其下拉至0以确认该位字节。(根据下面给出的波形可以看出,ack位的波形为逻辑1,但是为什么逻辑分析仪解析的值为0呢?是因为接收器将其下拉至0 以确认该位字节)

对于广播消息,应答位被反转:仍然作为1位发送,但被拒绝该字节的任何接收器下拉到0位。每个CEC帧的第一个字节包含4位源和目标地址头。如果寻址目标存在,则它确认该字节。由除标题之外的任何内容组成的帧是pig,它只检查另个设备的存在。

地址15(1111B)用于广播地址(作为目的地)和未注册的设备(作为源),它们尚未选择不同的地址。一些设备不需要接收非广播的消息,因此可以永久使用地址15。需要接收寻址消息的设备需要自己的地址。设备通过pig它获取地址,如果ping未被确认,则设备声明它。如果确认ping,则设备尝试另个地址。

第二个字节是操作码,它指定要执行的操作,以及后续数据字节的数量及含义。

CEC数据帧

cec帧结构 = 起始位+引导块+数据块

Start(bit)+ Header Block + Data Block 1(opcode block) + Data Block 2 (operand blocks)

注:

Block定义:Data(8 bit) + EOM(1 bit) + ACK(1 bit)

Header Block定义:Initiator(4 bit) + Destination(4 bit) + EOM(1 bit) + ACK(1 bit)

所有的引导块和数据块都是10bit。

块结构:

帧结构:

逻辑分析仪采集解析的一条完整的cec消息:

cec待机唤醒介绍

当一个CEC设备连接到CEC网络中时,其会通过ping的方式获取到自身的逻辑地址。各个设备类型的逻辑地址如下所示,其中总共有16个逻辑地址,而有些设备具有多个逻辑地址,如录音设备就有1、2、9三个不同的逻辑地址。

待机唤醒的场景如下:

其中,playback device 可以是碟机等设备,当TV处于待机状态时,用户可以使用碟机的遥控器或者开机键唤醒碟机后,碟机会发送或消息来唤醒TV,当source需要将输出显示在TV上时,source必须同时发送和消息。其中,消息的操作码为0x04,,的操作码为0x82。

待机唤醒的处理流程和实现

这里只配置接收端,在接收到cec开机信号后唤醒即可,所以下面对接受流程进行说明:

cec初始化配置:

本次基于极海APM32F107RC 芯片,接收CEC信号的GPIO口为:PB0

使用外部中断 和 定时器(TMR4)外设计数的方法 实现CEC信号的接收采集

所以初始化配置需要使能GPIO口,配置定时器和外部中断

void apm_eint0_rising_config(void) //配置外部中断为上升沿触发
{
    
    EINT_Config_T EINT_InitStructure2; //上升沿触发结构体
    EINT_InitStructure2.line = EINT_LINE_0;
    EINT_InitStructure2.mode = EINT_MODE_INTERRUPT;
    EINT_InitStructure2.trigger = EINT_TRIGGER_RISING;
    EINT_InitStructure2.lineCmd = ENABLE;
    EINT_Config(&EINT_InitStructure2);
}
void apm_eint0_falling_config(void)//配置外部中断为下降沿触发
{
    EINT_Config_T EINT_InitStructure1; //下降沿触发结构体
    EINT_InitStructure1.line = EINT_LINE_0;
    EINT_InitStructure1.mode = EINT_MODE_INTERRUPT;
    EINT_InitStructure1.trigger = EINT_TRIGGER_FALLING;
    EINT_InitStructure1.lineCmd = ENABLE;
    EINT_Config(&EINT_InitStructure1);
}
//cec 初始化
void apm_cec_init(void)
{
    GPIO_Config_T gpioConfig;

    TMR_BaseConfig_T baseConfig;
    
    //使能时钟
    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR4);
    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOB);
    
    
    //初始化GPIO_PB0,浮空输入
    gpioConfig.pin = GPIO_PIN_0;
    gpioConfig.mode = GPIO_MODE_IN_FLOATING;
    gpioConfig.speed = GPIO_SPEED_50MHz;
    GPIO_Config(GPIOB, &gpioConfig);
    
    GPIO_ConfigEINTLine(GPIO_PORT_SOURCE_B,GPIO_PIN_SOURCE_0);//设置IO口与中断的映射关系
    
    EINT_ClearStatusFlag(EINT_LINE_0);
    
    apm_eint0_falling_config();//外部中断初始为下降沿触发
    
    NVIC_EnableIRQRequest(EINT0_IRQn, 2, 1);
    
    //初始化定时器
    baseConfig.period        = 65000;//设定计数器自动重装值,65ms更新
    baseConfig.division      = 71;//预分频器,1M的计数频率,1us加1
    baseConfig.clockDivision = TMR_CLOCK_DIV_1;//设置时钟分割
    baseConfig.countMode     = TMR_COUNTER_MODE_UP;//TIM向上计数模式
    TMR_ConfigTimeBase(TMR4,&baseConfig);
    
    TMR_ClearIntFlag(TMR4,TMR_INT_UPDATE);
    
    TMR_EnableInterrupt(TMR4,TMR_INT_UPDATE);//允许更新中断 

    //使能中断分组及优先级
    NVIC_EnableIRQRequest(TMR4_IRQn,2,2);
    
    TMR_Enable(TMR4);//使能定时器3

}

cec信号接收处理:

当触发外部中断并且设备处于待机状态时,根据cec波形以及时序要求解析CEC信号,通过判断opcode数据位的值 从而判断是否唤醒。

//接收一个cec  帧
void apm_cec_receive_frame(void)
{
    if(EINT_ReadIntFlag(EINT_LINE_0)) //外部中断
    {
        if(apm_get_power_status() == POWER_OFF_STATUS)  //当前状态不是开机
        {
        if(CEC_State == CEC_STATE_IDLE)
        {  
            //如果波形状态为空闲,开启定时器3计数
            TMR_ConfigCounter(TMR4,0);
            TMR_Enable(TMR4);
            cec_previous_time = TMR_ReadCounter(TMR4);
            //SKG_INFO("cec_previous_time: %d\r\n",cec_previous_time);
            apm_eint0_rising_config(); //上升沿触发
            updatecnt = 0;
            CEC_State = CEC_STATE_START; //波形为起始码接收状态
        }
        else
        {
            cec_current_time = TMR_ReadCounter(TMR4); //读取当前捕获值
            //SKG_INFO("cec_current_time: %d\r\n",cec_current_time);
            if(updatecnt == 0)
            {
                //计算当前时间    //时间间隔=当前时间-前一时间
                cec_interval_time = abs(cec_current_time - cec_previous_time);
            }
            else
            {
                cec_interval_time = abs(0x186A0 * updatecnt - cec_previous_time);
                cec_interval_time += cec_current_time;
            }
            cec_previous_time = cec_current_time;//将当前时间设置为前一个时间
            updatecnt = 0; //计数器的范围返回0状态
                
            //SKG_INFO("cec_interval_time: %d\r\n",cec_interval_time);
                
            if(CEC_State == CEC_STATE_START)
            {
                //低电平时间在3.5ms —— 3.9ms之间
                if((cec_interval_time > 3500) && (cec_interval_time < 3900))
                {
                    CEC_State = CEC_STATE_STARTEND; //起始结束接收状态
                }
                else
                {
                    
                    //SKG_INFO("debug 0 cec_interval_time: %d\r\n",cec_interval_time);
                    CEC_State = CEC_STATE_IDLE;
                }
                    apm_eint0_falling_config(); //下降沿触发
                }
                else if(CEC_State == CEC_STATE_STARTEND)
                {
                    //起始结束的低电平区间4ms --- 1.2ms
                    if((cec_interval_time > 300) && (cec_interval_time < 1300))
                    {
                        cec_byte = 0;
                        CEC_State = CEC_STATE_HEADERLOW; //header block 数据位的低电平
                        apm_eint0_rising_config(); //上升沿触发
                    }
                    else
                    {
                        //SKG_INFO("debug 1 cec_interval_time:%d\r\n",cec_interval_time);
                        //SKG_INFO("AAAAAAAAAAAAAAAAAA\r\n");
                        CEC_State = CEC_STATE_IDLE;
                        apm_eint0_falling_config();  //如果波形采集异常,中断回到初始状态下降沿触发
                    }
                    
                }
                else if(CEC_State == CEC_STATE_HEADERLOW)
                {
                    //逻辑1    低电平300-900
                    if((cec_interval_time > 300) && (cec_interval_time < 900))
                    {
                        headerdata <<= 1;
                        headerdata |= 1;
                        cec_byte++;
                        CEC_State = CEC_STATE_HEADERHIGH; //header block  数据位高电平
                    }
                    //逻辑0    低电平1200-1800 
                    else if((cec_interval_time > 1200) && (cec_interval_time < 1800))
                    {
                        headerdata <<= 1;
                        cec_byte++;
                        CEC_State = CEC_STATE_HEADERHIGH;
                    }
                    else
                    {
                        CEC_State = CEC_STATE_IDLE;
                        //SKG_INFO("debug 2 cec_interval_time:%d\r\n",cec_interval_time);
                    }

                    apm_eint0_falling_config();//下降沿触发
                }
                else if(CEC_State == CEC_STATE_HEADERHIGH)
                {
                    //如果上一次低电平的时间+当前高电平的时间在2.05ms-2.75ms,说明data bit传输正确
                    if(2050 < (cec_pre_interval_time + cec_interval_time) < 2750)
                    {
                        CEC_State = CEC_STATE_HEADERLOW;
                    }
                    else
                    {
                        //SKG_INFO("debug 3 cec_interval_time:%d\r\n",cec_interval_time);
                        CEC_State = CEC_STATE_IDLE;
                    }
                    if(cec_byte == 10) //header block 字节接收完成
                    {
                        //head_src = headerdata >> 6;
                        head_src = headerdata >> 2;
                        //head_src = headerdata;
                        headerdata = 0;
                        CEC_State = CEC_STATE_CODELOW; //data block  数据位低电平接收
                    }
                    apm_eint0_rising_config(); //上升沿触发
                }
                else if(CEC_State == CEC_STATE_CODELOW)
                {
                    //逻辑1    低电平300-900
                    if((cec_interval_time > 300) && (cec_interval_time < 900))
                    {
                        codedata <<= 1;
                        codedata |= 1;
                        cec_byte++;
                        CEC_State = CEC_STATE_CODEHIGH; //data block  数据位高电平
                    }
                    //逻辑0    低电平1200-1800
                    else if((cec_interval_time > 1200) && (cec_interval_time < 1800))
                    {
                        codedata <<= 1;
                        cec_byte++;
                        CEC_State = CEC_STATE_CODEHIGH;
                    }
                    else
                    {
                        //SKG_INFO("debug 4 cec_interval_time:%d\r\n",cec_interval_time);
                        CEC_State = CEC_STATE_IDLE;
                    }
                    
                    apm_eint0_falling_config();//下降沿触发
                }
                else if(CEC_State == CEC_STATE_CODEHIGH)
                {
                    //如果上一次低电平的时间+当前高电平的时间在2.05ms-2.75ms,说明data bit传输正确
                    if(2050 < (cec_pre_interval_time + cec_interval_time) < 2750)
                    {
                        CEC_State = CEC_STATE_CODELOW;
                    }
                    else
                    {
                        //SKG_INFO("debug 5 cec_interval_time:%d\r\n",cec_interval_time);
                        CEC_State = CEC_STATE_IDLE;
                    }
                                        if(cec_byte == 18)
                    {
                        opcode = codedata;
                        codedata = 0;
                        CEC_State = CEC_STATE_IDLE;
                    }
                    apm_eint0_rising_config(); //上升沿触发
                }
            }
            cec_pre_interval_time = cec_interval_time;
        }
    }
}
                    

波形的处理流程是  使用状态标志位  的变化来表示接收的字节

typedef enum
{
    CEC_STATE_IDLE=0,        //0  初始为空闲
    CEC_STATE_START,        //1  起始位
    CEC_STATE_STARTEND,     //2     起始位结束
    CEC_STATE_HEADERLOW,    //3  head block  数据位低电平
    CEC_STATE_HEADERHIGH,  //4  head block  数据位高电平
    CEC_STATE_CODELOW,     //5  data block  数据位低电平
    CEC_STATE_CODEHIGH,    //6  data block  数据位高电平
}CEC_State_enum;

处理过程中没有单独解析ack和eom,字节只接收两个,一个header   10位数据,一个opcode  8位数据。

波形处理流程:

第一次进入中断为空闲,开启定时器计数并读取当前计数值,状态改为起始位接收,中断改为上升沿触发

第二次进入中断读取定时器的值,减去前一次计数器的值,就是起始位低电平维持的时间,判断时间是否为在协议范围,把触发改为下降沿,如果在范围内将状态改为起始位结束状态

第三次进入中断 依然是计算出时间的差值,判断高电平维持的时间范围,在范围内则起始位接收完成,将状态改为接收header clock,把中断改为上升沿触发

第四次进入中断  由于上一次是下降沿触发,所以时间的差值就是低电平的持续时间,判断时间的范围得到逻辑0或逻辑1,逻辑1 headerdata  

数据处理后将状态改为HEADERHIGH  ,中断改为下降沿触发

下一次进入中断  时间的差值就是高电平的持续时间,进入HEADERHIGH 条件判断,当前的时间差值+上一次的时间差值就是数据传输的总时间,判断总时间是否在范围,在范围将状态改为HEADERLOW,中断改为上升沿触发,接收处理下一位数据,接收的数据位达到10位,将状态改为接收data clock。Data的接收处理和header相同。接收的数据位达到18位就将数据保存,状态改为空闲。

void apm_cec_ctrl_handle(void)
{
    if(opcode == CEC_VIEW_ON || opcode == ACTIVE_SOURSE)
    {
        if(apm_get_power_status() == POWER_OFF_STATUS)
        {    
            power_on();            
        }

    }
}

在实际调试过程中可以根据需求和现象,调整电平时间判断范围,加入EOM位的判断作为数据传输结束的标志,加大数据的接收范围等。

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

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

相关文章

嵌入式linux系统设备树实例分析

前言 我们可以从LED程序中榨取很多知识&#xff1a;基本的驱动框架、驱动的简单分层、驱动的分层分离思想、总线设备驱动模型、设备树等。这大多都是结合韦老师的教程学的。 这篇笔记结合第6个demo&#xff08;基于设备树&#xff09;来学习、分析&#xff1a; 框图 下面是L…

10 创建型模式-原型模式

引言&#xff1a; 创建对象的五种方式&#xff1a; 通过new关键字通过Class类的newInstance()方法通过Constructor类的newInstance()方法利用Clone方法反序列化 Clone方法&#xff1a; 其实现方式正是通过调用 Object 类的 clone() 方法来完成。 protected native Object cl…

python安装.whl文件

python --version https://www.lfd.uci.edu/~gohlke/pythonlibs/ 用CtrlF找需要安装的包 下载对应版本的whl python3.8 把下载好的whl放到安装路径下&#xff1a;C:\Users\Administrator\AppData\Local\Programs\Python\Python38\Lib\site-packages 并在该路径下打开cmd执行…

GaussDB数据库管理系统介绍

1.GaussDB的发展 2.GaussDB的生态 内部&#xff1a; 云化自动化方案。通过数据库运行基础设施的云化将DBA(数据库管理员)和运维人员的日常工作 自动化。外部&#xff1a; 采用与数据库周边生态伙伴对接与认证的生态连接融合方案&#xff0c;解决开发者/DBA难获取、应用难对接等…

Linux绝对路径和相对路径

在 Linux 中&#xff0c;简单的理解一个文件的路径&#xff0c;指的就是该文件存放的位置。 只要我们告诉 Linux 系统某个文件存放的准确位置&#xff0c;那么它就可以找到这个文件。指明一个文件存放的位置&#xff0c;有 2 种方法&#xff0c;分别是使用绝对路径和相对路径。…

【驱动开发】LED灯的亮灭——通过字符设备驱动的分步实现编写LED驱动,实现设备文件和设备的绑定

头文件&#xff1a; #ifndef __HEAD_H__ #define __HEAD_H__typedef struct {unsigned int MODER;unsigned int OTYPER;unsigned int OSPEEDR;unsigned int PUPDR;unsigned int IDR;unsigned int ODR; }gpio_t;//LED灯的寄存器地址 #define LED1_ADDR 0X50006000 #define L…

深入理解Redis集群模式、协议、元数据维护方式

文章目录 &#x1f34a; 集群模式&#x1f34a; 集群协议&#x1f34a; 元数据维护方式&#x1f389; 集中式&#x1f389; gossip 协议 &#x1f4d5;我是廖志伟&#xff0c;一名Java开发工程师、Java领域优质创作者、CSDN博客专家、51CTO专家博主、阿里云专家博主、清华大学出…

适用于 Linux 和 Unix 的特权访问管理

凭据、SSH 密钥、服务帐户、数字签名、文件系统等内容构成了Linux 环境的关键部分&#xff0c;虽然大多数PAM供应商为基于Windows的环境提供无缝的特权访问管理&#xff0c;但它们的通用性不足以为Linux&#xff0c;Unix和*nix环境扩展相同的功能和功能。 Linux 中的root权限是…

redis的key超时策略和key淘汰机制(面试题详解)

ChatGPT给出的回答&#xff1a; Redis中的Key超时策略和Key淘汰机制是为了有效管理内存和控制数据的生命周期。 Key超时策略&#xff1a;Redis可以为每个Key设置过期时间&#xff0c;一旦Key过期&#xff0c;它将自动从Redis中删除。可以使用EXPIRE命令为Key设置过期时间&…

系统设计 - 我们如何通俗的理解那些技术的运行原理 - 第六部分:开发运维

本心、输入输出、结果 文章目录 系统设计 - 我们如何通俗的理解那些技术的运行原理 - 第六部分&#xff1a;开发运维前言DevOps vs. SRE vs. Platform Engineering。有什么区别&#xff1f;什么是k8s&#xff08;Kubernetes&#xff09;&#xff1f;控制面板组件节点 Docker vs…

关于阿里云服务器续费详细流程_优惠续费方法

阿里云服务器如何续费&#xff1f;续费流程来了&#xff0c;在云服务器ECS管理控制台选择续费实例、续费时长和续费优惠券&#xff0c;然后提交订单&#xff0c;分分钟即可完成阿里云服务器续费流程&#xff0c;阿里云服务器网分享阿里云服务器详细续费方法&#xff0c;看这一篇…

【代码随想录】算法训练营 第十三天 第五章 栈与队列 Part 3

239. 滑动窗口最大值 题目 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 思路 一开始我是直接暴力两层循环的&#xff…

Python学习笔记——MYSQL,SQL核心

食用说明&#xff1a;本笔记适用于有一定编程基础的伙伴们。希望有助于各位&#xff01; SQL语言分类 SQL注释 库管理 表管理 数据操作 分组聚合 分页限制 需要注意的是关键字的顺序不可以错乱&#xff0c;否则会报错其中LIMIT关键字的n是指从第n个开始&#xff0c;m是指查…

http post协议实现简单的rpc协议,WireShark抓包分析

文章目录 1.http 客户端-RPC客户端1.http 服务端-RPC服务端3.WireShark抓包分析3.1客户端到服务端的HTTP/JSON报文3.2服务端到客户端的HTTP/JSON报文 1.http 客户端-RPC客户端 import json import requests# 定义 RPC 客户端类 class RPCClient:def __init__(self, server_url…

【蓝桥杯选拔赛真题43】python二进制位数 青少年组蓝桥杯python 选拔赛STEMA比赛真题解析

目录 python二进制位数 一、题目要求 1、编程实现 2、输入输出 二、算法分析

深入浅出Apache SeaTunnel SQL Server Sink Connector

在大数据时代&#xff0c;数据的迁移和流动已经变得日益重要。为了使数据能够更加高效地从一个源流向另一个目标&#xff0c;我们需要可靠、高效和易于配置的工具。今天&#xff0c;我们将介绍 JDBC SQL Server Sink Connector&#xff0c;这是一个专为 SQL Server 设计的连接器…

嵌入式linux总线设备驱动模型分析

嵌入式linux系统按照&#xff0c;分层&#xff0c;抽象的思想&#xff0c;按照这样的思想来设计我们的程序可以更容易写出耦合性低、独立性强、可重用性强的代码。 Linux内核中更是存在着更多的分离、分层思想的代码&#xff0c;platform平台设备驱动就是用了这样的思想。本篇…

机器学习(新手入门)-线性回归 #房价预测

题目&#xff1a;给定数据集dataSet&#xff0c;每一行代表一组数据记录,每组数据记录中&#xff0c;第一个值为房屋面积&#xff08;单位&#xff1a;平方英尺&#xff09;&#xff0c;第二个值为房屋中的房间数&#xff0c;第三个值为房价&#xff08;单位&#xff1a;千美元…

pv操作题目笔记

对于 pv 操作分以下几步走 什么是pv操作 PV操作在进程同步中通常指的是信号量&#xff08;Semaphore&#xff09;操作。信号量是一种用于控制多个并发进程或线程之间的同步和互斥访问的同步工具。PV操作通常涉及两个基本操作&#xff1a;P操作&#xff08;wait操作&#xff0…

算法通关村第十一关青铜挑战——移位运算详解

大家好&#xff0c;我是怒码少年小码。 计算机到底是怎么处理数字的&#xff1f; 数字在计算机中的表示 机器数 一个数在计算机中的二进制表示形式&#xff0c;叫做这个数的机器数。 机器数是带符号的&#xff0c;在计算机用一个数的最高位存放符号&#xff0c;正数为0&am…