【面试题】
1.UART 和 IIC 的区别
UART (Universal Asynchronous Receiver-Transmitter)
- 用途:用于异步串行通信。
- 信号线:通常需要两根线(TX 和 RX),有时还需一根地线。
- 通信方式:点对点。
- 数据传输:单向或双向(全双工),可以同时进行收发信息。
- 同步方式:异步,没有时钟线,通过设置波特率同步(起始位和停止位来同步数据传输)。
- 应用场景:适用于长距离通信,如传感器、调制解调器等。
IIC (Inter-Integrated Circuit)
- 用途:用于同步串行通信。
- 信号线:需要两根线(SCL 和 SDA),其中 SCL 是时钟线,SDA 是数据线。
- 通信方式:多主多从。
- 数据传输:半双工,发送时不能接收,接收时不能发送。
- 同步方式:同步,通过时钟线同步。
- 应用场景:适用于短距离通信,如传感器、EEPROM 等。
特性 | UART (异步串行通信) | IIC (同步串行通信) |
---|---|---|
用途 | 异步串行通信 | 同步串行通信 |
信号线 | 两根线(TX 和 RX),有时需一根地线 | 两根线(SCL 和 SDA) |
通信方式 | 点对点 | 多主多从 |
数据传输 | 单向或双向(全双工),可以同时收发信息 | 半双工,发送时不能接收,接收时不能发送 |
同步方式 | 异步,无时钟线,通过波特率和起始位、停止位同步 | 同步,通过时钟线(SCL)同步 |
应用场景 | 长距离通信,如传感器、调制解调器等 | 短距离通信,如传感器、EEPROM 等 |
2. I2C
2.1 IIC 的数据帧结构:
- 起始信号(START):SDA 由高变低,SCL 保持高电平。
- 从设备地址:7 /10 位地址 + 1 位读/写位(0 表示写,1 表示读)。
- 应答位(ACK/NACK):1位,从设备返回低电平为 ACK,高电平为 NACK。
- 数据字节:8 位数据。
- 停止信号(STOP):SDA 由低变高,SCL 保持高电平。
2.2 I2C 通信流程
- 起始信号(START):主设备发送起始条件,表示通信开始。
- SDA 由高变低,SCL 保持高电平
- 从设备地址字节:因为是多主多从,所以主设备需要发送想建立连接的从设备的地址字节
- 地址字节的前 7 位或前 10 位是从设备地址,最后 1 位是读1 / 写0标志)
- 应答位:设备接收到地址字节后,发送一个应答位低电平(ACK)表示确认。
- 低电平(ACK)表示确认。
- 高电平(NACK)表示地址不匹配或数据错误或者设备忙或故障。
- 数据字节:主设备和从设备根据读/写标志进行数据交换。
- 发送数据位时,每个数据位(8 bit)后面跟着一个回应信号ACK(1 bit 低电平脉冲)。
- 数据字节:8 bit
- 应答字节:1 bit (低电平脉冲)
- 停止条件:主设备发送停止条件,表示通信结束。
- SDA 由低变高,SCL 保持高电平
2.3 I2C的起始信号、应答信号、停止信号、空闲状态?
起始信号: 当SCL为高期间,SDA由高到低的跳变
应答信号: 应答位是一个低电平脉冲
停止信号: 当SCL为高期间,SDA由低到高的跳变;
空闲状态: 当总线上的SDA和SCL两条信号线同时处于高电平,便是空闲状态, 当不传输数据时,SDA和SCL被上拉电阻拉高,即进入空闲状
下面的还没整理:
1. UART
UART(通用异步收发传输器)
-
异步通信:
- UART通信是异步的,意味着发送方和接收方的时钟是独立的,不需要同步信号。
-
全双工通信:
- UART支持全双工通信,即可以同时进行数据的发送和接收。
-
数据格式:
- UART通信的数据格式通常包括数据位、起始位和停止位。
- 起始位:每个字节的开始是一个低电平信号(0)。
- 数据位:可以是5到9位,常用的是8位。
- 奇偶校验位(Parity Bit):可选的,用于错误检测。
- 停止位:数据字节后的一个或两个高电平信号(1),表示数据传输的结束。
- UART通信的数据格式通常包括数据位、起始位和停止位。
-
波特率:
- 波特率(Baud Rate)是UART通信的速率,即每秒传输的信号单位数。常见的波特率有9600、19200、38400、115200等。
-
硬件连接:
- 通常只需要两条线:TX(发送线)和RX(接收线)。
1.2 常用寄存器
以下是STC51单片机中与UART通信相关的常用寄存器:
寄存器名称 | 功能描述 |
---|---|
SCON | 串行控制寄存器,用于设定串行口的工作方式、接收/发送控制以及设置状态标志等。 |
PCON | 电源控制寄存器,包括波特率选择和帧错误控制位。 |
SBUF | 串行数据缓冲寄存器,物理上是两个独立的寄存器,但占用相同的地址。 |
TMOD | 定时器模式寄存器,用于配置定时器的工作模式,UART通信中用于控制波特率。 |
TH1 | 定时器1高8位,用于设置定时器1的初值,进而控制波特率。 |
TL1 | 定时器1低8位,用于设置定时器1的初值,进而控制波特率。 |
1.3 代码回顾
#include "reg52.h"
#include "intrins.h"
sfr AUXR = 0x8E;void UartInit(void) {// 9600bps @ 11.0592MHzAUXR = 0x1;SCON = 0x40; // 选择串口工作方式1TMOD &= 0x0F;TMOD |= 0x20; // 定时器1工作在8位自动重载TH1 = 0xFD;TL1 = 0xFD; // 9600波特率根据公式算出的初始值TR1 = 1; // 定时器开始工作// ES = 1;// EA = 1;
}void Delay1000ms() {// @11.0592MHzunsigned char i, j, k;_nop_();i = 8;j = 1;k = 243;do {do {while (--k);} while (--j);} while (--i);
}void main() {char data_msg = 'a';// 配置C51串口的通信方式UartInit();while(1) {Delay1000ms();// 往发送缓冲区写入数据,就完成数据的发送SBUF = data_msg;}
}
1.4 面试常见问题
1.4.1 简述一下UART如何传输一个字符’A’
UART传输一个字符’A’的过程如下:
- 单片机通过配置UART的相关寄存器(如SCON、TMOD、TH1等)设置波特率和通信参数。
- 将字符’A’的ASCII码值(65)写入到UART的数据缓冲寄存器SBUF中。
- UART硬件检测到SBUF非空后,自动在起始位后发送’A’的8位ASCII码数据(从最低位(LSB)开始发送,然后逐步发送到最高位(MSB))。
- 接着发送一个可选的奇偶校验位。
- 最后发送一个或两个停止位来标识传输结束。
- 接收方的UART在检测到起始位后开始接收数据,并在停止位后确认字符’A’已完全接收。
1.4.2 简述一下UART通信协议
UART通信协议是一种异步串行通信机制,它允许设备之间通过两条线(发送线TX和接收线RX)进行数据交换,数据以字符为单位传输,每个字符由起始位、一定数量的数据位(通常是5到8位)、可选的奇偶校验位和停止位组成,所有这些位都以特定的波特率(即每秒传输的符号数)进行传输,从而实现设备间的同步通信。
1.4.3 如何提升串口通信效率
提升串口通信效率可以通过以下方法:
- 优化通信参数:选择合适的波特率和数据格式。
- 使用中断或DMA:减少CPU占用,提高数据传输效率。
- 采用更高的波特率:加快数据传输速度。
- 减少不必要的通信握手和校验过程:简化通信流程。
- 合理配置缓冲区大小:平衡内存使用和数据吞吐量。
- 优化协议栈和数据处理流程:提高软件层面的效率。
1.4.4 C51和STM32对UART使用上的区别
C51单片机和STM32单片机在使用串口(UART)时的主要区别如下:
-
硬件架构:
- C51单片机:基于传统的8051架构,通常只包含一个UART接口。
- STM32单片机:基于ARM Cortex-M系列处理器,拥有更复杂的总线结构和更多的串口资源,如USART1、USART2、USART3等。
-
外设功能:
- C51单片机:外设种类较少,功能相对简单。
- STM32单片机:集成了丰富的片上外设,包括多个UART接口,以及其他高级通信接口如SPI、I2C等。
-
波特率配置:
- C51单片机:波特率配置通常涉及到定时器的设置,需要手动计算并设置波特率生成器。
- STM32单片机:波特率配置更为灵活,可以通过软件配置APB时钟和USART分频寄存器来设置。
-
编程和配置:
- C51单片机:串口配置相对简单,主要涉及SCON、PCON和TMOD等寄存器的设置。
- STM32单片机:串口配置更为复杂,需要配置GPIO、RCC(时钟控制)、USART等多个寄存器,并且可以使用CubeMX等软件工具来简化配置。
-
中断和DMA:
- C51单片机:UART通信通常使用中断方式处理数据接收和发送,DMA功能较弱。
- STM32单片机:支持更高级的中断处理和DMA数据传输,可以提高数据传输效率。
-
内存和处理能力:
- C51单片机:通常具有较小的内存容量和较低的处理能力。
- STM32单片机:具有更大的内存容量和更高的处理能力,适合处理更复杂的数据和通信任务。
1.4.5 你用串口做过哪些开发
在我之前的开发经验中,串口主要用于网络通信模块和语音模块:
- 网络模块:较多使用AT指令驱动,如WiFi模块、蓝牙模块、4G模块,还有物联网NB-IoT模块等。
- 语音模块:使用SU-06模块,通过串口数据来交互模块中的固件,通过发送特定串口数据来播报语音,或者根据接收的串口数据来判断语音模块识别结果。
1.4.6 小车中关于串口的使用
智能小车属于大学期间的比赛项目,当时串口使用有两个目的:
- 调试:如驱动电机、获取电机速度、获取小车前方障碍物距离等。
- 连接语音模块:根据语音模块的识别结果来切换小车的工作模式,如避障模式、跟随模式、手机控制模式的切换。
因为51单片机只有一个串口,在项目设计中把一个串口拆分为两个模块连接:
- 语音模块:仅在需要语音识别功能时连接到C51串口的输入口。
- 蓝牙或WiFi:需要通过蓝牙或WiFi把小车数据(如车速、温湿度采集数据)发送到上位机时,连接到C51串口的输出口。
2. I2C
2.1 I2C协议概述
C51单片机实现I2C通信主要涉及以下几个方面:
-
I2C总线结构:
- I2C通信使用两条线,数据线(SDA)和时钟线(SCL),所有设备共享这两条线。
-
通信时序:
- I2C通信时序包括起始信号、数据传输、应答信号和停止信号。主设备生成时钟信号并控制通信的开始和结束,从设备响应时钟信号并进行数据的发送或接收。
-
数据传输协议:
- I2C数据传输包括发送和接收字节,每个字节包含8位,从最高位开始传输。
- 发送时,主机将数据位放在SDA线上,然后拉高SCL,从机在SCL高电平期间读取数据位。
- 接收时,从机将数据位放在SDA线上,主机在SCL高电平期间读取数据位。
-
软件模拟I2C通信:
- C51单片机可以通过软件模拟I2C通信时序,包括起始信号、发送字节、接收字节、发送应答和接收应答等。
-
硬件接口:
- C51单片机通过两个引脚(如P21和P20)分别连接到I2C的SCL和SDA,实现与I2C设备的通信。
-
编程实现:
- 在C51单片机上,需要编写程序来控制I2C通信,包括发送起始信号、发送数据字节、接收数据字节、发送和接收应答位以及发送停止信号。
-
应用示例:
- 例如,使用C51单片机与OLED进行通信时,可以通过编写特定的I2C通信协议函数来实现数据的读写操作。
总结来说,C51单片机实现I2C通信需要理解I2C的总线结构和通信时序,并通过软件编程来模拟I2C通信协议,控制硬件接口进行数据的发送和接收。
2.2 代码回顾
#include "reg52.h"
#include "intrins.h"sbit scl = P0^1;
sbit sda = P0^3;void IIC_Start() {sda = 1;scl = 1;_nop_();sda = 0;_nop_();
}void IIC_Stop() {sda = 0;scl = 1;_nop_();sda = 1;_nop_();
}char IIC_ACK() {char flag;sda = 1; // 在时钟脉冲9期间释放数据线_nop_();scl = 1;_nop_();flag = sda;_nop_();scl = 0;_nop_();return flag;
}void IIC_Send_Byte(char dataSend) {int i;for(i = 0; i < 8; i++) {scl = 0; // scl拉低,让sda做好数据准备sda = dataSend & 0x80; // 1000 0000 获得dataSend的最高位,给sda_nop_(); // 发送数据建立时间scl = 1; // scl拉高开始发送_nop_(); // 数据发送时间scl = 0; // 发送完毕拉低_nop_();dataSend = dataSend << 1;}
}void main() {int a = 10;IIC_Start();
}
2.3 面试官常问
2.3.1 说一下I2C通信协议
I2C通信协议是一种多主机、同步、串行计算机总线,用于连接微控制器和其他设备,通过两条线(数据线SDA和时钟线SCL)实现数据的传输。其特点是支持多个设备共享同一总线,且通信时序由主设备控制,从设备响应,包括起始条件、数据传输、应答位和停止条件等关键步骤,广泛应用于微控制器与外围设备如传感器、存储器等之间的数据交换。
2.3.2 描述I2C的起始信号、终止信号和停止信号
在I2C通信协议中:
- 起始信号:由SDA线在SCL保持高电平时从高电平跳变到低电平产生,表示一次新的数据传输开始。
- 停止信号:则是SDA线在SCL保持高电平时从低电平跳变到高电平,标志着数据传输的结束。
- 重复启动信号(Restart Condition):是SDA线在SCL为高电平时从高电平跳变到低电平,紧接着在SCL为低电平时回到高电平,用于在不释放SDA和SCL线的情况下开始新一轮的数据传输。
4.3.3 描述I2C总线数据传输过程
I2C总线数据传输过程开始于主设备生成的起始信号,随后主设备通过SDA线发送数据字节,每个字节后跟一个由从设备在SCL线产生的应答信号(ACK),数据传输可以包含多个字节,并通过发送应答位来确认每个字节的成功接收。传输结束后,主设备发出停止信号或重复启动信号来结束当前传输或开始新的传输周期。在整个过程中,SCL线由主设备控制,用于同步数据的发送和接收。
4.3.4 I2C通信有几种工作模式
I2C通信协议主要有以下几种工作模式:
- 单主单从模式:在这种模式下,只有一个主设备和一个从设备。主设备通过发送从设备地址选择具体的从设备进行通信。
- 单主多从模式:在这种模式中,主设备可以与多个从设备通信。每个从设备都有唯一的地址,主设备通过发送从设备地址选择特定的从设备。
- 多主多从模式:在这种模式中,多个主设备可以与多个从设备通信。I2C协议通过仲裁机制确保只有一个主设备在总线上进行数据传输。
这些模式允许I2C总线在不同的应用场景中灵活地进行数据通信。
4.3.5 I2C通信总线上拉电阻多大
I2C总线的上拉电阻通常推荐值在1kΩ到10kΩ之间。对于标准速率为100kHz的I2C通信,常见的选择是4.7kΩ或10kΩ。对于快速模式(400kHz)或更快的高速模式(3.4MHz),可能需要降低阻值到几千欧姆,以保证信号的快速上升沿。在实际应用中,常见的I2C上拉电阻阻值范围从1kΩ到10kΩ。
4.3.6 C51如何通过I2C驱动OLED屏
通过C51单片机驱动OLED显示屏,主要涉及以下几个步骤:
-
初始化I2C通信:
- 定义I2C通信所需的引脚,并初始化这些引脚的状态。例如,将P10设置为I2C时钟线(SCLK),P11设置为I2C数据线(SDA)。
-
编写I2C通信函数:
- 包括I2C的起始信号、停止信号、字节写入、等待应答等函数。这些函数通过软件模拟I2C协议的时序,控制数据线和时钟线来实现数据的发送和接收。
-
发送命令和数据:
- 通过编写的I2C通信函数,向OLED发送控制命令和显示数据。通常,命令和数据需要分别发送,命令用于设置OLED的工作模式,数据用于显示内容。
-
OLED显示控制:
- 定义OLED的显示控制函数,如清屏、显示字符、显示数字、显示字符串等。这些函数内部会调用I2C通信函数来发送具体的命令和数据。
通过以上步骤,可以在C51单片机上实现对OLED显示屏的控制。
————————
3.115200 波特率对应多少字节?
115200 波特率意味着每秒钟可以传输 115200 个位。在大多数串行通信协议中,一个字节(byte)由 8 位组成,即 ( \frac{115200}{8} ) 个字节。但在实际的串行通信中,还需要考虑起始位、停止位以及可能的奇偶校验位。
假设使用的是最常用的 8 位数据位、1 位起始位和 1 位停止位的配置(即 8N1 配置,其中 N 表示无奇偶校验位),那么一个完整的字节传输需要 10 位(1 + 8 + 1)。因此,我们可以计算每秒传输的字节数如下:
[ \text{每秒传输的字节数} = \frac{\text{波特率}}{\text{每字节的位数}} ]
对于 115200 波特率:
[ \text{每秒传输的字节数} = \frac{115200}{10} = 11520 \text{ 字节/秒} ]
总结
- 波特率:115200 波特率
- 每字节的位数:10 位(1 起始位 + 8 数据位 + 1 停止位)
- 每秒传输的字节数:11520 字节/秒
因此,115200 波特率对应的每秒传输字节数为 11520 字节。
4. 多线程间临界资源用了什么保证同步和互斥?
答:多线程之间的临界资源通常采用以下几种方式来保证同步和互斥:
-
信号量(Semaphore):一种计数器,用于控制多个进程对共享资源的访问。当信号量大于零时,进程可以获取该资源;否则,进程必须等待直到信号量变为正数。
-
互斥锁(Mutex):确保同一时间只有一个线程能访问特定的数据结构或资源。其他想要访问该资源的线程会被阻塞,直到持有锁的线程释放它为止。
-
条件变量(Condition Variable):与互斥锁一起使用,允许线程暂停和恢复执行,直到满足某些条件。这有助于避免“忙等待”现象,提高效率。
这些机制共同确保了多线程环境下的资源共享安全性和一致性。
5. 交叉编译是什么,为什么需要交叉编译?
答:交叉编译是指在一台机器上编写源代码,在另一台不同架构的机器上运行编译后的二进制文件。这种做法的主要原因包括:
-
目标设备资源有限:例如嵌入式系统或移动设备,它们可能没有足够的计算能力或存储空间来运行复杂的编译过程。
-
开发环境需求:开发者希望在自己的计算机上进行开发和测试,而不是在目标设备上,这样可以利用更好的开发工具和更快的反馈循环。
-
安全性考量:有些情况下,为了保护目标系统的完整性,不允许直接在其上进行编译活动。
6. Linux采取什么手段调试代码?
答:Linux提供了多种强大的工具和技术来帮助开发者调试代码,主要包括:
-
GDB(GNU Debugger):这是一个广泛使用的源码级调试器,支持C, C++, Objective-C等多种语言。GDB允许用户查看和修改程序状态,设置断点,检查变量值等。
-
Valgrind:一套开源的工具集,主要用于内存错误检测、性能分析和缓存模拟。特别适合查找内存泄漏和其他难以发现的问题。
-
strace:用于追踪系统调用和信号,可以帮助理解程序如何与操作系统交互。
-
core dump:当程序崩溃时,Linux会自动生成核心转储文件,包含程序终止时刻的内存映像,这对于诊断问题非常有用。
7. GDB常用命令有哪些?
答:GDB有许多有用的命令,这里列举一些最常见的:
-
run
:开始执行程序。 -
break
:设置断点。 -
continue
或c
:继续执行程序,直到遇到下一个断点或程序结束。 -
step
或s
:逐行执行代码,进入函数体。 -
next
或n
:逐行执行代码,但不会进入函数体。 -
list
或l
:显示当前正在执行的源代码行及其上下文。 -
info breakpoints
:列出所有的断点。 -
delete
:删除指定的断点。 -
watch
:监视表达式的值变化。 -
backtrace
或bt
:显示当前的调用堆栈。
8. 常用的是,怎么使用的?
答:GDB的基本使用步骤如下:
-
启动GDB并加载你的程序:
gdb your_program
-
设置断点:
break function_name
或b line_number
-
运行程序:
run
-
使用
next
,step
,continue
等命令逐步执行代码 -
查看变量值:
print variable_name
-
结束调试:
quit
9. 什么叫内存泄露?
答:内存泄露指的是程序在申请内存之后,无法正确地释放已经不再使用的内存块。随着时间推移,这些未被回收的内存会导致应用程序占用越来越多的物理内存,最终可能导致系统资源耗尽,甚至崩溃。
10. 段错误?
答:段错误(Segmentation Fault)是一种常见的程序错误,发生在程序尝试访问不属于其权限范围内的内存位置时。这可能是由于数组越界、空指针解引用或其他形式的非法内存访问造成的。段错误通常会导致程序立即退出,并输出错误消息。
11. char a 的取值范围?
答:字符型变量char a
的取值范围依赖于具体的编程语言和编译器。在C/C++中,默认情况下char
类型是带符号的,其取值范围从-128到+127。如果声明为unsigned char
,则取值范围是从0到255。
12. static关键字有什么作用?
答:static
关键字在C/C++中有几个不同的用途:
-
在全局作用域中,
static
修饰符使得变量仅在本文件范围内有效,不能被其他文件访问。 -
在函数体内,
static
变量具有静态存储期,即使函数返回后仍然保留其值,下次调用时保持不变。 -
对于成员函数,
static
表明它是类级别的,不需要实例化就可以调用,且对所有对象都是一样的行为。
13. 堆和栈有什么区别?
答:堆和栈是两种不同的内存管理方式,主要区别在于:
-
栈(Stack):栈是一种先进后出(LIFO)的数据结构,由编译器自动管理。栈内存用于存储函数参数、局部变量和返回地址等临时数据。栈的空间大小固定,增长速度快,但容量相对较小。
-
堆(Heap):堆内存由程序员手动分配和释放,常用于动态创建对象和大块数据。堆内存的增长速度较慢,但容量较大,适用于长时间存在的数据。
11. Git版本管理工具?
答:Git是一款分布式版本控制系统,设计目的是高效快速地处理从小到大的项目版本管理。Git的核心特点包括:
-
分布式:每个克隆的仓库都有完整的历史记录和版本库,无需连接中央服务器即可工作。
-
快速:本地操作如提交、分支切换等几乎瞬间完成。
-
安全性高:每次提交都会生成唯一的哈希标识,防止数据篡改。
-
支持非线性开发:轻松创建、合并和删除分支。
12. 说说你这个项目最大的难点,你是怎么解决的?
答:在这个项目中,我们面临的一个重大挑战是如何优化算法以适应大规模数据处理的需求。为了解决这一难题,我们采用了以下策略:
-
并行处理:利用多核处理器的优势,将任务分解成独立的部分并发执行。
-
数据压缩:通过对原始数据进行预处理,减少不必要的冗余,降低存储和处理成本。
-
缓存技术:合理运用缓存机制,减少重复计算,加快响应速度。
通过这些措施,我们成功提高了系统的整体性能和稳定性。
13. PWM IIC UART 英文?
答:PWM: Pulse Width Modulation(脉冲宽度调制)
IIC: Inter-Integrated Circuit(集成电路总线)
UART: Universal Asynchronous Receiver/Transmitter(通用异步收发器)
8. 消息队列有什么优点?
消息队列的主要优点包括:
- 解耦:生产者和消费者之间解耦,生产者不需要关心消费者的细节。
- 异步:生产者发送消息后可以立即返回,消费者在空闲时处理消息。
- 削峰:通过消息队列可以平滑处理高峰期的请求,避免系统过载。
- 可靠性:消息队列通常支持消息的持久化,确保消息不会丢失。
- 灵活性:支持多种消息模式,如发布/订阅、点对点等。
9. 队列和栈有什么区别?
- 队列:先进先出(FIFO),新元素从队尾插入,从队头删除。
- 栈:后进先出(LIFO),新元素从栈顶插入,也从栈顶删除。
10. 堆和栈有什么区别?
-
管理方式:
- 栈:由操作系统自动分配和释放。
- 堆:由程序员手动分配和释放。
-
空间大小:
- 栈:通常较小,大小有限。
- 堆:通常较大,大小受限于系统内存。
-
生长方向:
- 栈:由高地址向低地址生长。
- 堆:由低地址向高地址生长。
-
分配方式:
- 栈:静态分配和动态分配。
- 堆:动态分配。
-
分配效率:
- 栈:分配和释放速度快。
- 堆:分配和释放速度较慢,容易产生内存碎片。
11. UART 英文、中文全称?
- 英文全称:Universal Asynchronous Receiver-Transmitter
- 中文全称:通用异步收发传输器
12. UART 和 I2C 有什么区别?
-
UART:
- 串行通信:使用两根线(TX和RX)进行全双工通信。
- 异步:没有时钟线,通过波特率同步。
- 点对点:通常用于一对一通信。
-
I2C:
- 串行通信:使用两根线(SCL和SDA)进行半双工通信。
- 同步:有时钟线(SCL)同步数据传输。
- 多设备:支持多主多从设备通信。
13. I2C 一条总线最多可以挂多少从设备?
I2C总线理论上可以支持128个从设备,但实际上受限于总线电容和时序要求,通常建议不超过10-20个从设备。
14. PWM 英文、中文全称?
- 英文全称:Pulse Width Modulation
- 中文全称:脉冲宽度调制
15. 交叉编译是什么,为什么需要交叉编译?
- 交叉编译:在一种平台上生成另一种平台可执行代码的过程。
- 为什么需要交叉编译:
- 目标平台资源有限:目标平台可能没有足够的资源(如内存、CPU)来编译代码。
- 开发便利性:在开发环境中编译代码,然后将编译后的程序传输到目标平台运行。
- 构建速度:开发平台通常性能更强,编译速度更快。
16. Git 版本管理工具?
Git 是一个分布式版本控制系统,用于跟踪文件的变化,支持多人协作开发。主要功能包括:
- 版本控制:记录每次提交的变更。
- 分支管理:支持创建和合并分支。
- 代码回溯:可以恢复到任何历史版本。
- 远程仓库:支持与远程仓库同步。
17. GDB 常用的命令有哪几个?
run
:开始或重新开始程序。break
:设置断点。continue
:继续执行程序。step
:单步执行,进入函数。next
:单步执行,不进入函数。print
:打印变量的值。quit
:退出GDB。
18. 函数指针和指针函数有什么区别?
-
函数指针:指向函数的指针,可以用来调用函数。
void (*func_ptr)(int);
-
指针函数:返回值为指针的函数。
int* func(int x);
19. 什么叫回调函数,举例说说哪些?
- 回调函数:在某个事件发生时被调用的函数,通常作为参数传递给其他函数。
- 例子:
- GUI事件处理:按钮点击事件的处理函数。
- 网络请求:请求完成后的回调函数。
- 定时器:定时器到期时的回调函数。
20. char a
的取值范围是多少?
- 有符号字符:-128 到 127
- 无符号字符:0 到 255
21. static
关键字有什么作用?
- 静态变量:在函数内部声明的静态变量在整个程序运行期间都存在,初始化一次。
- 静态函数:只能在声明它的文件中被调用。
- 静态全局变量:只能在声明它的文件中被访问。
22.什么是内存泄露,如何避免?
- 内存泄露:程序中已经分配的内存没有被释放,导致内存逐渐耗尽。
- 如何避免:
- 及时释放内存:使用完动态分配的内存后,及时调用
free
或delete
。 - 智能指针:使用C++中的智能指针(如
std::unique_ptr
和std::shared_ptr
)管理内存。 - 内存泄漏检测工具:使用工具(如 Valgrind)检测内存泄漏。
- 及时释放内存:使用完动态分配的内存后,及时调用
23. 什么是野指针、和空指针、内存泄漏什么关系什么区别?
- 野指针:指向不确定地址的指针,通常是因为指针被删除后仍然使用。
- 空指针:指向空地址(通常是
nullptr
或NULL
)的指针,表示没有有效地址。 - 内存泄漏:程序中已经分配的内存没有被释放。
关系和区别:
- 野指针:可能导致程序崩溃或未定义行为。
- 空指针:通常会导致程序崩溃,但容易检测和处理。
- 内存泄漏:导致内存逐渐耗尽,但不一定立即导致程序崩溃。
24.char
char
类型的取值范围是 -128
到 127
,这是因为 char
类型通常占用一个字节(8位),并且在大多数系统中默认是有符号的。让我们详细解释一下这个范围的由来:
1. 字节的二进制表示
一个字节有8位,每一位可以是0或1。因此,一个字节可以表示 (2^8 = 256) 种不同的值。
2. 有符号和无符号
-
无符号字符 (
unsigned char
):所有8位都用于表示数值,范围是从0到255。- 最高位(第7位)用于表示数值的一部分。
- 因此,范围是从 (0) 到 (255)。
-
有符号字符 (
signed char
):最高位(第7位)用于表示符号(0表示正数,1表示负数),其余7位用于表示数值。- 正数的范围是从 (0) 到 (127)。
- 负数的范围是从 (-128) 到 (-1)。
3. 有符号字符的范围
-
正数:最高位为0,剩下的7位用于表示数值。
- 范围是从 (0) 到 (127)。
- 例如,二进制
01111111
表示十进制127
。
-
负数:最高位为1,剩下的7位用于表示数值。
- 范围是从 (-128) 到 (-1)。
- 例如,二进制
10000000
表示十进制 (-128)。 - 二进制
11111111
表示十进制 (-1)。
4. 补码表示法
在计算机中,负数通常使用补码表示法。补码表示法的好处是可以简化加法和减法运算。
- 正数的补码:与原码相同。
- 负数的补码:原码的各位取反,然后加1。
例如:
-
-1
的补码:- 原码:
10000001
- 取反:
11111110
- 加1:
11111111
- 原码:
-
-128
的补码:- 原码:
10000000
- 取反:
11111111
- 加1:
10000000
- 原码:
5. 总结
char
类型:默认是有符号的,占用一个字节(8位),范围是从 (-128) 到 (127)。unsigned char
类型:无符号的,占用一个字节(8位),范围是从 (0) 到 (255)。
希望这能帮助你理解为什么 char
类型的取值范围是 (-128) 到 (127)。如果你有更多问题,欢迎继续提问!
2. IIC 的数据帧
IIC 数据帧包括以下几个部分:
- 起始条件:SCL 高电平时,SDA 从高变低。
- 地址字节:7 位或 10 位设备地址,加上 1 位读/写标志。
- 应答位:每个字节传输后,接收方发送一个应答位。
- 数据字节:8 位数据。
- 停止条件:SCL 高电平时,SDA 从低变高。
3. IIC 速率
IIC 的标准速率包括:
- 标准模式:100 kbps
- 快速模式:400 kbps
- 高速模式:3.4 Mbps
IIC 最多能挂多少 IC 从设备
对于 7 位地址的 IIC 总线,最多可以挂载 128 个设备(地址范围从 0x00 到 0x7F)。实际上,地址 0x00 是保留的,用于广播地址,因此最多可以挂载 127 个设备。
Linux 系统查找一个名叫 abc 的文件
- 命令:
find
- 参数:
-name
- 示例:
find / -name abc
绝对路径命令
- 命令:
pwd
(显示当前目录的绝对路径) - 示例:
pwd
查看当前目录的文件
- 命令:
ls
- 示例:
ls
执行一个 shell
- 命令:
bash
或sh
- 示例:
bash script.sh
Shell 的第一行
- 第一行:通常是解释器路径,例如:
#!/bin/bash
Shell 里面的循环函数语法
- for 循环:
for i in {1..5}; doecho $i done
- while 循环:
while [ $i -lt 5 ]; doecho $ii=$((i + 1)) done
交叉编译
- 定义:交叉编译是指在一个平台上生成另一个平台上的可执行代码的过程。
- 原因:目标平台可能没有编译工具链,或者编译环境资源有限。
Linux 调试代码的手段
- GDB:GNU 调试器
- Valgrind:内存检测工具
- strace:系统调用跟踪工具
- dmesg:查看内核日志
GDB 常用命令
- 启动调试:
gdb program
- 运行程序:
run
- 设置断点:
break function
- 继续执行:
continue
- 单步执行:
step
- 查看变量:
print variable
- 退出调试:
quit
内存泄露
- 定义:内存泄露是指程序中已分配的内存未能被释放,导致内存占用不断增加。
段错误
- 定义:段错误(Segmentation Fault)是指程序试图访问一个未分配给它的内存区域,或者试图以不适当的方式访问内存。
char a 的取值范围
- 取值范围:通常情况下,
char
类型的取值范围是 -128 到 127(有符号)或 0 到 255(无符号)。
static 关键字的作用
- 局部变量:延长局部变量的生命周期,使其在整个程序运行期间都存在。
- 全局变量:限制全局变量的作用域,使其只在定义它的文件中可见。
- 函数:限制函数的作用域,使其只在定义它的文件中可见。
数组和链表的优缺点
- 数组:
- 优点:随机访问速度快,内存连续。
- 缺点:插入和删除操作效率低,固定大小。
- 链表:
- 优点:插入和删除操作效率高,动态大小。
- 缺点:随机访问速度慢,内存不连续。
Git 版本修改了内容之后上传到服务端
- 添加更改:
git add .
- 提交更改:
git commit -m "Commit message"
- 推送到远程仓库:
git push origin branch_name
Git 常用命令
- 克隆仓库:
git clone repository_url
- 查看状态:
git status
- 添加文件:
git add file_name
- 提交更改:
git commit -m "Commit message"
- 推送到远程仓库:
git push origin branch_name
- 拉取最新代码:
git pull origin branch_name
IIC 英文
- 全称:Inter-Integrated Circuit
UART 英文
- 全称:Universal Asynchronous Receiver-Transmitter
PWM 波英文
- 全称:Pulse Width Modulation
希望这些解答对你有所帮助!如果有更多问题,欢迎继续提问。
相关文章:

【面试题】
1.UART 和 IIC 的区别 UART (Universal Asynchronous Receiver-Transmitter) 用途:用于异步串行通信。信号线:通常需要两根线(TX 和 RX),有时还需一根地线。通信方式:点对点。数据传输:单向或…...

Leetcode 寻找峰值
为了实现时间复杂度为 O ( log n ) O(\log n) O(logn),可以使用二分查找法: 解题思路: 峰值的特性是:当前元素大于左右相邻元素。使用二分法: 如果 nums[mid] > nums[mid 1],说明峰值在左侧或当前…...

探索大规模语言模型(LLM)在心理健康护理领域中的应用与潜力
概述 心理健康是公共卫生最重要的领域之一。根据美国国家精神卫生研究所(NIMH)的数据,到 2021 年,22.8% 的美国成年人将患上某种形式的精神疾病。在全球范围内,精神疾病占非致命性疾病负担的 30%,并被世界…...

Infisical开源密钥管理平台实战指南
1. 引言 在现代软件开发中,安全地管理环境变量和敏感信息已成为一个关键挑战。Infisical作为一个开源的密钥管理平台,为这一问题提供了强大而灵活的解决方案。本指南将深入探讨Infisical的功能,并通过实际操作步骤,帮助读者全面了解和使用这个工具。 2. Infisical概述 I…...

AI大模型:重塑软件开发流程与模式
人工智能技术的飞速发展,尤其是AI大模型的兴起,正以前所未有的速度和深度影响着各行各业,其中软件开发领域尤为显著。AI大模型,如GPT系列、BERT、Claude等通过其强大的自然语言处理能力、代码理解和生成能力,正在从根本…...

AMD(Xilinx) FPGA配置Flash大小选择
目录 1 FPGA配置Flash大小的决定因素2 为什么选择的Flash容量大小为最小保证能够完成整个FPGA的配置呢? 1 FPGA配置Flash大小的决定因素 在进行FPGA硬件设计时,选择合适的配置Flash是我们进行硬件设计必须考虑的,那么配置Flash大小的选择由什…...

基于Java Springboot图书借阅系统
一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue、Element-ui 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA/eclipse 数据…...

DDRPHY数字IC后端设计实现系列专题之数字后端floorplanpowerplan设计
3.2.3 特殊单元的布局 布图阶段除了布置 I/O 单元和宏单元,在 28nm 制程工艺时,还需要处理两种特 殊的物理单元,Endcap 和 Tapcell。 DDRPHY数字IC后端设计实现系列专题之后端设计导入,IO Ring设计 (1)拐…...

【Mysql】Mysql函数(上)
1、概述 在Mysql中,为了提高代码重用性和隐藏实现细节,Mysql提供了很多函数。函数可以理解为封装好的模块代码。 2、分类 在Mysql中,函数非常多,主要可以分为以下几类: (1)聚合函数 …...

Java连接MySQL(测试build path功能)
Java连接MySQL(测试build path功能) 实验说明下载MySQL的驱动jar包连接测试的Java代码 实验说明 要测试该情况,需要先安装好MySQL的环境,其实也可以通过测试最后提示的输出来判断build path是否成功,因为如果不成功会直…...

卡尔曼滤波器
卡尔曼滤波器概述 卡尔曼滤波器(Kalman Filter)是一种递归的最优估计方法,广泛应用于信号处理、控制理论、导航定位等领域。它基于线性动态系统模型,通过观测数据不断更新系统的状态估计,从而使得估计值能够在噪声干扰…...

基于BERT的情感分析
基于BERT的情感分析 1. 项目背景 情感分析(Sentiment Analysis)是自然语言处理的重要应用之一,用于判断文本的情感倾向,如正面、负面或中性。随着深度学习的发展,预训练语言模型如BERT在各种自然语言处理任务中取得了…...

推荐15个2024最新精选wordpress模板
以下是推荐的15个2024年最新精选WordPress模板,轻量级且SEO优化良好,适合需要高性能网站的用户。中文wordpress模板适合搭建企业官网使用。英文wordpress模板,适合B2C网站搭建,功能强大且兼容性好,是许多专业外贸网站的…...

AWTK-WIDGET-WEB-VIEW 实现笔记 (2) - Windows
在 Windows 平台上的实现,相对比较顺利,将一个窗口嵌入到另外一个窗口是比较容易的事情。 1. 创建窗口 这里有点需要注意: 父窗口的大小变化时,子窗口也要跟着变化,否则 webview 显示不出来。创建时窗口的大小先设置…...

Linux四剑客及正则表达式
正则表达式 基础正则(使用四剑客命令时无需加任何参数即可使用) ^ # 匹配以某一内容开头 如:^grep匹配所有以grep开头的行。 $ # 匹配以某一内容结尾 如:grep$ 匹配所有以grep结尾的行。 ^$ # 匹配空行。 . # 匹配…...

ALS 推荐算法案例演示(python)
数学知识补充:矩阵 总结来说: Am*k X Bk*n Cm*n ----至于乘法的规则,是数学问题, 知道可以乘即可,不需要我们自己计算 反过来 Cm*n Am*k X Bk*n ----至于矩阵如何拆分/如何分解,是数学问题,知道可以拆/可以分解即可 ALS 推荐算法案例:电影推…...

labview中连接sql server数据库查询语句
当使用数据库查询功能时,我们需要用到数据库的查询语句,这里已调用sql server为例,我们需要按照时间来查询,这里在正常调用数据库查询语句时,我们需要在前面给他加一个限制条件这里用到了,数据库的查询语句…...

leetcode_二叉树最大深度
对二叉树的理解 对递归调用的理解 对内存分配的理解 基础数据结构(C版本) - 飞书云文档 每次函数的调用 都会进行一次新的栈内存分配 所以lmax和rmax的值不会混在一起 /*** Definition for a binary tree node.* struct TreeNode {* int val;* …...

Elasticsearch 重建索引 数据迁移
Elasticsearch 重建索引 数据迁移 处理流程创建临时索引数据迁移重建索引写在最后 大家都知道,es的索引创建完成之后就不可以再修改了,包括你想更改字段属性或者是分词方式等。那么随着业务数据量的发展,可能会出现需要修改索引,或…...

2411rust,异步函数
原文 Rust异步工作组很高兴地宣布,在实现在特征中使用异步 fn的目标方面取得了重大进度.将在下周发布稳定的Rust1.75版,会包括特征中支持impl Trait注解和async fn. 稳定化 自从RFC#1522在Rust1.26中稳定下来以来,Rust就允许用户按函数的返回类型(一般叫"RPIT")编…...

前端网络性能优化问题
DNS预解析 DNS 解析也是需要时间的,可以通过预解析的⽅式来预先获得域名所对应的 IP。 <link rel"dns-prefetch" href"//abcd.cn"> 缓存 强缓存 在缓存期间不需要请求, state code 为 200 可以通过两种响应头实现&#…...

优选算法——双指针
前言 本篇博客为大家介绍双指针问题,它属于优选算法中的一种,也是一种很经典的算法;算法部分的学习对我们来说至关重要,它可以让我们积累解题思路,同时也可以大大提升我们的编程能力,本文主要是通过一些题…...

【Rabbitmq篇】RabbitMQ⾼级特性----消息确认
目录 前言: 一.消息确认机制 • ⾃动确认 • ⼿动确认 手动确认方法又分为三种: 二. 代码实现(spring环境) 配置相关信息: 1). AcknowledgeMode.NONE 2 )AcknowledgeMode.AUTO 3&…...

开源TTS语音克隆神器GPT-SoVITS_V2版本地整合包部署与远程使用生成音频
文章目录 前言1.GPT-SoVITS V2下载2.本地运行GPT-SoVITS V23.简单使用演示4.安装内网穿透工具4.1 创建远程连接公网地址 5. 固定远程访问公网地址 前言 本文主要介绍如何在Windows系统电脑使用整合包一键部署开源TTS语音克隆神器GPT-SoVITS,并结合cpolar内网穿透工…...

【idea】更换快捷键
因为个人习惯问题需要把快捷键替换一下。我喜欢用CTRLD删除一下,用CTRLY复制一样。恰好这两个快捷键需要互换一下。 打开file——>setting——>Keymap——>Edit Actions 找到CTRLY并且把它删除 找到CTRLD 并且把它删除 鼠标右键添加CTRLY 同样操作在Delet…...

最小的子数组(leetcode 209)
给定一个正整数数组,找到大于等于s的连续的最小长度的区间。 解法一:暴力解法 两层for循环,一个区间终止位置,一个区间起始位置,找到大于等于s的最小区间长度(超时了) 解法二:双指…...

IDEA-Plugins无法下载插件(网络连接问题-HTTP Proxy Settings)
IDEA-Plugins无法下载插件(网络连接问题) 改成如下配置: 勾选 添这个url即可:https://plugins.jetbrains.com/ 重启插件中心,问题解决。...

AWTK-WIDGET-WEB-VIEW 发布
awtk-widget-web-view 是通过 webview 提供的接口,实现的 AWTK 自定义控件,使得 AWTK 可以方便的显示 web 页面。 项目网址: https://gitee.com/zlgopen/awtk-widget-web-view webview 提供了一个跨平台的 webview 接口,是一个非…...

Mysql每日一题(if函数)
两种写法if()和case if()函数 select *,if(T.xT.y>T.z and T.xT.z>T.y and T.yT.z>T.x,Yes,No) as triangle from Triangle as T; case方法 select *, case when T.xT.y>T.z and T.xT.z>T.y and T.yT.z>T.x then Yes else No end as triangle from Trian…...

Spring Cloud Alibaba [Gateway]网关。
1 简介 网关作为流量的入口,常用功能包括路由转发、权限校验、限流控制等。而springcloudgateway 作为SpringCloud 官方推出的第二代网关框架,取代了Zuul网关。 1.1 SpringCloudGateway特点: (1)基于Spring5,支持响应…...